Send a batch
A batch submits up to 1,000 payouts in one request, validates every line, then waits for you to confirm or cancel. Batch payouts covers when to use one and its limits.
- Submit the run with
POST /payments/organizations/{orgId}/payouts/batches. - Watch it with
GET …/batches/{batchId}. - Review the lines with
GET …/batches/{batchId}/items. - Confirm with
POST …/batches/{batchId}/confirm, or cancel. - Join each created payout to your ledger.
-
Submit the run
Section titled “Submit the run”A
202means received, not paid. Each line ofitemsis aPOST /payoutsbody.POST /payments/organizations/{orgId}/payouts/batchesx-api-key: avvio_live_…Idempotency-Key: payroll-2026-09-01-run1Content-Type: application/json{"externalReferenceId": "payroll-2026-09-01","autoCommit": true,"items": [{ "amount": "200.00", "destinationAccountId": "sbx_acct_MXN_4471_ae66cbc5", "reference": "PAYROLL-2026-0042" },{ "amount": "150.00", "destinationAccountId": "sbx_acct_MXN_0002_1b02c77d", "reference": "PAYROLL-2026-0043" }]}{"batchId": "cmf3k2xg00009q8b7v0w2x4yz","externalReferenceId": "payroll-2026-09-01","status": "received","autoCommit": true,"counts": { "received": 2, "invalid": 0, "validated": 0, "creating": 0,"created": 0, "create_failed": 0, "canceled": 0, "requires_review": 0 },"createdAt": "2026-09-01T14:03:11.000Z","updatedAt": "2026-09-01T14:03:11.000Z","completedAt": null}An unknown field on any line refuses the whole request with
400. A throttled submit gets429withRetry-Afterin seconds; resend with the same key.The run id and the key
Section titled “The run id and the key”Idempotency-Keyidentifies the HTTP attempt: the same key and body within 7 days returns the same batch, with theIdempotency-Replayedheader (Idempotency).externalReferenceIdidentifies the run permanently, so it also catches a job that loses its key and re-runs the file under a fresh one. It is required, 1 to 128 characters of letters, digits, spaces and. _ : -, and unique per organization. Submit acceptsX-Allow-Duplicate: true, but the run id must still differ. A second batch with the same id answers:// 409{"type": "PAYOUT_BATCH_DUPLICATE_REFERENCE","message": "A batch with externalReferenceId \"payroll-2026-09-01\" already exists (cmf3k2xg00009q8b7v0w2x4yz). NOTHING WAS SUBMITTED. …","originalBatchId": "cmf3k2xg00009q8b7v0w2x4yz"}If this was a retry, continue from
originalBatchId. A new run, such as corrected lines, needs its own id (payroll-2026-09-01-r2).GET …/batches?externalReferenceId=finds the run an id already names.
Section titled “autoCommit”autoCommitWith
true(the default), a run with no validation errors goes straight to creation and a run with any error holds atawaiting_confirmation. Withfalse, it always holds. When approvals are required,autoCommitis forced off andconfirmcaptures the approval. -
Watch it move
Section titled “Watch it move”GET /payments/organizations/{orgId}/payouts/batches/{batchId}{"batchId": "cmf3k2xg00009q8b7v0w2x4yz","externalReferenceId": "payroll-2026-09-01","status": "awaiting_confirmation","autoCommit": true,"counts": { "received": 0, "invalid": 3, "validated": 247, "creating": 0,"created": 0, "create_failed": 0, "canceled": 0, "requires_review": 0 },"estimatedSourceTotal": "49400.00","createdAt": "2026-09-01T14:03:11.000Z","updatedAt": "2026-09-01T14:03:40.000Z","completedAt": null}estimatedSourceTotalis the advisory sum of the valid lines, to compare with your balance before confirming. It isnullwhile validating and when any line usesamountLeg: "destination".A batch tracks creation, not settlement (batch statuses). On a
failedbatch,erroris an object,{ "code": "VALIDATION_RUN_FAILED", "message": "…" }(readerror.code), and no payout exists; contact support with thebatchIdinstead of resubmitting. Instead of polling, listen for thepayout_batch.*webhooks. List your runs, newest first:GET /payments/organizations/{orgId}/payouts/batches?status=&externalReferenceId=&limit=&cursor=limitis 1 to 100 (default 50). A foreign cursor or unknownstatusis a400, never an empty page. -
Review the lines
Section titled “Review the lines”GET /payments/organizations/{orgId}/payouts/batches/{batchId}/items?status=invalidLines come back in order, each echoing its instruction:
{"data": [{"index": 17,"status": "invalid","instruction": { "amount": "200.00", "destinationAccountId": "sbx_acct_MXN_0009_d41d8cd9", "reference": "PAYROLL-2026-0059" },"errors": [ { "code": "DESTINATION_ACCOUNT_NOT_FOUND", "message": "…" } ]}],"hasMore": false,"nextCursor": null}limitis 1 to 1,000 (default 100); the cursor is the last line’sindex. Error codes match a singlePOST /payouts(Errors).?format=csvreturns the whole run, filtered by?status=, with columnsindex, status, payoutId, amount, amountLeg, destinationAccountId, reference, errorCode, errorMessage(first error per line only).Item statuses
Section titled “Item statuses”Status Meaning Terminal receivedStored, not yet examined invalidFailed validation; see errors. No payout✓ validatedWaiting for creation or your confirm creatingA quote/accept is in flight createdA payout exists; payoutIdis set✓ create_failedRefused at creation; see errors. No payout✓ canceledBatch canceled before this line was attempted ✓ requires_reviewOutcome unknown; see below ✓ Lines that need review
Section titled “Lines that need review” -
Confirm or cancel
Section titled “Confirm or cancel”Both take an
Idempotency-Key, and both act only before the run is committed.POST /payments/organizations/{orgId}/payouts/batches/{batchId}/confirmIdempotency-Key: <a uuid>Confirm works only in
awaiting_confirmation, otherwise409 PAYOUT_BATCH_NOT_CONFIRMABLE. Valid lines go to creation; resubmit fixedinvalidlines as a new batch with a newexternalReferenceId.With approvals required, the first confirm answers
202with one approval for the whole run:{ "status": "pending_approval", "approvalId": "cmf3k2xf90008q8b7q4r6s8tu", "requiredApprovals": 2, "expiresAt": "…" }At quorum the run is released within a minute. A repeat confirm returns the same approval; after a rejection it is
409 PAYOUT_BATCH_AWAITING_APPROVAL, and cancel still works (Approvals).POST /payments/organizations/{orgId}/payouts/batches/{batchId}/cancelIdempotency-Key: <a uuid>Cancel works in
received,validatingorawaiting_confirmation, so a canceled batch never produces a payout; later it is409 PAYOUT_BATCH_NOT_CANCELABLE. A created payout can be canceled withPOST …/payouts/{payoutId}/cancelonly while it waits on your own funding. -
Join the run to your ledger
Section titled “Join the run to your ledger”GET /payments/organizations/{orgId}/payouts/batches/{batchId}/items?status=createdEach created payout behaves like one sent alone: it appears in
GET /orders, emitspayout.*events, and can still fail or be returned (Track status & failures). Reconcile through the event feed.
Was this page helpful?