Getting Started

Dynamic Templates

Turn on Dynamic template on a route (in the Advanced section of the route editor) and its response body is rendered as a sandboxed Jinja2 template before being sent — so it can echo back parts of the request, or generate a fresh id/timestamp on every call instead of returning the same static JSON.

What's available in a template

request.method              → "POST"
request.path                → "/users/42"
request.query.<name>        → a query string parameter
request.headers.<name>      → a request header (case-insensitive)
request.body.<path>         → a field from the JSON request body, dot-path for nested fields
request.raw_body            → the original, unparsed request body
request.path_params.<name>  → a value captured from a {name} path segment

Helper functions

{{ uuid4() }}                    a fresh UUID
{{ now_iso() }}                  the current time, ISO 8601
{{ random_int(1, 100) }}         a random integer in [low, high]

random_int uses a cryptographically secure random source, not a predictable pseudo-random generator.

Example

Route: POST /users/{id}, template enabled, response body:

{
  "id": "{{ request.path_params.id }}",
  "name": "{{ request.body.name }}",
  "request_id": "{{ uuid4() }}",
  "received_at": "{{ now_iso() }}"
}

Calling it with {"name": "Ada"} against /users/42 returns the id from the URL, the name you sent, and a fresh id/timestamp pair every time.

Limits

Templates run in a sandboxed Jinja2 environment (no access to Python internals, file system, or imports) and are bounded in input length, output length, and recursion depth. A template that exceeds those limits, or fails to render, returns 422 instead of a response body.