> ## Documentation Index
> Fetch the complete documentation index at: https://docs.antonpayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Batch Payouts

> Upload a CSV or XLSX of many payouts in a single call. Anton validates, you confirm, Anton processes.

<Note>
  **Editability note:** this guide was drafted from the OpenAPI spec. If the product/engineering team has an updated batch flow (file schema, row limits, validation rules), edit inline — each H2 is self-contained.
</Note>

Batch payouts let you send thousands of payments in one upload. The flow is three phases: **upload → validate → confirm → process**. You can't skip steps; Anton requires you to explicitly confirm after seeing the validation summary.

## When to use batches

* **Payroll** — one upload per pay cycle
* **Marketplace disbursements** — nightly seller settlements
* **Contractor payments** — monthly or bi-weekly payouts to many contractors

For single-digit payouts per call, stick with `POST /v1/payouts`.

## The file format

Download the template to start:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/template" \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN" \
  -o batch-template.csv
```

The template contains the canonical column order and example rows. Column order matters — Anton parses by position as well as name. Supported formats: **CSV** and **XLSX**.

Each row is one payout instruction. Key columns include:

* `external_ref` — your beneficiary reference (used to match existing beneficiaries or create new ones)
* Beneficiary identity fields — populated only when creating a new beneficiary from the row
* `source_amount` or `dest_amount` — decimal string
* `dest_currency`, `dest_country`
* `method`, `reference`, `purpose`
* Method-specific credential columns (e.g., `iban`, `sort_code`, `wallet_address`)

Consult the downloaded template for the exact schema; do not reorder columns.

## Upload a batch

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches" \
  -X POST \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN" \
  -F "file=@payroll-2026-04-30.csv"
```

* Max file size: 32 MB
* Max rows: contact support for current limits

The response returns the batch in `uploaded` status. Anton queues an async validation job — polling the batch endpoint will show the status moving through `uploaded → validating → validated` (or `validation_failed`).

Duplicate uploads of the exact same file within 24 hours return `409 duplicate_file` — use `Idempotency-Key` on the upload if you want deterministic retries (the file hash already acts as one, but explicit keys give clearer error handling).

## Watch for validation

Validation is asynchronous. Poll or subscribe to webhooks:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID" \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN"
```

When `status` moves to `validated`, the response includes a `summary` block:

* `new_beneficiaries` / `matched_beneficiaries` / `existing_beneficiaries`
* Method mix (count of rows per payment method)
* Estimated debits per funding currency
* FX markup in basis points
* Balance-sufficiency check per currency

Review these before confirming. The batch has an `expires_at` — confirm before it expires, or the validated batch is marked `expired` and you have to re-upload.

## Inspect errors before confirming

Row-level validation errors and warnings:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID/errors" \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN"
```

Errors block specific rows; warnings don't. Typical errors:

* Missing required columns
* Invalid currency / country codes
* Amount formatting (non-decimal, too many digits)
* Beneficiary mismatch (PII conflicts with existing record at same `external_ref`)
* Unsupported method for the destination country

Fix errors in your source file and re-upload — batches are immutable once uploaded.

## Confirm a validated batch

Confirmation is irrevocable — once confirmed, Anton creates payouts from valid rows and starts processing.

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID/confirm" \
  -X POST \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN" \
  -H "Idempotency-Key: confirm-$BATCH_ID" \
  -H "Content-Type: application/json" \
  -d '{"source_currency": "USD"}'
```

The `source_currency` in the body is the default funding currency for rows that didn't specify one. Omit to let Anton use your account default.

<Warning>
  Once a batch is `confirmed` you cannot cancel the batch as a whole via `POST /v1/batches/{id}/cancel` — that only works from pre-processing states. Individual payouts within the batch can still be cancelled via `POST /v1/payouts/{id}/cancel` up until they reach `processing`.
</Warning>

## Watch processing

Status progression after confirmation:

```
confirmed → processing → completed | partial | failed
```

* `completed` — every valid row became a successful payout
* `partial` — some rows succeeded, some failed during processing
* `failed` — all rows failed

Subscribe to `batch.completed` and `batch.failed` webhook events rather than polling.

## Inspect per-row results

Once processing finishes, pull the per-row outcomes:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID/results" \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN"
```

Each result has the original row number, outcome (`success` / `failed` / `skipped` / `pending`), and the created `payout_id` (if any). Use this to reconcile your source file with what actually shipped.

For the created payouts themselves:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID/payouts" \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN"
```

These are normal `Payout` records — the full state machine applies, and each fires its own `payout.*` webhook events as it moves through processing and settlement.

## Cancelling

Before processing starts (states: `uploaded`, `validating`, `validated`, `validation_failed`, `confirmed` before worker picks it up), cancel the whole batch:

```bash theme={}
curl "https://api.antonpayments.dev/v1/batches/$BATCH_ID/cancel" \
  -X POST \
  -H "Authorization: DPoP $ANTON_ACCESS_TOKEN"
```

Once `processing` starts, cancel individual payouts instead.

## Resumability

Anton tracks a per-batch `current_row_index` checkpoint — if the batch worker restarts mid-process, it resumes from the last successfully processed row rather than re-processing everything. You don't have to do anything for this to work; it's platform behavior.

## Next steps

<CardGroup cols={2}>
  <Card title="Send a single payout" icon="paper-plane" href="/guides/send-a-payout">
    For low-volume, per-event payout flows.
  </Card>

  <Card title="Handle webhooks" icon="bell" href="/guides/handle-webhooks">
    Subscribe to `batch.*` and `payout.*` events for real-time status.
  </Card>
</CardGroup>
