Skip to main content

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

Request โ€” CreateBatchJsonBody
{
"rows": [
{ "name": "Alice", "total": "$1,200" },
{ "name": "Bob", "total": "$950" }
],
"output": "zip",
"fileNamePattern": "invoice-{{name}}"
}
FieldTypeRequiredNotes
rowsarray of objectsโœ…One render per element. Max 2,000 rows.
output"zip" | "merged"โœ…zip โ†’ per-row PDFs in a ZIP; merged โ†’ one concatenated PDF.
fileNamePatternstring | 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.

Response (illustrative)
{
"jobId": "uuid",
"status": "processing",
"total": 50,
"completed": 23,
"failed": 0
}
statusMeaning
pendingQueued, not yet started.
processingRunning โ€” completed + failed show progress.
completedAll rows attempted; download the result.
failedJob-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.


  • Templates โ€” the template being batch-rendered.
  • Rendering โ€” single-document render reference.
  • API Keys โ€” usage metering (batch renders are tagged api).