Skip to main content
New to bulk transfer? Read the overview first — it explains statuses, reprocessing, and idempotency, all of which apply to this endpoint.
Creating a bulk transfer validates and records every transfer in the batch, then returns immediately — a 201 response means the batch was accepted, not that any money has moved. Nothing executes yet at this point.
Creating a batch does not start processing it. Immediately after this call, follow up with Process a bulk transfer using the returned bulkTransferId to actually begin executing the transfers.

Endpoint

POST /clients/business/customers/funds/bulk-transfer

Headers

x-api-key
string
required
Your public API key.
x-api-secret
string
required
Your API secret. Use a stl_test_... value in sandbox, stl_live_... in production.
businessId
string
required
Your business ID.

Request body

batchName
string
required
A name for this batch, up to 255 characters. Must be unique among your business’s bulk transfers — reusing a name returns 409 Conflict instead of creating a second batch, so it’s safe to retry a timed-out create request with the same batchName.
transfers
array
required
A non-empty array of transfers to execute, up to 5,000 entries. Larger batches must be split across multiple requests.
transfers[].amount
string
required
Amount to transfer, in kobo, e.g. "100000" for ₦1,000.
transfers[].receiverAccountNumber
string
required
The destination bank account number to credit.
transfers[].receiverBankCode
string
required
The bank code of the receiving bank.
transfers[].retrievalReference
string
required
A unique reference you generate for this transfer. Must be unique across your business’s entire transfer history — not just within this batch — and is also used for idempotency and reconciliation.
transfers[].narration
string
A description of the transfer. Optional — defaults to an empty string if omitted.

Response

status
boolean
true on success.
message
string
Confirmation message, e.g. "Bulk transfer created successfully".
data.bulkTransferId
string
Unique ID for this batch. Use this in every other bulk transfer endpoint.
data.bulkReference
string
A human-readable reference for this batch, e.g. "BULK-a1b2c3d4e5f6g7h8i9j0".
data.totalItems
integer
The number of transfers accepted into this batch.
data.status
string
Always "pending" in the create response — processing hasn’t started yet. See statuses.

Code examples

curl -X POST https://sandbox.stellasbank.com/api/v1/clients/business/customers/funds/bulk-transfer \
  -H "x-api-key: stl_c8e286ca55b0123e0b05da047494f585" \
  -H "x-api-secret: stl_test_6332e4b1dd6c2e5814395b549aec6deb0d0664406c66f2285f95f801c76117c0" \
  -H "businessId: YOUR_BUSINESS_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "batchName": "July salaries",
    "transfers": [
      {
        "amount": "100000",
        "receiverAccountNumber": "1234567890",
        "receiverBankCode": "058",
        "retrievalReference": "salary_2024_07_001",
        "narration": "July salary"
      },
      {
        "amount": "200000",
        "receiverAccountNumber": "0987654321",
        "receiverBankCode": "058",
        "retrievalReference": "salary_2024_07_002",
        "narration": "July salary"
      }
    ]
  }'
const res = await fetch(
  "https://sandbox.stellasbank.com/api/v1/clients/business/customers/funds/bulk-transfer",
  {
    method: "POST",
    headers: {
      "x-api-key": "stl_c8e286ca55b0123e0b05da047494f585",
      "x-api-secret": "stl_test_6332e4b1dd6c2e5814395b549aec6deb0d0664406c66f2285f95f801c76117c0",
      businessId: "YOUR_BUSINESS_ID",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      batchName: "July salaries",
      transfers: [
        {
          amount: "100000",
          receiverAccountNumber: "1234567890",
          receiverBankCode: "058",
          retrievalReference: "salary_2024_07_001",
          narration: "July salary",
        },
        {
          amount: "200000",
          receiverAccountNumber: "0987654321",
          receiverBankCode: "058",
          retrievalReference: "salary_2024_07_002",
          narration: "July salary",
        },
      ],
    }),
  }
);
const { data } = await res.json();
const bulkTransferId = data.bulkTransferId;
import requests

res = requests.post(
    "https://sandbox.stellasbank.com/api/v1/clients/business/customers/funds/bulk-transfer",
    headers={
        "x-api-key": "stl_c8e286ca55b0123e0b05da047494f585",
        "x-api-secret": "stl_test_6332e4b1dd6c2e5814395b549aec6deb0d0664406c66f2285f95f801c76117c0",
        "businessId": "YOUR_BUSINESS_ID",
    },
    json={
        "batchName": "July salaries",
        "transfers": [
            {
                "amount": "100000",
                "receiverAccountNumber": "1234567890",
                "receiverBankCode": "058",
                "retrievalReference": "salary_2024_07_001",
                "narration": "July salary",
            },
            {
                "amount": "200000",
                "receiverAccountNumber": "0987654321",
                "receiverBankCode": "058",
                "retrievalReference": "salary_2024_07_002",
                "narration": "July salary",
            },
        ],
    },
)
data = res.json()["data"]
bulk_transfer_id = data["bulkTransferId"]

Example response

{
  "status": true,
  "message": "Bulk transfer created successfully",
  "data": {
    "bulkTransferId": "6f9d3e2a-1b4c-4a8d-9e2f-3c1a2b4d5e6f",
    "bulkReference": "BULK-a1b2c3d4e5f6g7h8i9j0",
    "totalItems": 2,
    "status": "pending"
  }
}

Errors

This endpoint returns 400 BAD_REQUEST for any of the following, with a message describing which check failed:
SituationExample message
businessId header missing"businessId is required in headers"
transfers missing or empty"transfers array is required and must not be empty"
batchName missing or blank"batchName is required"
More than 5,000 transfers"Maximum 5000 transfers allowed per bulk transfer request. Split larger batches into multiple requests."
A required field missing on one transfer"Transfer at index {i} is missing required fields"
Two transfers in the same request share a retrievalReference"Duplicate retrievalReference \"{ref}\" within the same request"
A retrievalReference was already used previously"Retrieval reference {ref} already exists"
A repeated batchName for the same business returns 409 Conflict ("A batch named \"{batchName}\" already exists for this business"), not 400 — check for 409 separately if you retry create requests automatically.
See Errors for the full envelope and error code reference.

Next step

Process a bulk transfer

Start executing the transfers in this batch.