---
title: "Render one template row synchronously"
method: POST
path: "/api/v1/images/render"
tags: ["Synchronous images"]
---

# Render one template row synchronously

`POST /api/v1/images/render`

## Request

- Base URL: `https://api.imagestep.dev`
- URL: `https://api.imagestep.dev/api/v1/images/render`
- Auth: API key in header `Authorization`

A template plus ONE row of data becomes one PNG, returned directly. Nothing is
stored: no job, no asset, no public URL.

`templateId` accepts `id@version` to pin a version, exactly as the job form does.

LIMITS: 20 s of wall clock (`503`, `deadline_exceeded`). It shares the synchronous lane's 4 calls in flight per account (`429 rate_limited`, `Retry-After: 1`), and a success counts one against the processing allowance — past it, paid from the balance (`402 insufficient_credit` when it cannot be). No `Idempotency-Key`: send it again.

USE THIS WHEN:
- You want one image from one row of data, right now

DO NOT USE WHEN:
- You have many rows → POST /api/v1/jobs {"op":"render_template", "items":[…]}
- You want an asset id or a permanent URL → the job form

## Request body

- RenderRequest: One template and one row of data
  - `templateId` string, required: Template id, your own slug, or either with `@version` to pin one version
  - `data` object: The row: variable name → value. `{{ name }}` is filled HTML-escaped, `{{{ name }}}` raw, `a.b` reads nested data; a name the row does not carry renders as nothing.

## Response `200`

The PNG, at the template's `width` × `height`, with `X-ImageStep-Duration-Ms`

## Other responses

- `400`: `invalid_param` on `templateId` — missing, an `@version` that is not a positive number, or a template Chromium could not load (not retryable, as in a batch)
- `404`: `not_found` on `templateId` — no such template or version, or it is not yours
- `429`: Rate limited — `error.code` is `rate_limited` and `retryable` is true. `Retry-After` says how many seconds to wait.
- `503`: `provider_unavailable`, retryable, with `Retry-After` — `details.reason` says which: - `capacity` — this node, or the render worker, is full - `deadline_exceeded` — the render took longer than the deadline - `worker_unreachable` — no render worker answered

---

[API](https://skmtc.dev/imagestep/apis/imagestep-api.md) · [All operations](https://skmtc.dev/imagestep/apis/imagestep-api/llms.txt) · [OpenAPI document](https://skmtc.dev/imagestep/apis/imagestep-api/revisions/5e8e922a3085?raw)
