Create a batch from N rows
/api/v1/workflows/{id}/batches
Pre-creates the batch and N queued child executions in a single
transaction and returns 202; the rows are then processed
asynchronously. Poll getBatch for the counters and
listBatchExecutions for per-row status. Cap of 500 rows per
request; every row must be an object. live requires production
access (403 live_mode_forbidden).
Batches need an active cascade, in test mode too. On a draft
(active: false) every batch create returns 409 workflow_inactive
before the rows, the mode or the Idempotency-Key are checked. A
single test-mode triggerWorkflow on a draft still runs (202).
A sandbox account (not approved for production) cannot activate a
cascade, so it gets this 409 on every batch. To run a batch, an
approved account activates the cascade in the app, or with
PATCH /workflows/{id} and active: true from a key made at
/api-keys (docs keys cannot activate).
Idempotency-Key is required (422 missing_idempotency_key). The
key is compared against the resolved execution_mode,
external_reference and a SHA-256 digest of the rows, so reusing a
key with different content returns 409 idempotency_conflict.
Requires executions:write.
Asynchronous: the response is 202 Accepted. Poll
GET /batches/{id}
until status is terminal.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired |
integer |
Workflow id. Only workflows owned by the token's account resolve; a foreign or deleted id returns |
Header parameters
| Name | Type | Description |
|---|---|---|
Idempotency-Keyrequired |
string |
Unique per-business-event key. Identical resubmissions return
the original response; conflicting bodies return The header is accepted up to 200 characters, but the stored key is
namespaced to your client ( 3fa85f64-5717-4562-b3fc-2c963f66afa6
|
Request body
The rows to run, one applicant payload per row.
-
rowsarray of object required One object per applicant. Every row must be an object.-
external_referencestring -
applicantApplicantPayload Free-form applicant data forwarded to the workflow's first node as `context.applicant`. Field names depend on the workflow definition.
-
-
execution_modestring One oftestlive -
external_referencestring
{
"rows": [
{
"external_reference": "row-1",
"applicant": {
"first_name": "Ava",
"last_name": "Stone",
"email": "ava@example.com"
}
},
{
"external_reference": "row-2",
"applicant": {
"first_name": "Ben",
"last_name": "Park",
"email": "ben@example.com"
}
}
],
"execution_mode": "test",
"external_reference": "rentvine-batch-001"
}Responses
-
202 Batch accepted
application/json-
dataBatchSchema: Batch
-
idinteger -
objectstring -
workflow_idinteger -
statusstring `completed` means every row reached a terminal status, even when some rows failed (see `failed_count`). `failed` means the batch itself stopped on an unexpected error; it is not accepted by `filter[status]` on `listBatches`. One ofpendingrunninginterruptedcompletedcancelledfailed -
execution_modestring One oftestlive -
external_referencestring, nullable -
total_countinteger -
completed_countinteger -
failed_countinteger -
started_atstring (date-time), nullable -
completed_atstring (date-time), nullable -
created_atstring (date-time) -
updated_atstring (date-time)
-
-
metaMetaSchema: Meta
-
request_idstring required Correlation id for this request. Also sent as the `X-Request-Id` response header; quote it when contacting support.
-
202 example{ "data": { "id": 77, "object": "batch", "workflow_id": 27, "status": "pending", "execution_mode": "test", "external_reference": "rentvine-batch-001", "total_count": 2, "completed_count": 0, "failed_count": 0, "started_at": null, "completed_at": null, "created_at": "2026-09-09T14:20:00Z", "updated_at": "2026-09-09T14:20:00Z" }, "meta": { "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f" } } -
-
400
malformed_bodyapplication/json400 example{ "error": { "code": "validation_failed", "message": "The request could not be processed.", "details": [ { "field": "execution_mode", "message": "must be test or live" } ], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/validation_failed" } } -
401 Missing, malformed, expired or revoked bearer token. The
WWW-Authenticateheader carries the RFC 6750 challenge.application/json401 example{ "error": { "code": "unauthorized", "message": "A valid bearer token is required.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/unauthorized" } } -
403
insufficient_scopeorlive_mode_forbiddenapplication/json403 example{ "error": { "code": "live_mode_forbidden", "message": "Live mode requires production access.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/live_mode_forbidden" } } -
404 Resource does not exist or belongs to another tenant / api_client
application/json404 example{ "error": { "code": "not_found", "message": "The requested resource was not found.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/not_found" } } -
409
workflow_inactive(the cascade is a draft, in any mode) oridempotency_conflictapplication/json409 example{ "error": { "code": "workflow_inactive", "message": "Only active workflows can run batches through the public API.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/workflow_inactive" } } -
422
missing_idempotency_keyorvalidation_failed(emptyrows, more than 500 rows, a non-object row, or a badexecution_mode)application/json422 example{ "error": { "code": "missing_idempotency_key", "message": "Idempotency-Key header is required.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/missing_idempotency_key" } } -
429 Rate limit exceeded (60 req/min per IP on
/api/v1, 600 req/hour per token prefix, or 300 req/5 min per IP globally). The body is the standard error envelope andRetry-Aftergives the seconds until the window resets.application/json429 example{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Retry later.", "details": [], "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f", "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/rate_limited" } }