Errors
Every error has the same shape. Branch on code — it’s stable; message is for humans and may change.
{ "error": { "code": "insufficient_funds", "message": "Available balance is too low for this payout", "details": null } }| HTTP | code |
Meaning | What to do |
|---|---|---|---|
| 400 | validation_error |
body/query invalid (details lists fields), amount below the minimum, unknown starting_after |
fix the request; don’t retry as-is |
| 400 | invalid_request |
the request couldn’t be read (e.g. malformed JSON) | fix the request |
| 401 | authentication_required |
no Authorization: Bearer sk_… header |
send your secret key |
| 401 | invalid_api_key |
key malformed, unknown or revoked | check the key and its mode |
| 403 | forbidden |
account suspended, or simulate used with a live key |
contact Xaalis / use a test key |
| 403 | merchant_not_active |
live request while your account isn’t active yet |
use test mode until activated |
| 404 | not_found |
no such object for this key’s merchant and mode | check id and test/live key |
| 409 | idempotency_conflict |
Idempotency-Key reused with different parameters (amount, provider, recipient…) |
use a new key for a different request |
| 409 | invalid_state |
the object can’t do that now (payment already final or expired, subscription no longer active, a test advance already running) | read the object’s state; create a new one if needed |
| 409 | key_secret_unavailable |
a key issuance (API key or agent-wallet key) was retried: a secret is only ever shown once | revoke the key id in the error, then issue a replacement with a new Idempotency-Key |
| 422 | insufficient_funds |
payout larger than available (fee included) |
pay out less |
| 422 | unsupported |
e.g. Orange Money payouts in live mode | use Wave |
| 429 | rate_limited |
more than 100 requests/second on one key (60/s per IP on checkout routes) | wait Retry-After seconds, then retry |
| 502 | provider_error |
Wave / Orange Money failed to start the payment | retry, or offer the other method |
| 503 | temporarily_unavailable |
a dependency is briefly unavailable, or a payout/refund outcome isn’t known yet | retry with the same Idempotency-Key |
| 503 | provider_not_configured |
that provider isn’t enabled on this platform | offer the other method |
| 500 | internal_error |
our bug; request_id is included |
retry with the same Idempotency-Key; report the request_id |
Retry only 429 (after Retry-After), 5xx and network errors — and only with the same Idempotency-Key. Never retry
any other 4xx unchanged.