/api/v1/:workspace/templates/:id/bulkBulk render (synchronous)
Render up to 30 items in one request. Response shape is chosen via the Accept header: application/zip streams the archive; anything else (default) returns JSON with a presigned download URL.
Parameters
workspacepath | Workspace slug.required |
idpath | Template UUID.required |
Acceptheader | application/zip for bytes, or application/json (default) for { url, expiresAt, … }. |
Response
// Accept: application/zip
(application/zip — binary stream)
// Accept: application/json (default)
{
"url": "https://…",
"ttl": 259200,
"expiresAt": "…",
"urlExpiresAt": "…",
"filename": "invoice.zip",
"bytes": 428931
}Items without a filename get <template-slug>_0001.pdf, _0002.pdf, …; duplicates get a -2, -3 suffix.
ttlSeconds — same rules as /generate.
ignoreErrors applies to the whole batch: false (default) aborts on the first failing item with 400 transform_failed + itemIndex; true renders every item, blanking failed fields.
/api/v1/:workspace/jobsCreate async render job
Queue a large batch (up to 10,000 items). Returns immediately with a jobId; poll GET /jobs/:id for status + downloadUrl.
Parameters
workspacepath | Workspace slug.required |
Response
{
"jobId": "uuid",
"status": "pending",
"itemsTotal": 2
}filename and ttlSeconds follow the same rules as /bulk. With ignoreErrors: false (default), a transform failure flips the job to failed and error names the item and field.
/api/v1/:workspace/jobsList render jobs
Workspace-scoped job list. Returns the standard {data, meta} envelope; default sort is createdAt:desc.
Parameters
workspacepath | Workspace slug.required |
statusquery | pending | running | completed | failed | expired |
templateIdquery | Only jobs for this template UUID. |
limitquery | 1 – 100 (default 50) |
offsetquery | Rows to skip (default 0). |
sortByquery | createdAt | finishedAt | status, suffixed with :asc or :desc. |
totalResultsquery | true to include meta.total. |
Response
{
"jobs": [
{
"id": "…",
"status": "completed",
"itemsTotal": 100,
"itemsDone": 100
}
],
"meta": {
"count": 1,
"limit": 50,
"offset": 0,
"hasMore": false
}
}/api/v1/:workspace/jobs/:idGet one job
Once status === completed, the response includes a downloadUrl (capped at 7 days). Call this endpoint again to mint a fresh URL anywhere up to expiresAt. Past expiresAt, status flips to expired — re-create the job to regenerate.
Parameters
workspacepath | Workspace slug.required |
idpath | Job UUID.required |
Response
{
"id": "…",
"status": "completed",
"itemsTotal": 100,
"itemsDone": 100,
"ttlSeconds": 604800,
"downloadUrl": "https://…",
"urlExpiresAt": "2026-06-16T22:46:04.000Z",
"expiresAt": "2026-06-16T22:46:04.000Z"
}Need help?
Open a ticket from the in-app Support page, or email [email protected].