What you’ll need
- Your secret key. Every call in this guide authenticates with it.
- A funded account in the payout currency.
- A CSV file of recipients, in the exact template below.
The shape of the flow
1
Build the CSV
The column names are fixed. Getting them wrong fails the whole file.
2
Check your categories
Categories group a batch for reporting.
3
Validate the file
A dry run. Every bad row is reported, and no money moves.
4
Upload the batch
The same file, now for real.
5
Track the batch
Read the batch back and watch the rows settle.
Step 1: Build the CSV
The header row must be exactly this, in snake_case:Step 2: Check your categories
A category labels the batch. List the ones available to you:An empty list is normal on a new merchant — it means no categories have been set up yet.
The
category query parameter in Step 4 is still required, so you must send a value
whether or not it appears here.Step 3: Validate the file
This is a dry run. It parses every row, applies the same validation as the real upload, and moves no money. Always do this before Step 4.totalRequestsis every row, not every failure. Here 3 rows were parsed and 2 failed. The count of good rows istotalRequests - failedRequests.length.- Each failure echoes the whole parsed row back in
request. That is how you tell which line of your CSV it came from, since there is no line number. - The second message spells out the three valid ways to name a destination: an internal
accountId, an externalaccountNumber+bankCode, or a stablecoinwalletId+chain+toAddress.
Step 4: Upload the batch
The same file, with the batch settings as query parameters:
Omitting
category returns 400:
Step 5: Track the batch
The calls in this step could not be exercised, because Step 4 does not currently return a
batch id on dev. Shapes are from the API specification, not from a live run — check them
against your own response before depending on them.
page, size, query, status, category, currency, from and
to.
The remaining three take a batch id:
GET /transfers/bulk/{id}— the batch itselfGET /transfers/bulk/{id}/stats— counts by statusGET /transfers/bulk/{id}/transfers— the individual payouts in the batch
When things go wrong
What to do next
- Pay one person out — the single-transfer flow, including how to get bank codes
- Give a Customer a Virtual Account — confirm the balance you are paying from

