Skip to main content
The meCash Bulk Payout API lets you disburse funds to multiple beneficiaries in a single API request. Instead of sending individual transfer requests, you submit a batch of payout orders — ideal for payroll, vendor payments, commissions, and mass disbursements.
Each order within a bulk payout is processed independently. If one transfer fails validation, the remaining valid transfers still execute.

Bulk payout lifecycle

How it works

1
Step 1: Submit bulk payout
2
Send all payout orders in one request to POST /v1/bulk/payout. Each item includes a unique referenceNumber, amount, reason, and full recipient bank details.
3
Request
cURL
curl --location 'https://{{BaseURL}}/v1/bulk/payout' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data '{
    "items": [
        {
            "referenceNumber": "REF_ZZOEAZH8ZJI6",
            "targetAmount": "1500",
            "reason": "Salary payment",
            "recipient": {
                "name": "NNOROM UZOMA CHUKWUDI",
                "account": {
                    "bankName": "FCMB",
                    "sortCode": "214",
                    "accountNumber": "2483520014"
                },
                "paymentChannel": "BANK_TRANSFER",
                "currency": "NGN",
                "country": "NG"
            }
        },
        {
            "referenceNumber": "REF_DZNGDNK5FFGH",
            "targetAmount": "2500",
            "reason": "Salary payment",
            "recipient": {
                "name": "NNOROM UZOMA CHUKWUDI",
                "account": {
                    "bankName": "FCMB",
                    "sortCode": "214",
                    "accountNumber": "2483520014"
                },
                "paymentChannel": "BANK_TRANSFER",
                "currency": "NGN",
                "country": "NG"
            }
        },
        {
            "referenceNumber": "REF_YMSVIDEXJX1Y",
            "targetAmount": "3600",
            "reason": "Salary payment",
            "recipient": {
                "name": "NNOROM UZOMA CHUKWUDI",
                "account": {
                    "bankName": "FCMB",
                    "sortCode": "214",
                    "accountNumber": "2483520014"
                },
                "paymentChannel": "BANK_TRANSFER",
                "currency": "NGN",
                "country": "NG"
            }
        }
    ],
    "paymentChannel": "BANK_TRANSFER",
    "remark": "June 2026 Salary"
}'
Response (202)
copy
{
    "message": "Batch Created",
    "status": "success",
    "data": {
        "batchId": "44cbef79-3b95-4214-bda2-xxxxxxxxxxxx",
        "referenceNo": "KJ5CFZ0YMWJC7",
        "timestamp": "2026-04-08T17:35:54.114741545Z",
        "batchTotal": 15,
        "totalSuccessful": 0,
        "totalFailed": 0,
        "totalPending": 15
    }
}
4
A 202 Accepted response means the batch has been queued — not yet processed. Orders are settled asynchronously. Listen for payout.completed and payout.failed webhooks to track individual transfer outcomes.
5
Step 2: Check batch status (Optional)
6
Poll for results using the batchId returned from Step 1. This is useful if you want to check overall progress without waiting for individual webhooks.
7
Request
cURL
curl --location 'https://{{BaseURL}}/v1/bulk/payout/{{batchId}}/status' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY'
Response (200)
copy
{
    "message": "Transaction Processing",
    "status": "success",
    "data": {
        "state": "pending",
        "batchId": "44cbef79-3b95-4214-bda2-78014f400d11",
        "startTimestamp": "2026-04-08T17:35:54.070396Z",
        "endTimestamp": null,
        "batchTotal": 15,
        "totalSuccessful": 0,
        "totalFailed": 0,
        "totalPending": 15,
        "items": [
            {
                "referenceNumber": "REF_ZZOEAZH8ZJI6",
                "status": "pending",
                "targetAmount": "1500",
                "reason": "Salary payment",
                "recipient": {
                    "id": "f55914fe-0568-473d-bf6f-95c32c71094e",
                    "name": "NNOROM UZOMA CHUKWUDI",
                    "account": {
                        "bankName": "FCMB",
                        "sortCode": "214",
                        "accountNumber": "2483520014"
                    },
                    "paymentChannel": "BANK_TRANSFER",
                    "currency": "NGN",
                    "country": "NG"
                }
            }
        ],
        "paymentChannel": "BANK_TRANSFER",
        "remark": "June 2026 Salary"
    }
}
8
Step 3: Listen for webhooks
9
Every individual payout in the batch triggers its own separate webhook — so a batch with 15 orders will fire 15 individual webhook events. Each webhook is either payout.completed or payout.failed, depending on the outcome of that specific transfer.
10
Use the referenceNumber from each order to correlate incoming webhook events with specific transfers in your system.
11
Your webhook endpoint must be able to handle multiple concurrent deliveries. For a large batch, many webhooks may arrive in quick succession as transfers are settled.
12
See Webhook Signature Verification to secure your endpoint.

Request body breakdown

FieldTypeRequiredDescription
itemsArrayList of individual payout orders (see below).
items[].referenceNumberStringYour unique reference for this specific order.
items[].targetAmountStringAmount to send to the recipient.
items[].reasonStringPurpose of the transfer (e.g. Salary payment).
items[].recipient.nameStringFull name of the recipient.
items[].recipient.account.bankNameStringName of the recipient’s bank.
items[].recipient.account.sortCodeStringBank sort code / bank code.
items[].recipient.account.accountNumberStringRecipient’s bank account number.
items[].recipient.paymentChannelStringPayment method (e.g. BANK_TRANSFER).
items[].recipient.currencyStringTarget currency code (e.g. NGN).
items[].recipient.countryStringTarget country code (e.g. NG).
paymentChannelStringTop-level payment channel for the batch.
remarkStringA general note for the entire batch submission.

Response breakdown

FieldTypeDescription
messageStringConfirmation message from the API.
statusStringOverall request status (success or failed).
data.stateStringThe processing state of the batch (e.g. pending, completed).
data.batchIdStringUnique identifier for the batch submission.
data.startTimestampStringISO 8601 timestamp of when processing began.
data.endTimestampStringISO 8601 timestamp of when processing finished (null if pending).
data.batchTotalNumberTotal number of payout orders in the batch.
data.totalSuccessfulNumberTotal orders that have reached a final success state.
data.totalFailedNumberTotal orders that have failed processing.
data.totalPendingNumberTotal orders still in the queue or being processed.
data.itemsArrayA list of all individual payout orders and their specific statuses.

Key behaviors

BehaviorDescription
Independent processingEach transfer is validated and processed separately. A single failure does not block other orders.
Balance pre-checkThe system validates that your wallet balance covers the total amount plus all fees before processing any orders.
Individual transaction recordsEvery order generates its own referenceNumber. Use the Get Transaction API to fetch full traceability details.
Rate limitsThe bulk endpoint enforces payload size limits. Contact support for your account’s maximum orders per request.
Audit trailBoth the bulk request reference and individual transaction references are logged for compliance and reconciliation.

Use cases

Payroll

Disburse salaries to all employees in one API call instead of hundreds of individual transfers.

Vendor Payments

Pay multiple suppliers and vendors across different banks simultaneously.

Commission Payouts

Distribute commissions or rewards to agents, affiliates, or partners at once.

Next steps

Create Bulk Payout API

Full OpenAPI reference for POST /v1/bulk/payout.

Fetch Batch Status API

Check processing status via GET /v1/bulk/payout/{batchId}/status.

Single Payout Guide

Need to send to just one recipient? Use the standard payout flow.