Skip to main content

Error codes

Every response carries a code. It is the normative field: map your switch codes to it, not to the HTTP status, and not to the message text.

Info

message is written for humans and may be reworded. code is contractual and will not change meaning.

Safe to retry

CodeHTTPWhat to do
INTERNAL_ERROR500Retry with the same reference
SERVICE_UNAVAILABLE503Retry with the same reference
RATE_LIMITED429Back off, honour Retry-After, same reference
REQUEST_IN_PROGRESS409Your earlier attempt is still settling. Wait, then poll
Check

A timeout with no response at all belongs in this group. Retry with the same reference — idempotency guarantees at most one credit.

Settle, then retry

CodeHTTPMeaning
PARTNER_EXPOSURE_LIMIT_EXCEEDED402You are at the ceiling on what you may owe at once
PARTNER_DAILY_CAP_EXCEEDED402Today's agreed volume cap is reached

Nothing moved and nothing is wrong with the request. Settle what you owe — or wait for the daily cap to roll over — then retry with the same reference.

Do not retry — fix the request

CodeHTTPMeaning
INVALID_REQUEST400Malformed, or a required field is missing
AMBIGUOUS_BENEFICIARY400More than one beneficiary identifier
UNSUPPORTED_CURRENCY400Not the currency your account settles in
AMOUNT_BELOW_MINIMUM400Under your agreed minimum
AMOUNT_ABOVE_MAXIMUM400Over your agreed maximum
REFERENCE_CONFLICT409That reference already exists with a different body

Do not retry — authentication

CodeHTTPMeaning
INVALID_SIGNATURE401Signature mismatch. See Authentication
STALE_REQUEST401Timestamp outside the ±2 minute window. Check your clock
INVALID_API_KEY401Unknown, inactive or expired key
REPLAYED_REQUEST409Nonce reused. Generate a fresh one per attempt
PARTNER_MISMATCH403X-Partner-ID disagrees with your key
PARTNER_SUSPENDED403Your account is not active. Contact us
IP_NOT_ALLOWED403Source address is off your allowlist
SCOPE_DENIED403Your key lacks the scope for this endpoint

Do not retry — the beneficiary or the limits

CodeHTTPMeaning
BENEFICIARY_NOT_FOUND404No such account, number or card
BENEFICIARY_NO_ACCOUNT422Found, but not onboarded with a wallet
BENEFICIARY_INACTIVE422The account is not active
BENEFICIARY_BLOCKED422The account is blocked
CARD_NOT_ASSIGNED422The card is not linked to a subscriber
KYC_LIMIT_EXCEEDED422Over the customer's per-transaction KYC limit
MAX_BALANCE_EXCEEDED422Would push the wallet past its KYC ceiling
DAILY_LIMIT_EXCEEDED422Over the customer's daily or monthly limit
COMPLIANCE_HOLD422Held for compliance review
Warning

These are about the customer, not about you. Tell them what to do — top up less, complete KYC, contact support — rather than retrying.

Call POST /api/v1/inbound/name-enquiry first and read max_creditable to avoid most of this class before you debit anyone.

Reversals

CodeHTTPMeaning
REFERENCE_NOT_FOUND404No transaction under that reference
ALREADY_REVERSED409That credit was already reversed
NOT_REVERSIBLE422The original is not a completed credit
REVERSAL_WINDOW_EXPIRED422Past the agreed window, seven days by default
INSUFFICIENT_SUBSCRIBER_BALANCE422The customer already spent it
Note

INSUFFICIENT_SUBSCRIBER_BALANCE is deliberate: a reversal never overdraws a consumer wallet. That case becomes a manual recovery conversation, and we would rather tell you plainly than leave a customer at a negative balance.