# Dynamic Document API: Batches

> Render one template for many items (JSON or CSV), plus an optional ZIP / merged PDF.

> Part of the Dynamic Document API documentation. Index of all pages for agents: [llms.txt](https://dynamicdocumentapi.com/llms.txt), every page in one file: [llms-full.txt](https://dynamicdocumentapi.com/llms-full.txt).

7 endpoints of the [API reference](https://dynamicdocumentapi.com/docs/api-reference/index.md), version 1.0.0. Interactive reference: https://dynamicdocumentapi.com/docs/api-reference#tag/batches. Machine-readable OpenAPI document: https://dynamicdocumentapi.com/openapi/openapi-public.json

## Servers

- https://api-eu.dynamicdocumentapi.com — EU (Germany)

## Endpoints

- `GET /v1/batches` — List batches
- `POST /v1/batches` — Create a batch
- `GET /v1/batches/{batch_id}` — Retrieve a batch
- `POST /v1/batches/{batch_id}/cancel` — Cancel a batch
- `GET /v1/batches/{batch_id}/items` — List batch items
- `POST /v1/batches/{batch_id}/resend-emails` — Resend a batch's failed emails
- `POST /v1/batches/{batch_id}/retry-failed` — Retry the failed items

## GET /v1/batches

**List batches**

Newest first. Test keys see test batches only.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `cursor` | query | string |  |
| `limit` | query | integer | 1 to 100 (default 50). |
| `reference` | query | string |  |
| `status` | query | "canceled" \| "completed" \| "failed" \| "processing" \| "queued" |  |
| `template_id` | query | string |  |

Responses:

- `200` 
- `400` Unknown `status` or malformed `template_id`.
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `429` Rate limited (`Retry-After`).

## POST /v1/batches

**Create a batch**

Renders one template version for many items — a JSON `items` array (≤ 25 MB body) or a CSV from `POST /v1/uploads` with an optional `csv_mapping` — sharing `output`, `delivery` and `webhook`. Items become ordinary renders (`source: batch`), released under your plan's bulk concurrency; `combine` adds a ZIP of all outputs and/or one merged PDF. Answers `202` right away; follow progress with `GET /v1/batches/{id}` or the `batch.progress` / `batch.completed` webhooks. Live items are billed as they are released: if the render limit is reached mid-batch, the batch pauses (`paused`, one `batch.progress`) and resumes on its own once renders are available again.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |

Request body (`application/json`): BatchRequest

| Field | Type | Description |
|---|---|---|
| `combine` | CombineSpec or null |  |
| `csv_mapping` | object or null |  |
| `csv_upload_id` | string or null |  |
| `delivery` | DeliverySpec or null |  |
| `engine` | string or null |  |
| `items` | array of BatchItemSpec or null |  |
| `metadata` | object or null |  |
| `output` | OutputSpec or null |  |
| `reference` | string or null |  |
| `template_id` (required) | string |  |
| `test` | boolean or null |  |
| `version` | string or integer |  |
| `webhook` | BatchWebhookSpec or null |  |

Responses:

- `202` Batch accepted (`Location: /v1/batches/{id}`).
- `400` Invalid request, items or CSV (`errors[]` with `/items/<i>/…` or `/csv/row/<n>`).
- `401` Missing, invalid, expired or revoked credentials.
- `402` Batches not on your plan, or render limit reached (`render_limit_reached`).
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified; or `region_not_enabled`: the workspace's enabled regions leave out this region.
- `404` Template, version or upload not found.
- `409` A request with this Idempotency-Key is still in progress.
- `410` Template deleted.
- `413` Body over 25 MB or an item's data over 1 MB.
- `422` Item data does not match the template schema, or the webhook URL is not allowed.
- `429` Rate limited (`Retry-After`).
- `503` Region degraded (`Retry-After`).

## GET /v1/batches/{batch_id}

**Retrieve a batch**

Counters, progress and — once combined — the ZIP / merged PDF with signed URLs.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `batch_id` (required) | path | string | Batch id (`bat_…`). |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Batch not found.
- `429` Rate limited (`Retry-After`).

## POST /v1/batches/{batch_id}/cancel

**Cancel a batch**

Items not released yet are canceled; released renders are canceled when a worker picks them up (items already rendering may still finish and are counted). The batch is `canceled` at once and `batch.completed` fires. Canceled items are not billed.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |
| `batch_id` (required) | path | string | Batch id (`bat_…`). |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Batch not found.
- `409` `conflict`: the batch already finished.
- `429` Rate limited (`Retry-After`).

## GET /v1/batches/{batch_id}/items

**List batch items**

Items in `index` order; `?status=failed` lists what `retry-failed` renders again.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `batch_id` (required) | path | string | Batch id (`bat_…`). |
| `cursor` | query | string |  |
| `limit` | query | integer | 1 to 100 (default 50). |
| `status` | query | "canceled" \| "failed" \| "pending" \| "queued" \| "succeeded" |  |

Responses:

- `200` 
- `400` Unknown `status`.
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Batch not found.
- `429` Rate limited (`Retry-After`).

## POST /v1/batches/{batch_id}/resend-emails

**Resend a batch's failed emails**

For each item and rule, the newest email is resent when its status is listed (`failed` by default; `unknown` only when listed). Emails that can't be resent are listed in `skipped` with the reason (at most 100).

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |
| `batch_id` (required) | path | string | Batch id (`bat_…`). |

Request body (`application/json`): BatchResendEmailsRequest

| Field | Type | Description |
|---|---|---|
| `statuses` | array of "failed" \| "unknown" | Resend the newest email of each render and rule when its status is listed. |

Responses:

- `200` 
- `400` Unknown status.
- `401` Missing, invalid, expired or revoked credentials.
- `402` Email delivery needs the Growth plan or higher (`plan_feature_unavailable`).
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Batch not found.
- `429` Rate limited (`Retry-After`).

## POST /v1/batches/{batch_id}/retry-failed

**Retry the failed items**

For a finished batch with failed items: those items are rendered again as new renders (the old render id stays in `error.previous_render_id`), earlier combined files are dropped and the batch is `processing` until it finishes again. Zero-retention batches can't be retried: their items keep no data once they finish. Nor can a batch with `combine` whose succeeded items' files expired or were deleted: its new combined files couldn't hold those items.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |
| `batch_id` (required) | path | string | Batch id (`bat_…`). |

Responses:

- `202` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Batch not found.
- `409` `conflict`: the batch is still running or has no failed items. `zero_retention`: a zero-retention batch keeps no item data; submit the failed items in a new batch. `item_files_expired`: the batch has `combine` and the files of succeeded items expired or were deleted (`items` lists their indexes, at most 100); submit the failed items in a new batch.
- `429` Rate limited (`Retry-After`).
