SettlraSettlra/Docs
DashboardAPI Playground

Bulk Payouts API

The Bulk Payouts API lets you upload hundreds of payout instructions at once as either a CSV file or a JSON array. Settlra processes each row asynchronously and fires per-payout webhook events as they settle. Use the batch endpoints to monitor overall progress.

POST/v1/batchesCreate a batch (CSV or JSON)
GET/v1/batches/:idGet batch status
GET/v1/batches/:id/payoutsList payouts in a batch

Create a batch

POST/v1/batches

Uploads a batch of payout instructions. Accepts either a multipart CSV file upload or a JSON array body. Settlra validates every row before enqueuing — if any row is invalid the entire batch is rejected with a validation error listing the offending rows.

CSV format

When uploading a CSV, set the Content-Type to multipart/form-data and include the file under the file field. The first row must be the header row with the exact column names shown below.

bash
phone,network,amount_usdc,name,idempotency_key
+256700123456,mtn_uganda,25.00,Grace Nakamura,order_001
+256701234567,airtel_uganda,10.50,David Opio,order_002

CSV column reference

ColumnRequiredDescription
phoneYesRecipient phone number in E.164 format.
networkYesMobile money network slug. See Supported Networks.
amount_usdcYesUSDC amount to send, up to 6 decimal places.
nameNoRecipient full name (used for provider validation where required).
idempotency_keyYesUnique key per row for deduplication. Max 128 chars.

JSON body format

Alternatively, POST a JSON array of payout objects. Set Content-Type: application/json.

json
{
  "payouts": [
    {
      "phone": "+256700123456",
      "network": "mtn_uganda",
      "amount_usdc": 25.00,
      "name": "Grace Nakamura",
      "idempotency_key": "order_001"
    },
    {
      "phone": "+256701234567",
      "network": "airtel_uganda",
      "amount_usdc": 10.50,
      "name": "David Opio",
      "idempotency_key": "order_002"
    }
  ]
}

cURL — CSV upload

bash
"color:#ff7b72">curl "color:#79c0ff">-X POST https://api-sandbox.settlra.com/v1/batches \
  "color:#79c0ff">-H "Authorization: Bearer pk_test_your_key" \
  -F "file=@payouts.csv"

cURL — JSON upload

bash
"color:#ff7b72">curl "color:#79c0ff">-X POST https://api-sandbox.settlra.com/v1/batches \
  "color:#79c0ff">-H "Authorization: Bearer pk_test_your_key" \
  "color:#79c0ff">-H "Content-Type: application/json" \
  "color:#79c0ff">-d '{
    "payouts": [
      {
        "phone": "+256700123456",
        "network": "mtn_uganda",
        "amount_usdc": 25.00,
        "name": "Grace Nakamura",
        "idempotency_key": "order_001"
      }
    ]
  }'

Node.js — CSV upload

javascript
"color:#ff7b72">import Settlra "color:#ff7b72">from '@settlra/node';
"color:#ff7b72">import fs "color:#ff7b72">from 'fs';

"color:#ff7b72">const client = "color:#ff7b72">new Settlra({ apiKey: process.env.SETTLRA_API_KEY });

"color:#ff7b72">const batch = "color:#ff7b72">await client.batches.createFromFile(
  fs.createReadStream('./payouts.csv'),
  { contentType: 'text/csv' }
);

console.log(batch.id);     "color:#8b949e">// "batch_01HXYZ"
console.log(batch.total);  "color:#8b949e">// 150

Response

FieldTypeDescription
idstringUnique batch identifier.
statusstringBatch status. See status values below.
totalnumberTotal number of payouts in the batch.
completednumberPayouts that have reached a terminal success state.
failednumberPayouts that reached a terminal failure state.
pendingnumberPayouts still in progress.
created_atstringISO 8601 creation timestamp.
json
{
  "id": "batch_01HXYZ",
  "status": "processing",
  "total": 150,
  "completed": 87,
  "failed": 3,
  "pending": 60,
  "created_at": "2025-06-23T14:22:01Z"
}

Batch status values

StatusDescription
queuedBatch accepted and waiting to begin processing.
processingAt least one payout is actively being processed.
completedAll payouts reached a terminal state (success or failure).
cancelledBatch was cancelled before all payouts were processed.

Get batch status

GET/v1/batches/:id

Returns the current status and progress counters for a batch.

bash
"color:#ff7b72">curl https://api-sandbox.settlra.com/v1/batches/batch_01HXYZ \
  "color:#79c0ff">-H "Authorization: Bearer pk_test_your_key"
javascript
"color:#ff7b72">const batch = "color:#ff7b72">await client.batches.retrieve('batch_01HXYZ');

console.log(`${batch.completed}/${batch.total} payouts completed`);
"color:#8b949e">// "87/150 payouts completed"
json
{
  "id": "batch_01HXYZ",
  "status": "processing",
  "total": 150,
  "completed": 87,
  "failed": 3,
  "pending": 60,
  "created_at": "2025-06-23T14:22:01Z"
}

List payouts in a batch

GET/v1/batches/:id/payouts

Returns a paginated list of individual payouts that belong to a batch. Filter by status to quickly surface failed rows for retry or reporting.

Query parameters

ParameterTypeDefaultDescription
statusstringFilter by payout status (e.g. FAILED).
limitnumber20Number of results per page (1–100).
offsetnumber0Pagination offset.
bash
"color:#8b949e"># List all failed payouts in a batch
"color:#ff7b72">curl "https://api-sandbox.settlra.com/v1/batches/batch_01HXYZ/payouts?status=FAILED" \
  "color:#79c0ff">-H "Authorization: Bearer pk_test_your_key"
javascript
"color:#ff7b72">const { data } = "color:#ff7b72">await client.batches.listPayouts('batch_01HXYZ', {
  status: 'FAILED',
});

"color:#8b949e">// Inspect and retry each failed payout
"color:#ff7b72">for ("color:#ff7b72">const payout of data) {
  console.log(payout.payout_id, payout.failure_reason);
}
json
{
  "data": [
    {
      "payout_id": "pyt_01HABC123",
      "idempotency_key": "order_001",
      "status": "SETTLED",
      "recipient_phone": "+256700123456",
      "amount_usdc": 25.00,
      "network": "mtn_uganda"
    },
    {
      "payout_id": "pyt_01HABC124",
      "idempotency_key": "order_002",
      "status": "FAILED",
      "recipient_phone": "+256701234567",
      "amount_usdc": 10.50,
      "network": "airtel_uganda",
      "failure_reason": "invalid_recipient"
    }
  ],
  "total": 150,
  "limit": 20,
  "offset": 0
}