Error codes
Errors use standard HTTP status codes and always return the same JSON shape, with a stable machine-readable code.
{
"error": {
"code": "validation_error",
"message": "The request parameters are invalid.",
"details": { "fields": { "amount": ["The amount must be greater than zero."] } },
"request_id": "9f2c1c1e-..."
}
}Write your logic against code, not message. Messages may change, codes will not. details is only present when there is extra information.
Retry or not?
- 4xx: fix the request first. Retrying the same request will fail the same way. The exceptions are
409 request_in_progressand429, which you can retry after a short wait. - 5xx: safe to retry with the same
Idempotency-Key. Failed requests are not stored, so the retry runs again without creating a duplicate.
All error codes
| Status | Code | Meaning |
|---|---|---|
| Authentication & access | ||
| 401 | authentication_required | No API key was sent. |
| 401 | invalid_api_key | The key is invalid, expired or revoked. |
| 403 | ip_not_allowed | The request IP is not on the key's allowlist. |
| 403 | insufficient_scope | The key lacks the scope in details.required_scope. |
| 403 | account_suspended | The merchant account is suspended. |
| 403 | account_not_allowed | The account cannot perform this action, for example live payments before verification. |
| Request | ||
| 422 | validation_error | One or more fields are invalid. details.fields lists them. |
| 400 | idempotency_key_required | The POST needs an Idempotency-Key header. |
| 400 | invalid_idempotency_key | The key must be 1–191 printable ASCII characters. |
| 422 | idempotency_key_reused | This key was already used with a different request body. |
| 409 | request_in_progress | A request with this key is still running. |
| 409 | duplicate_reference | The reference was already used; see details.existing_id. |
| 404 | resource_not_found | No such object for your account and mode. |
| 429 | rate_limited | Too many requests. See Rate limits. |
| Payments & payouts | ||
| 422 | currency_not_supported | The provider does not support this currency in this direction. |
| 422 | network_not_supported | The network is not supported for this currency. |
| 422 | network_required | A network must be given for this payout. |
| 422 | amount_out_of_range | Below the minimum or above the maximum; see details. |
| 422 | limit_exceeded | Over a per-transaction or daily limit on your account. |
| 422 | insufficient_balance | Available balance does not cover the payout's total debit. |
| 422 | destination_not_supported | The provider cannot pay out to this destination type. |
| 422 | provider_not_available | No enabled provider can handle the request, or the chosen one is not available. |
| 422 | unsupported_operation | The provider does not support this operation. |
| 409 | invalid_state | The object's current status does not allow this, for example cancelling an approved payout. |
| Platform & provider | ||
| 502 / 503 | provider_error and other provider codes | The provider rejected or failed the request. details.retryable says whether a retry may succeed (503) or not (502). |
| 503 | service_unavailable | New payments or payouts are temporarily paused for maintenance. |
| 500 | internal_error | Unexpected error on our side. Retry, and contact support with the request_id if it continues. |