POST /v1/render
Render a document from a template and data. Returns either a download URL or the rendered output inline.
Endpoint:
POST /v1/renderRequest Body
Section titled “Request Body”You can render either a saved template (by ID) or an inline template (passed directly in the request).
Option A — Saved template:
{ "templateId": "your-template-id", "data": { "orderNumber": "ORD-9876", "customer": "Acme Corp" }, "format": "pdf"}Option B — Inline template:
{ "template": { "version": 2, "units": "in", "meta": { "name": "Badge" }, "size": { "width": 76.2, "height": 50.8 }, "elements": [ { "id": "name", "kind": "text", "position": { "x": 8, "y": 15 }, "size": { "width": 60, "height": 12 }, "expression": "attendeeName", "font": { "family": "Arial", "size": 14 }, "color": "#111111" } ] }, "data": { "attendeeName": "Jane Smith" }, "format": "png"}Fields
Section titled “Fields”| Field | Type | Required | Description |
|---|---|---|---|
templateId |
string |
One of templateId or template is required |
ID of a published template. Accepts a template ID, a team slug (e.g., shipping-label), or a library-qualified slug (e.g., carbon:product-2x1). See Template Libraries. |
template |
object |
One of templateId or template is required |
Inline template object. See Templates for the full schema. |
data |
object or array |
Yes | Data to bind into the template. An object fills one label (or, on sheet media without slots, is replicated across every cell on the page). An array of objects tiles one row per label cell in reading order across the sheet (and onto additional pages when the array is longer than one sheet). Top-level keys become variables in element expression and visibleExpression fields. |
format |
string |
Yes | Output format: "pdf", "png", "zpl", or "html". |
dpi |
number |
No | Resolution for raster output. Default: 300 for PNG, 203 for ZPL. Ignored for PDF and HTML. |
delivery |
string |
No | "url" (default) returns a JSON response with a download URL. "inline" returns the rendered output directly as the response body. |
slots |
number[] |
No | Optional 1-based sheet positions for partial-sheet printing. Only valid with sheet media templates and formats html, pdf, or png. See Partial-sheet slots below. |
Partial-sheet slots
Section titled “Partial-sheet slots”When a template has sheet media (an N-up grid such as Avery 2×4), each cell on the page is a numbered slot. Numbering is 1-based and row-major from the top-left:
- Slot
1is the top-left cell. - On a 2-column grid, slot
2is the top-right cell; slot3is the second row, left cell; and so on through the bottom-right cell. - Capacity is
columns × rows(for example, 8 on a 2×4 sheet).
Pass slots to print only into chosen positions. Unselected cells render truly blank (no label content). A slots request is always a single page: you cannot request more positions than capacity.
Validation rules
Section titled “Validation rules”All of the following return HTTP 400 with code INVALID_SLOTS and a specific message:
| Rule | Detail |
|---|---|
| Sheet media required | The resolved template must have media.type === "sheet". |
| Format | Only "html", "pdf", and "png". Rejected for "zpl" (single-label path). |
| Values | Integers only, unique, each in 1..capacity. |
Array data |
slots.length must equal data.length, and both must be ≤ capacity. A full-capacity permutation is legal. |
Object data |
1 ≤ slots.length ≤ capacity. The same object is replicated into every listed slot. |
| Omitted | If slots is omitted, behaviour is unchanged from today (full-sheet fill / multi-page tiling). |
Example — array data into chosen slots
Section titled “Example — array data into chosen slots”Two data rows placed in physical positions 4 and 6 (leaving the rest blank):
{ "templateId": "avery-22890-labels", "data": [ { "name": "A" }, { "name": "B" } ], "slots": [4, 6], "format": "pdf"}Row data[i] is printed into slots[i]. Order in the array is meaningful — you may permute slots deliberately.
Example — single object into selected slots
Section titled “Example — single object into selected slots”One object copied into slots 1, 3, and 5 only:
{ "templateId": "avery-22890-labels", "data": { "name": "Jane Smith", "role": "Guest" }, "slots": [1, 3, 5], "format": "pdf"}Without slots, the same object is still replicated across every cell on the sheet (existing behaviour).
Response — URL Delivery (default)
Section titled “Response — URL Delivery (default)”Status: 200 OK
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "complete", "format": "pdf", "url": "https://api.binderypress.dev/v1/render-outputs/a1b2c3d4-e5f6-7890-abcd-ef1234567890", "sizeBytes": 12345, "renderTimeMs": 450}| Field | Type | Description |
|---|---|---|
id |
string |
Unique render job ID (UUID). |
status |
string |
"complete". |
format |
string |
The output format. |
url |
string |
Download URL. Valid for 7 days. |
sizeBytes |
number |
Output file size in bytes. |
renderTimeMs |
number |
Time spent rendering in milliseconds. |
The response also includes rate limit headers.
Response — Inline Delivery
Section titled “Response — Inline Delivery”Status: 200 OK
The response body contains the rendered document directly. The Content-Type header matches the format:
| Format | Content-Type |
|---|---|
pdf |
application/pdf |
png |
image/png |
zpl |
text/plain |
html |
text/html |
Examples
Section titled “Examples”Render with a saved template (by slug)
Section titled “Render with a saved template (by slug)”curl -X POST https://api.binderypress.dev/v1/render \ -H "Authorization: Bearer bp_sk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": "shipping-label", "data": { "orderNumber": "ORD-9876", "customer": "Acme Corp", "items": [ { "name": "Widget A", "qty": 10 }, { "name": "Widget B", "qty": 5 } ] }, "format": "pdf" }'Render inline template as PNG
Section titled “Render inline template as PNG”curl -X POST https://api.binderypress.dev/v1/render \ -H "Authorization: Bearer bp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "template": { "version": 2, "units": "in", "meta": { "name": "Badge" }, "size": { "width": 76.2, "height": 50.8 }, "elements": [ { "id": "name", "kind": "text", "position": { "x": 8, "y": 15 }, "size": { "width": 60, "height": 14 }, "expression": "attendeeName", "font": { "family": "Arial", "size": 20, "weight": "bold" }, "color": "#111111" } ] }, "data": { "attendeeName": "Jane Smith" }, "format": "png", "dpi": 150 }'Render ZPL for label printer (inline delivery)
Section titled “Render ZPL for label printer (inline delivery)”curl -X POST https://api.binderypress.dev/v1/render \ -H "Authorization: Bearer bp_sk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": "label-template-id", "data": { "sku": "WIDGET-001", "quantity": 50 }, "format": "zpl", "dpi": 203, "delivery": "inline" }' \ -o label.zplRender a library template
Section titled “Render a library template”curl -X POST https://api.binderypress.dev/v1/render \ -H "Authorization: Bearer bp_sk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateId": "carbon:product-2x1", "data": { "sku": "WIDGET-001", "name": "Widget A" }, "format": "pdf" }'Library templates use the librarySlug:templateSlug format. See Template Libraries for details.
Errors
Section titled “Errors”Schema validation errors use details.issues, an array of objects with path and message fields.
| Status | Code | Cause |
|---|---|---|
400 |
BAD_REQUEST |
Missing required fields or invalid format. |
400 |
V1_SCHEMA |
The inline template uses the legacy schema; this endpoint accepts schema v2 only. |
400 |
INVALID_TEMPLATE |
The inline template failed schema v2 validation. Check details.issues. |
401 |
AUTH_REQUIRED |
Missing or invalid API key. |
404 |
NOT_FOUND |
Template ID not found (when using templateId). |
413 |
PAYLOAD_TOO_LARGE |
Request body exceeds 10 MB (1 MB for demo keys). |
429 |
RATE_LIMITED |
Too many requests. Retry after the Retry-After period. |
429 |
QUOTA_EXCEEDED |
Monthly quota exceeded (hard-capped plans only). |
500 |
STORED_TEMPLATE_INVALID |
The saved template failed schema v2 validation. |
502 |
RENDER_ERROR |
Rendering failed. |