Batches
Bulk/related document generation jobs
How relations work
relations is an object keyed by the field name to set on the child document. Each value is either:
- a plain string
"<parentAlias>.<dotted.field.path>"— resolves against the parent's single document. Only valid when the parent'scountis1; using it against a parent withcount > 1is rejected withAMBIGUOUS_RELATIONat submit time. - or an object
{ "from": "<parentAlias>.<dotted.field.path>", "strategy": "round-robin" }— required when the parent'scount > 1; each child document is matched to a parent document by index, wrapping around (childIndex % parentCount).round-robinis the only supportedstrategyvalue today — anything else is rejected withUNSUPPORTED_STRATEGY.
Example: one customer and 3 order documents, each stamped with that customer's id:
{
"documents": [
{ "templateId": "<customerTemplateId>", "alias": "customer", "count": 1 },
{
"templateId": "<orderTemplateId>",
"alias": "order",
"count": 3,
"relations": { "customerId": { "from": "customer.id", "strategy": "round-robin" } }
}
]
}The child template body never calls a function to fetch the relation value — the batch engine injects customerId onto each generated order document after generation (overwriting it if already present).
| Method | Path | Summary |
|---|---|---|
| POST | /v1/batches | Create a batch generation job |
| GET | /v1/batches/{batchId} | Get batch status and documents |
/v1/batchesCreate a batch generation job
Small batches may be executed synchronously (200 with results), larger batches are queued and executed asynchronously (202). Template params: batch-level `params` are defaults for every document; each document's own `params` are shallow-merged over them (document keys win). Each document may also override the batch-level `sequenceNamespace`/`variableNamespace`. Params and namespaces of one document never affect another, and sync and async execution use the same resolved inputs.
Request body — BatchSpec
{
"seed": 42424242,
"params": {
"locale": "en-US"
},
"sequenceNamespace": "batch-2026-07-23",
"variableNamespace": "batch-2026-07-23",
"documents": [
{
"templateId": "tpl_9f3a1c2e",
"alias": "order",
"count": 3,
"params": {
"name": "Jane Doe"
}
}
]
}Responses
object
{
"batchId": "batch_7d2e4f10",
"status": "completed",
"seed": 42424242,
"results": {
"order": [
{
"orderNo": 1001,
"customer": "Jane Doe",
"locale": "en-US"
},
{
"orderNo": 1002,
"customer": "Jane Doe",
"locale": "en-US"
},
{
"orderNo": 1003,
"customer": "Jane Doe",
"locale": "en-US"
}
]
}
}{
"batchId": "batch_7d2e4f10",
"status": "failed",
"seed": 42424242,
"error": {
"code": "TEMPLATE_FETCH_FAILED",
"message": "Failed to fetch template 'tpl_9f3a1c2e': HTTP 404"
}
}object
{
"batchId": "batch_7d2e4f10",
"status": "queued",
"seed": 42424242
}ErrorEnvelope
{
"error": {
"code": "VALIDATION_ERROR",
"message": "document 'order' params must be a JSON object, got array",
"details": {
"alias": "order",
"field": "params",
"receivedType": "array"
}
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "sequenceNamespace must be a non-empty string, got number",
"details": {
"field": "sequenceNamespace",
"receivedType": "number"
}
}
}ErrorEnvelope
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid API key",
"details": {}
}
}/v1/batches/{batchId}Get batch status and documents
Returns the batch's status and seed. Once `status` is `completed`, `results` maps each document alias to the array of generated documents (same shape as the synchronous `POST /v1/batches` 200 response). While `queued`/`running` there is no `results`; on `failed` there is an `error` object instead. The original request spec, tenant id and per-document metadata are not returned.
| Param | In | Type | Required | Description |
|---|---|---|---|---|
| batchId | path | string | Yes | — |
Responses
object
{
"batchId": "batch_7d2e4f10",
"status": "completed",
"seed": 42424242,
"results": {
"order": [
{
"orderNo": 1001,
"customer": "Jane Doe",
"locale": "en-US"
},
{
"orderNo": 1002,
"customer": "Jane Doe",
"locale": "en-US"
},
{
"orderNo": 1003,
"customer": "Jane Doe",
"locale": "en-US"
}
]
}
}{
"batchId": "batch_7d2e4f10",
"status": "running",
"seed": 42424242
}{
"batchId": "batch_7d2e4f10",
"status": "failed",
"seed": 42424242,
"error": {
"code": "TEMPLATE_FETCH_FAILED",
"message": "Failed to fetch template 'tpl_9f3a1c2e': HTTP 404"
}
}ErrorEnvelope
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid API key",
"details": {}
}
}ErrorEnvelope
{
"error": {
"code": "NOT_FOUND",
"message": "Template tpl_missing not found",
"details": {}
}
}