Skip to content

Errors

Every refusal on /v1 answers JSON with the Error body. Branch on error.code: it is stable and catalogued, in upper case. The merchant API’s own refusals carry the code alone; a refusal it relays from the switch keeps the message_en and message_fr the switch gave, as below. A payout route’s own refusals answer MerchantPayoutError, the same body with a shortfall: what the payout balance lacks for INSUFFICIENT_PAYOUT_BALANCE, null for any other code, as the payouts guide shows. An invoice route’s own refusals answer MerchantInvoiceError, the same body with message_en and message_fr always given, as the invoices guide shows.

{
"error": {
"code": "SWITCH_UNAVAILABLE",
"message_en": "Retry with the same key",
"message_fr": "Réessayez avec la même clé"
}
}

Every authenticated /v1 response carries X-Request-Id, the ID the request log keeps for that call: give it when you ask about one. A request the server refuses before routing it, such as a firewall rejection, answers {timestamp, status, error, path} instead, and no page is ever HTML.

A 503 can leave the outcome unknown: retry the exact request with its original Idempotency-Key, which never creates a second payment or payout, and read the payment or payout before you create another.

400 Bad Request
Code When
INVALID_REQUEST The request breaks the contract: a missing or malformed field, header or parameter, or another refusal of the framework without a code of its own.
INVALID_CURSOR The delivery list did not seal this cursor.
401 Unauthorized
Code When
INVALID_API_KEY The key is missing, unknown, revoked or a live key; it is checked on every request, replays included.
403 Forbidden
Code When
INSUFFICIENT_SCOPE The key lacks the permission the route needs, or no permission rule covers the route.
SCOPE_ESCALATION A key asked for permissions beyond its own, keys:manage among them, which no key ever grants, including by rotating a key that holds it.
404 Not Found
Code When
PAYMENT_NOT_FOUND The payment is unknown or belongs to another merchant.
ROUTE_NOT_FOUND No route answers at this address under a covered prefix.
LINK_NOT_FOUND The payment link is unknown or belongs to another merchant, or a list’s cursor names no link of this merchant.
BRANCH_NOT_FOUND The store named for a new link is not this merchant’s.
PAYOUT_NOT_FOUND The payout is unknown or belongs to another merchant, or a list’s cursor names no payout of this merchant.
PAYOUT_BATCH_NOT_FOUND The payout batch is unknown or belongs to another merchant, or a list’s cursor names no batch of this merchant.
PAYOUT_LINE_NOT_FOUND The batch line is unknown or belongs to another merchant, or a cursor names no line of this batch.
NAME_ENQUIRY_NOT_FOUND The name enquiry a payout names is unknown or belongs to another merchant.
INVOICE_BATCH_NOT_FOUND The invoice batch is unknown or belongs to another merchant, or a list’s cursor names no batch of this merchant.
INVOICE_NOT_FOUND The invoice is unknown or belongs to another merchant, or a list’s cursor names no invoice of this batch.
405 Method Not Allowed
Code When
METHOD_NOT_ALLOWED The route does not answer this method; Allow lists those it does.
406 Not Acceptable
Code When
NOT_ACCEPTABLE The route cannot produce what Accept asks for.
409 Conflict
Code When
IDEMPOTENCY_CONFLICT The Idempotency-Key already belongs to another request or mode, a payout command’s key was first used more than 720 hours ago, or a chunk of invoices holds other invoices under a number the batch already received.
METHOD_UNAVAILABLE A new direct admission is refused: its method is unavailable. Nothing is retained.
PARTICIPANT_CAP_EXCEEDED A new direct admission is refused: the participant’s cap is reached. Nothing is retained.
INTENT_EXPIRED A new direct admission is refused: the intent has expired. Nothing is retained.
DIRECT_PAYMENT_NOT_ADMITTED A new direct admission is refused. Nothing is retained.
BRANCH_ARCHIVED A new direct admission is refused: the branch is archived. Nothing is retained.
MERCHANT_LIMIT_EXCEEDED Above the merchant’s per-payment limit, the day’s or month’s in Kinshasa time for a direct payment, the day’s refunds limit, or the merchant’s payout limits, per payout or per day.
PARTICIPANT_LIMIT_EXCEEDED A direct payment above the participant’s maximum per transaction.
PAYMENT_NOT_CANCELLABLE The intent was submitted, is uncertain, ended or expired, or another original holds the key.
REFUND_AMOUNT_EXCEEDED The refund asks for more than remains refundable.
PAYMENT_NOT_REFUNDABLE The payment is not approved.
REFUND_METHOD_UNSUPPORTED The payment’s method cannot be refunded yet.
REFUND_WINDOW_EXPIRED The payment was approved more than 180 days ago.
LINK_NOT_CANCELLABLE The link is paid or expired, or an attempt is under way; cancelling a cancelled link again answers it as it is.
LINK_NOT_SHAREABLE The link is no longer payable.
EVENT_NOT_SUBSCRIBED The event to replay is outside the current subscription.
WEBHOOK_CHANGED The webhook configuration changed since the version you sent: read it again.
STATEMENT_UNAVAILABLE A lot from before statements were recorded has none.
STATEMENT_TOO_LARGE The statement would hold more than 10,000 lines.
INSUFFICIENT_PAYOUT_BALANCE The available payout balance does not cover the payout’s or the batch’s amounts and fees: shortfall gives what is missing. Nothing is reserved.
NAME_ENQUIRY_STALE The payout’s name enquiry is more than 24 hours old.
NAME_ACKNOWLEDGEMENT_REQUIRED The name enquiry could not give the holder’s name and the payout does not acknowledge it.
PAYOUT_DESTINATION_UNKNOWN The participant does not know the payout’s destination account.
PAYOUT_ROUTE_UNAVAILABLE The participant takes no payouts at the moment, or a decision accepts or keeps a ROUTE_PAUSED line.
PAYOUTS_HELD Futa holds the merchant’s payouts: nothing is sent or approved.
PAYOUT_BATCH_TOO_LARGE The merchant’s open payout batches are at their bound of 20, or a chunk’s lines would pass those the batch announced, or all have arrived.
PAYOUT_BATCH_INVALID A line is in another currency or numbered beyond those announced or received, a decision does not fit its line, a submission has no valid line, or the batch would keep one more preparer or key holder than it can.
PAYOUT_BATCH_NOT_VALIDATED The batch is not VALIDATED: its lines are still arriving or being checked, it was submitted or lapsed, or lines are still to review at submission.
PAYOUT_BATCH_CHANGED The batch’s version is no longer the one you sent: read it again.
PAYOUT_LINE_NOT_RETRYABLE The batch has no failed line left that a retry may send.
RESULT_NOT_READY The batch has not reached the state its report or result describes.
INVOICE_BATCH_LIMIT_REACHED The merchant’s open invoice batches, those MAPPING, VALIDATING, RECEIVING or READY, are at their bound of 20 (SYNTHETIC).
INVOICE_BATCH_TOO_LARGE A chunk’s invoice is numbered beyond those the batch announced, or was received in another chunk.
INVOICE_BATCH_CHANGED The batch’s version is no longer the one you sent, or the batch takes no more of this: its invoices have all arrived, it was made from a file, or it is being sent, was sent, failed to send, has lapsed or was discarded. Read it again.
INVOICE_BATCH_NOT_VALIDATED The batch cannot be sent yet: its invoices have not all arrived, its file’s mapping is not confirmed or still being checked, or no invoice is ready.
MESSAGES_NOT_CONFIGURED A channel was chosen outside the sandbox, where no message transport exists yet.
MERCHANT_NAME_INVALID The merchant’s stored name fails the text rule, at most 120 code points once trimmed: the send is refused before anything is made.
413 Content Too Large
Code When
EXPORT_TOO_LARGE The export is too large: narrow the filters. No file is returned.
REQUEST_TOO_LARGE The body exceeds 16 KiB, chunked bodies included, on a /v1 POST that does not bound its own body, or 512 KiB for a chunk of payout batch lines or of invoices; it is refused before it is read.
415 Unsupported Media Type
Code When
UNSUPPORTED_MEDIA_TYPE The request body is not JSON.
429 Too Many Requests
Code When
RATE_LIMITED The merchant’s shared quota is exhausted for now.
NAME_ENQUIRY_RATE_LIMITED The merchant’s name-enquiry budget for the rolling hour is spent, for one destination, one person or key, or the merchant; Retry-After gives the seconds to wait.
500 Internal Server Error
Code When
INTERNAL_ERROR An unexpected failure, logged and never detailed.
503 Service Unavailable
Code When
SWITCH_UNAVAILABLE The switch did not answer: the outcome may be unknown. Retry the exact request with its original key.
INVALID_CREATION_RESPONSE The switch’s answer to a creation was not valid: the outcome may be unknown. Retry with the original key.
INVALID_CANCELLATION_RESPONSE The switch’s answer to a cancellation was not valid: the outcome may be committed. Retry with the original key.
INVALID_LINK_RESPONSE The switch’s answer was not the closed link shape: nothing of it is relayed. Retry, a creation with its original key.
SERVICE_UNAVAILABLE An asynchronous answer timed out.
TOP_UP_UNAVAILABLE The sandbox’s sponsor simulator did not answer a top-up, or the sandbox has no simulator key: the outcome may be unknown. Send the same request again under the same key, which funds at most once.

The merchant API also answers these codes on /v1, which the public contract does not name yet. Publishing the full catalogue of codes is an open gate; until then, branch on them as on the others.

Code Status When
EVENT_NOT_FOUND 404 The event whose attempts you read or that you replay is not this merchant’s.
INVALID_RECEIPT_REQUEST 400 A receipt was asked for with a query other than lang=fr or lang=en.
KEY_NOT_FOUND 404 The key to rotate or revoke is not this merchant’s.
KEY_REVOKED 409 The key to rotate is revoked.
MERCHANT_NOT_FOUND 404 The merchant is disabled, for key and webhook management.
REPLAY_RATE_LIMITED 429 The event was already replayed within the last minute.
WEBHOOK_ALREADY_CONFIGURED 409 The merchant already has an endpoint: move it with POST /v1/webhooks/endpoint/configuration.
WEBHOOK_NOT_FOUND 404 The merchant has no endpoint yet.

The full contract states each operation’s refusals in the API reference.