Batch Render โ Mail Merge
Tag: Batch ยท Version: v1 ยท Stability: ๐ก Beta
Generate many PDFs from a single template in one call โ one render per data row. The result is either a ZIP of per-row files or a single merged PDF, produced by a background job with live progress and partial-failure reporting.
JWT-only. Rate limits apply per workspace (same as single renders).
:::info Async โ poll for status
Batch jobs run in the background. Submit the job, get back a jobId, poll the
status endpoint until completed or failed, then download the result.
:::
Submit a batch job (JSON rows)โ
POST /api/templates/{id}/render-batch ยท JWT ยท application/json
{
"rows": [
{ "name": "Alice", "total": "$1,200" },
{ "name": "Bob", "total": "$950" }
],
"output": "zip",
"fileNamePattern": "invoice-{{name}}"
}
| Field | Type | Required | Notes |
|---|---|---|---|
rows | array of objects | โ | One render per element. Max 2,000 rows. |
output | "zip" | "merged" | โ | zip โ per-row PDFs in a ZIP; merged โ one concatenated PDF. |
fileNamePattern | string | null | โ | Token pattern for filenames inside the ZIP (e.g. invoice-{{name}}). |
Returns { jobId }.
Submit a batch job (CSV / XLSX upload)โ
POST /api/templates/{id}/render-batch/upload ยท JWT ยท multipart/form-data
Upload a .csv or .xlsx file. Each data row becomes one render. Column
headers map to template {{tokens}}. Returns { jobId }.
Get job statusโ
GET /api/templates/{id}/render-batch/jobs/{jobId} ยท JWT
Poll this endpoint until status is completed or failed.
{
"jobId": "uuid",
"status": "processing",
"total": 50,
"completed": 23,
"failed": 0
}
status | Meaning |
|---|---|
pending | Queued, not yet started. |
processing | Running โ completed + failed show progress. |
completed | All rows attempted; download the result. |
failed | Job-level failure (not a partial row failure). |
List recent jobsโ
GET /api/templates/{id}/render-batch/jobs ยท JWT
Returns the workspace's recent batch jobs for this template.
Download resultโ
GET /api/templates/{id}/render-batch/jobs/{jobId}/result ยท JWT
Returns the ZIP or merged PDF. Only available when status === "completed".
Results expire after 24 hours.
Partial failuresโ
If individual rows fail to render, they are skipped and reported in the status
response โ the job still completes. A job-level failure (e.g. the template is
missing) marks the whole job failed.
Row capโ
Maximum 2,000 rows per job. Larger datasets should be split across multiple jobs.