Generating Images
The generate endpoint is the core of the API. You send variable values; it returns the rendered image bytes — or, with delivery: "link", a public URL for the render instead.
POST /api/v1/templates/{templateId}/generateEach successful call consumes one render from your monthly quota. Identical requests are not deduplicated or cached server-side — every call re-renders and consumes quota, so deduplicate on your side if you may issue the same request twice. (Batch jobs are different: their submit endpoint supports an Idempotency-Key that makes retries safe.)
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 |
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 |
delivery | string | no | binary (default) returns image bytes; link publishes the render and returns a JSON share link |
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" \ -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. The body depends on delivery.
delivery: "binary" (default)
Section titled “delivery: "binary" (default)”The raw image is the body — no JSON wrapper. 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.
delivery: "link"
Section titled “delivery: "link"”The body is application/json describing a public share link:
{ "id": "019a4c31-8e2f-7b10-9c44-1d5e77b0a913", "url": "https://img.zandovi.com/s/8f3c2ad9e1b74c05.png", "mimeType": "image/png", "fileSize": 41982, "createdAt": "2026-08-24T09:00:00Z", "expiresAt": "2026-09-23T09:00:00Z"}The link expires after a plan-dependent number of days, and anyone holding the URL can open it. See Share Links for the full field reference, listing and revocation, and the limits.
Either way the call consumes exactly one render — delivery changes how the result is returned, not what it costs.
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-Timestamp | ISO 8601 UTC time the response was produced |
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 |
403 | delivery: "link" requested but share links aren’t on this plan, or the active-link cap is reached |
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. With delivery: "link", also covers share storage being unavailable or the upload failing |
See Errors, quotas & rate limits for response bodies and retry guidance.