JsonFabrica

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's count is 1; using it against a parent with count > 1 is rejected with AMBIGUOUS_RELATION at submit time.
  • or an object { "from": "<parentAlias>.<dotted.field.path>", "strategy": "round-robin" } — required when the parent's count > 1; each child document is matched to a parent document by index, wrapping around (childIndex % parentCount). round-robin is the only supported strategy value today — anything else is rejected with UNSUPPORTED_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).

MethodPathSummary
POST/v1/batchesCreate a batch generation job
GET/v1/batches/{batchId}Get batch status and documents
POST/v1/batches

Create a batch generation job

Small batches may be executed synchronously (200 with results), larger batches are queued and executed asynchronously (202).

Request body — BatchSpec

{
  "seed": 42424242,
  "sequenceNamespace": "batch-2026-07-23",
  "variableNamespace": "batch-2026-07-23",
  "documents": [
    {
      "templateId": "tpl_9f3a1c2e",
      "alias": "order",
      "count": 3,
      "params": {
        "name": "Jane Doe"
      }
    }
  ]
}

Responses

200Batch executed synchronously (small batches)

object

{
  "batchId": "batch_7d2e4f10",
  "status": "completed",
  "seed": 42424242,
  "results": [
    {
      "batchId": "batch_7d2e4f10",
      "alias": "order",
      "seqNo": 0,
      "templateId": "tpl_9f3a1c2e",
      "status": "completed",
      "result": "Hello Jane Doe, order #1001",
      "documentSeed": 123456789
    }
  ]
}
202Batch accepted for async processing

object

{
  "batchId": "batch_7d2e4f10",
  "status": "queued",
  "seed": 42424242
}
400Validation or template/generation error

ErrorEnvelope

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "\"name\" is required",
    "details": {
      "field": "name"
    }
  }
}
401Missing, malformed, or invalid API key

ErrorEnvelope

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing or invalid API key",
    "details": {}
  }
}
GET/v1/batches/{batchId}

Get batch status and documents

ParamInTypeRequiredDescription
batchIdpathstringYes—

Responses

200Batch details

object

{
  "batchId": "batch_7d2e4f10",
  "tenantId": "tenant-acme-01",
  "seed": 42424242,
  "status": "completed",
  "spec": {
    "seed": 42424242,
    "sequenceNamespace": "batch-2026-07-23",
    "variableNamespace": "batch-2026-07-23",
    "documents": [
      {
        "templateId": "tpl_9f3a1c2e",
        "alias": "order",
        "count": 3,
        "params": {
          "name": "Jane Doe"
        }
      }
    ]
  },
  "documents": [
    {
      "batchId": "batch_7d2e4f10",
      "alias": "order",
      "seqNo": 0,
      "templateId": "tpl_9f3a1c2e",
      "status": "completed",
      "result": "Hello Jane Doe, order #1001",
      "documentSeed": 123456789
    }
  ]
}
401Missing, malformed, or invalid API key

ErrorEnvelope

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing or invalid API key",
    "details": {}
  }
}
404Resource does not exist

ErrorEnvelope

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Template tpl_missing not found",
    "details": {}
  }
}