Generating Images
The generate endpoint is the core of the API. You send variable values; it returns the rendered image bytes.
POST /api/v1/templates/{templateId}/generateEach successful call consumes one render from your monthly quota.
Request
Section titled “Request”Path parameter: templateId (UUID) — the template to render.
Headers
| Header | Required | Description |
|---|---|---|
X-Api-Key | yes | Your API key |
Content-Type | yes | application/json |
Idempotency-Key | no | Up to 128 chars. Repeating a request with the same key returns the cached image without re-rendering (and without consuming extra quota). |
Body
| Field | Type | Required | Description |
|---|---|---|---|
variables | object | yes | Map of variable name → value. Names must match those from GET /templates/{id}. Values are strings. |
format | string | no | png (default), jpeg, webp, or pdf |
options | object | no | Render options (below) |
options object
| Field | Type | Range | Description |
|---|---|---|---|
scale | integer | 1–4 | Resolution multiplier for raster output |
quality | integer | 1–100 | Compression quality for jpeg / webp |
outputDpi | integer | 96, 150, 300 | DPI tier — use 300 for print/PDF |
backgroundColor | string | hex | Overrides the template background, e.g. #ffffff |
Example
Section titled “Example”curl -X POST https://app.zandovi.com/api/v1/templates/$TEMPLATE_ID/generate \ -H "X-Api-Key: $ZANDOVI_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-10432-coupon" \ -o coupon.png \ -d '{ "variables": { "first_name": "Sarah", "discount_code": "VIP30", "expires_at": "30 Jun 2026" }, "format": "png", "options": { "scale": 2, "quality": 90 } }'For JavaScript and Python examples, see the Quickstart.
Response
Section titled “Response”On success the response is 200 OK with the raw image as the body — there is no JSON wrapper and no hosted URL. The Content-Type matches the requested format:
format | Content-Type |
|---|---|
png | image/png |
jpeg | image/jpeg |
webp | image/webp |
pdf | application/pdf |
A Content-Disposition: attachment; filename=… header is included. Write the body straight to a file or pipe it onward.
Response headers
| Header | Description |
|---|---|
X-Request-Id | Unique ID for this request — include it in support requests |
X-Template-Id | Template used for the render |
X-Render-Time-Ms | Server-side render duration |
X-Quota-Limit | Monthly render ceiling for the workspace |
X-Quota-Remaining | Renders left this billing period |
X-Quota-Reset | ISO 8601 UTC time the quota resets |
Variable values & validation
Section titled “Variable values & validation”- Supply every required variable. Missing required variables return
400with anapplication/problem+jsonbody naming the offending variable. - Values are sent as strings, including
number,date,phone, andurltypes — they are validated against the template’s rules server-side. qrcodeandbarcodevariables take the data to encode;imagevariables take an image URL.- Variables you omit fall back to their
defaultValueif the template defines one; otherwise an optional variable simply renders empty.
Errors
Section titled “Errors”| Code | Cause |
|---|---|
400 | Missing required variable or a value failed validation |
401 | Missing or invalid API key |
404 | Template not found or not accessible to this key |
429 | Monthly quota or short-term rate limit exceeded |
502 / 503 | Rendering service errored or is temporarily unavailable — retry with backoff |
See Errors, quotas & rate limits for response bodies and retry guidance.