Concepts
Batches
Run up to 500 applicants through one cascade in a single request, track per-row status, cancel, resume or retry, and export the results.
A batch runs one cascade against many applicants. You submit the rows once; Cascades pre-creates a child execution per row in queued state and works through them in the background. Track progress on the batch, drill into rows with the child-execution list, and export everything when it is done.
How do I create a batch?
POST /workflows/{id}/batches with a rows array — up to 500 rows per request — and an Idempotency-Key. Each row carries its own external_reference and applicant:
{
"rows": [
{ "external_reference": "row-1", "applicant": { "first_name": "Ava", "last_name": "Stone" } },
{ "external_reference": "row-2", "applicant": { "first_name": "Ben", "last_name": "Park" } }
],
"execution_mode": "test",
"external_reference": "rentvine-batch-001"
}The response is 202 Accepted with the batch. More than 500 rows is 422 validation_failed (rows: max 500 rows per batch). The idempotency key is compared against a hash of the rows: the same key with the same rows returns the original batch, the same key with different rows returns 409 idempotency_conflict.
Batches need an active cascade, even in test mode (see the next section). execution_mode: live needs production access (403 live_mode_forbidden). Needs executions:write.
Why does my batch return 409 workflow_inactive?
The cascade is a draft (active: false). A draft refuses every batch create with 409 workflow_inactive, in test mode too, before the rows are checked. A single trigger is different: POST /workflows/{id}/trigger with execution_mode: test runs on a draft and answers 202.
A sandbox account (not yet approved for production) cannot activate a cascade, so its cascades stay drafts and every batch create returns this 409. To run a batch:
- Get the account approved for production through the activation form at /activate.
- Activate the cascade: turn on its Status toggle on the Cascades list in the app, or
PATCH /workflows/{id}withactive: truefrom a key made at /api-keys. Docs keys cannot activate a cascade (403 activation_forbidden). - Create the batch. Test mode still works on an active cascade, so you can try it before you run live.
Until then, run single test-mode triggers on the draft to check the cascade one applicant at a time.
What are the batch statuses?
| Status | Meaning |
|---|---|
pending |
Accepted, dispatch not started |
running |
Rows are being processed |
interrupted |
Processing stopped before every row finished (worker restart, streaming disconnect) — resumable |
completed |
Every row reached a terminal status, including rows that failed (count them with failed_count) |
cancelled |
Stopped by POST /batches/{id}/cancel |
failed |
The batch itself stopped on an unexpected error. Rare; filter[status] does not accept it |
total_count, completed_count and failed_count on the batch give you a progress bar without listing rows.
How do I follow the rows?
GET /batches/{id}/executions lists child executions in row_index order with each row's status, retry_count, external_reference, needs_human_review and review_status. Filter with filter[status]=failed,skipped. Each child is a normal execution: GET /executions/{id} returns its detail and step_outputs, and it emits its own execution.completed / execution.failed webhook with batch_execution_id set — so integrations that process batches as a whole can ignore per-row events and watch the batch instead.
Cancel, resume, retry
POST /batches/{id}/cancelhalts dispatch and marks queued and in-flight rowscancelled. Onlypending,runningandinterruptedbatches can be cancelled (409 batch_not_cancellable).POST /batches/{id}/resumere-queues the remaining rows of aninterruptedbatch (409 batch_not_resumableotherwise). The cascade must still be active and live batches still need production access.POST /batches/{id}/retry_failedre-queues everyfailedrow under the per-row retry cap and everyskippedrow, clearing their stale terminal state (409 batch_not_retryablewhen there is nothing to retry).
All three answer 202 with the batch. Resume and retry also answer 409 workflow_inactive when the cascade was set back to a draft after the batch was created.
How do I export results?
| Endpoint | Returns |
|---|---|
GET /batches/{id}/exports.csv |
One row per child execution: identity, status, decision, headline report fields |
GET /batches/{id}/exports.zip |
Error report, per-product CSVs, per-row JSON, and the report PDFs |
GET /batches/{id}/adverse_action_notices.zip |
Every applicant's adverse-action notice PDFs (404 not_found if none exist yet) |
Add ?include=all to the CSV or ZIP to include re-evaluation revisions rather than only the latest state per applicant. All three are gated behind executions:read:full because the contents are raw applicant data.
Related
- Executions — the per-row lifecycle
- Idempotency
POST /workflows/{id}/batches