Error codes
On failure the envelope carries data: null and a code from the
list below. Branch on the code; the HTTP status is only a hint.
Every endpoint in the API Explorer lists the codes that endpoint can return, under its responses. This page is the union of all of them.
Errors every endpoint can return
| Code | HTTP | When |
|---|---|---|
INVALID_REQUEST_DATA | 400 | Request validation failed — a field is missing, malformed, or unknown. |
INTERNAL_SERVER_ERROR | 500 | Unexpected server error. An internal alert is raised; retry is safe for reads. |
ACCESS_TOKEN_INVALID (401) can be returned by every authenticated endpoint — the token is
missing, invalid, or expired. The open endpoints listed under
Authentication never return it.
Your account
These say something about you, not about the request. They will keep failing until you fix the account, so do not retry them in a loop.
| Code | HTTP | When |
|---|---|---|
INVALID_SIGNATURE | 401 | The client assertion's signature or claims are invalid, or the assertion is stale. |
PARTNER_NOT_FOUND | 404 | The partner for this token no longer exists. |
PARTNER_ACCOUNT_LOCKED | 403 | The partner account is locked. |
PARTNER_IP_NOT_ALLOWED | 403 | The caller IP is not in your allowlist. |
PARTNER_INSUFFICIENT_BALANCE | 402 | Your crypto fund cannot cover the order. Top the fund up. |
USER_EMAIL_INVALID | 400 | userEmail is missing or malformed. |
The user and their KYC
A user must be verified before they can transact. See KYC.
| Code | HTTP | When |
|---|---|---|
USER_REGISTRATION_REQUIRED | 400 | The user is not registered. |
USER_KYC_VERIFICATION_REQUIRED | 400 | The user does not exist, has no KYC profile, or KYC is not verified. |
USER_KYC_UNDER_PROCESSING | 400 | A KYC submission is already being processed. |
KYC_PROFILE_UNDER_REVIEW | 400 | The KYC profile is pending review — the user cannot transact yet. |
KYC_PROFILE_NOT_ELIGIBLE | 400 | The KYC profile was rejected. |
KYC_DOCUMENT_ALREADY_REGISTERED | 400 | KYC is already verified, or the national ID belongs to another profile. |
KYC_DOCUMENT_FORMAT_INVALID | 400 | One or more document images are not valid base64 data URLs. |
HIGHER_KYC_LEVEL_REQUIRED | 400 | The service needs a higher KYC level than the user holds. |
NATIONALITY_NOT_SUPPORTED | 400 | The user's nationality is missing, or not supported for this service. |
HIGH_RISK_USER | 400 | The user is flagged as high risk. |
REQUESTED_INFO_NOT_FOUND | 404 | No KYC profile exists for this user yet. |
The recipient and the payout
| Code | HTTP | When |
|---|---|---|
BANK_NOT_SUPPORTED | 400 | The bank code is not active. Fetch the current bank list. |
INVALID_BANK_ACCOUNT | 400 | The bank account could not be verified. |
HIGH_RISK_BANK_ACCOUNT | 400 | The recipient account or name is flagged as high risk. |
INVALID_TRANSFER_CONTENT | 400 | The transfer description is invalid. |
FIAT_CURRENCY_NOT_SUPPORTED | 400 | The fiat currency is not supported. |
PAYMENT_CHANNEL_NOT_SUPPORTED | 400 | No payment channel is available for this fiat currency. |
QR_CODE_NOT_SUPPORTED | 400 | No supported format could decode the QR code. |
INVALID_PAYMENT_INFO | 400 | A PHP QR payout is missing the additionalData from the QR decoding step. Pass it through verbatim. |
Amounts and limits
| Code | HTTP | When |
|---|---|---|
SELL_AMOUNT_BELOW_MIN | 400 | The fiat amount is below the minimum. |
SELL_AMOUNT_ABOVE_MAX | 400 | The fiat amount is above the maximum. |
AMOUNT_OUT_OF_RANGE | 400 | The fiat amount is below the minimum allowed for this payout. |
TRANSACTION_AMOUNT_LIMIT_EXCEEDED | 400 | The per-transaction amount limit was exceeded. |
DAILY_AMOUNT_LIMIT_EXCEEDED | 400 | The daily amount or transaction-count limit was exceeded. |
MONTHLY_AMOUNT_LIMIT_EXCEEDED | 400 | The monthly amount limit was exceeded. |
The bounds themselves come back on every quote as minAmount and maxAmount — check against those
before you create the order, and you will rarely see these.
Orders
| Code | HTTP | When |
|---|---|---|
DUPLICATE_TRANSACTION_ID | 409 | The orderId already exists for your partner account. |
TRANSACTION_NOT_FOUND | 404 | No order matches that orderId for your partner account. |
TRANSACTION_CREATE_FAILED | 500 | The payout could not be completed after the order was created. The order is already refunded. |
WEBHOOK_SECRET_NOT_FOUND | 400 | The webhookSecretKey matches no registered webhook endpoint. |
DUPLICATE_TRANSACTION_ID usually means your retry worked the first time. Fetch the order rather
than treating it as a failure — see Orders.
Temporary
These are the only codes worth retrying with backoff.
| Code | HTTP | When |
|---|---|---|
SERVICE_NOT_AVAILABLE | 503 | The service is not available for your account or the requested currency. |
SERVICE_UNDER_MAINTENANCE | 503 | Pricing is temporarily unavailable for this currency. |