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

# Bulk payouts

> Disburse stablecoin or fiat payments to multiple recipients from a platform treasury wallet.

> [!NOTE]
>
> **Before you start:** the OMS API is in early access. Every endpoint, including the ones in this guide, requires an early-access API key. [Request access](https://polygon.technology/get-access?utm_source=docs\&utm_medium=card\&utm_campaign=oms_access) before you begin. Bulk payouts are enabled per project; contact us before you build against them.

This guide shows you how to pay many recipients, such as contractors, sellers, or payroll, from one treasury wallet. There is no batch endpoint: a payout run is one quote and one transaction per recipient, which you create in parallel and reconcile together.

The treasury is an OMS wallet owned by a business customer that represents your platform. Each recipient is a counterparty of that customer with a registered bank account. Payouts are in USD over US rails (`ach`, `achSameDay`, `wire`, `rtp`) or SWIFT, or in CAD to Canadian accounts.

Per-recipient payout pattern

Platform treasuryBusiness customer's OMS wallet

<table>
  <thead>
    <tr>
      <th>Recipient</th>
      <th>Rail</th>
      <th>Quote</th>
      <th>Transaction</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Alice</td>
      <td>ACH</td>
      <td>wlt\_treasury → ext\_alice</td>
      <td>txn\_alice</td>
    </tr>

    <tr>
      <td>Bob</td>
      <td>ACH</td>
      <td>wlt\_treasury → ext\_bob</td>
      <td>txn\_bob</td>
    </tr>

    <tr>
      <td>Carlos</td>
      <td>SWIFT</td>
      <td>wlt\_treasury → ext\_carlos</td>
      <td>txn\_carlos</td>
    </tr>
  </tbody>
</table>

## Step 1: Register each recipient once

For each new recipient:

1. Create a counterparty with `POST /counterparties`: `customerId` (your treasury customer), `entityType` (`individual` or `business`), and `firstName` and `lastName` or `businessName`. Address and contact details are optional unless your project requires them.
2. Register their bank account with `POST /external-accounts`, setting `owner` to `{ "kind": "counterparty", "counterpartyId": "ctp_..." }`, `type` to `bankUs`, `bankIban`, or `bankCanada`, and the matching detail object.
3. Wait until the account is `active` (the `externalAccount.statusChanged` webhook tells you), then store its `ext_` ID against the recipient.

[Pay a third party](https://docs.polygon.technology/payments/guides/third-party-payouts.md) walks through these calls with full request and response bodies.

## Step 2: Quote and execute each payout

For every recipient in the run, create a quote from the treasury wallet to the recipient's account, then accept it:

```bash theme={null}
curl -X POST https://sandbox-api.polygon.technology/v0.13/quotes \
  -H "Authorization: Bearer {accessToken}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: run-2026-03-alice-quote" \
  -d '{
    "customerId": "cst_treasury...",
    "source": {
      "type": "walletCrypto",
      "details": { "id": "wlt_treasury...", "asset": "usdc", "network": "polygon" }
    },
    "destination": {
      "type": "bankUs",
      "details": { "id": "ext_alice...", "asset": "usd", "network": "ach", "memo": "INV 2026-03" },
      "amount": "1250.00"
    },
    "metadata": { "payoutRun": "2026-03", "recipient": "alice" }
  }'

curl -X POST https://sandbox-api.polygon.technology/v0.13/transactions \
  -H "Authorization: Bearer {accessToken}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: run-2026-03-alice-txn" \
  -d '{ "quoteId": "qt_..." }'
```

* Set `amount` on the destination to pay an exact amount; OMS computes the USDC to pull, fees included.
* A quote expires after 30 seconds by default, so accept each one as soon as it is created rather than quoting the whole run first.
* Derive each `Idempotency-Key` from the run and recipient, as above, so a retried request cannot pay anyone twice.
* Quote `metadata` is copied onto the transaction; use it to tag the run.
* A `bankIban` destination uses `network: "swift"`; a `bankCanada` destination uses `swift` for USD or `local` for CAD.

## Step 3: Reconcile the run

Follow each payout with the `transaction.statusChanged` webhook, or list the treasury customer's transactions with `GET /transactions?customerId=cst_treasury...`. Each transaction's `destination.owner` identifies the counterparty that was paid. For bank references (rail, `imad`, `uetr`) fetch the payout transfer with `GET /transfers/{transferId}`; see [Bank transfers](https://docs.polygon.technology/payments/guides/bank-transfers.md#step-4-read-the-bank-rail-and-tracking-references).

A payout that fails is retried by OMS where it can (`processing.payoutRetrying`). If it ends `failed`, read `failure` and create a new quote once the cause is fixed.
