Skip to navigation

Responses & idempotency

Response formats, safe retries and how to handle uncertain outcomes when moving money.
View as Markdown

Response formats

Response shapes differ by section. Each endpoint in the API reference shows its exact responses.

ShapeUsed by
{ "status": "success" | "error", "message"?, "data"? }Customers, transactions, virtual accounts, corporate, crypto, cards
{ "success": true | false, "message"?, "data"? }VTU (airtime, data, bills) and List Customers
{ "message", "data" } or { "error": "..." }Payouts
Bare arrayList Settlement Accounts and List Supported Banks

Validation errors return 400 with { "status": "error", "message": "Validation error", "details": [ ... ] }. Corporate endpoints use their own errors[] format.

Idempotency and outcomes

SectionIdempotency keyUncertain outcome
PayoutsHeader named exactly idempotencyKey (a new value per payout)202: still processing. Get the final result from the payout webhook or Check Payout Status
VTUidempotencyKey in the JSON body200 with status: "PENDING". Do not retry; check Fetch Single VTU Transaction
Card fundingNone400 "Card funding is being confirmed. Do not retry..."

For payouts, the header must be named idempotencyKey. Idempotency-Key is not recognised and returns 400 Idempotency key is required.

Retrying safely

Use a new key for every new transaction. To retry the same transaction after a network error on your side, resend the identical key:

  • VTU returns the existing transaction.
  • Payouts return 400 Transaction already processed. Check the payout status instead.

Refunds

Definite rejections from a provider are refunded automatically before you get the response.

Timeouts are never refunded automatically, because the provider may have delivered. Shimi reconciles them.