Create a render
POST/renders
Renders a PDF, an image, or a Word or PowerPoint file from a stored template, from ad-hoc HTML
or from a public URL: send exactly one of template, html and url. Needs the
render:create scope.
Synchronous by default: the answer is the finished render, or the file itself with
output=binary. A synchronous render that has no answer after 60 seconds, or finds no free
render slot within 30 seconds, continues in the background and answers 202 with
X-Render-Async-Fallback: true. With mode: async the answer is always 202. A 202 names
the render's result in Location; ask that, poll GET /renders/{id}, or wait for the webhook.
What can be refused is checked before anything is counted: the body (400 invalid_request),
the plan (403 forbidden with the feature), the template (404 template_not_found),
validate_data (422 data_validation_error), an e-invoice's _invoice block (422
einvoice_data_invalid) and the quota (402 quota_exceeded). A render that fails afterwards
(a template error, a page that does not load, a page or size limit, a timeout) answers with
its problem, which names the failed render in render_id.
Request
Responses
- 200
- 202
- 402
- 422
- 429
- default
The finished render (synchronous), or with output=binary the file itself.
Response Headers
Size of the workspace's request bucket: the plan's requests per second. Free test keys are also held to 30 requests a minute, and the headers then describe whichever bucket is closer to empty.
Requests left in the bucket.
Seconds until the bucket is full again.
Units this request costs; 0 for test keys, for an answer from the dedup cache, and for a render or batch that was queued, which counts its units when it finishes.
Units left in the organisation's billing period after this request (included units and prepaid packs), rounded down.
The region that rendered, or will.
What filled the source: the template language (jinja2, liquid, handlebars), none for plain HTML and URLs, dedup for an answer from the dedup cache, queued for a render that went to the background.
true when an identical request was served from the dedup cache at zero units.
A synchronous render that ran: compile;dur=…, render;dur=…, post;dur=…, upload;dur=… in milliseconds, the phases of timings. Absent on an answer from the dedup cache.
With output=binary: the render's id (rnd_…), the JSON answer's id.
With output=binary: the PDF's page count; empty for images and Word or PowerPoint files.
With output=binary: when the render's download_url stops working (ISO 8601), the JSON answer's expires_at; empty when there is none.
With output=binary: attachment; filename="<name>" with the stored file's name, for images too.
Only with output=binary on a render that set settings.pdf.ua: what the validator said about the file. The JSON answer carries the same as accessibility.
Render queued: either mode: async was requested, or a synchronous render outlived the 60 second deadline or found no free render slot within 30 seconds, and was handed to the background. The body is the render with status queued; it counts its units when it finishes.
Response Headers
Absolute URL of the render's result (GET /renders/{id}/result, with output=binary when the request asked for the file), which answers 202 until the render has finished.
Seconds to wait before asking Location again.
true when a synchronous request fell back to async; absent with mode: async.
Size of the workspace's request bucket: the plan's requests per second. Free test keys are also held to 30 requests a minute, and the headers then describe whichever bucket is closer to empty.
Requests left in the bucket.
Seconds until the bucket is full again.
Units this request costs; 0 for test keys, for an answer from the dedup cache, and for a render or batch that was queued, which counts its units when it finishes.
Units left in the organisation's billing period after this request (included units and prepaid packs), rounded down.
The region that rendered, or will.
What filled the source: the template language (jinja2, liquid, handlebars), none for plain HTML and URLs, dedup for an answer from the dedup cache, queued for a render that went to the background.
quota_exceeded: the units of the billing period are used up on a plan without overage (Free), or do not cover one unit per item of a batch, or the overage reached the period's hard cap while auto top-up is off. The problem names the first day after the period in period_end, and the cap in hard_cap_units when it was the cap. Test keys never get it.
The request was understood but cannot be rendered: data that does not fit the schema (data_validation_error), a template error (template_syntax_error, template_runtime_error, with location), a page that does not load (navigation_failed), a page or size limit of the plan (page_limit_exceeded, output_too_large), a source a PDF step cannot use (source_not_found, source_invalid, source_encrypted), or an e-invoice or PDF/UA failure.
rate_limited: the workspace's bucket of the plan's requests per second is empty (Free test keys also have 30 a minute). The problem names the bucket's limit and its window_seconds. Retry after Retry-After seconds.
Response Headers
Seconds until a request is let through again.
Size of the workspace's request bucket: the plan's requests per second. Free test keys are also held to 30 requests a minute, and the headers then describe whichever bucket is closer to empty.
Requests left in the bucket.
Seconds until the bucket is full again.
Error (RFC 9457 problem details).