Errors
Interpret machine codes, request IDs, validation failures, and retryable outcomes.
An API failure uses the same JSON envelope across operations. Read the HTTP status and error.code; use error.message for diagnosis, not application branching.
Error format#
{
"error": { "code": "unprocessable_entity", "message": "request cannot be processed" },
"meta": { "request_id": "00000000-0000-0000-0000-000000000001" }
}The request ID is also returned in X-Request-ID. Preserve it with the operation and resource ID when investigating a failure. Do not log API keys, webhook secrets, or sensitive request bodies.
HTTP status codes#
| Status | Meaning | Your action |
|---|---|---|
400 | Malformed JSON, unsupported field, missing header, invalid type/format, or invalid cursor | Correct the request |
401 | Authentication failed | Check the API key and merchant access |
403 | Permission or IP restriction | Correct access before retrying |
404 | Resource not found in the key's merchant/environment scope | Check the saved ID and environment |
409 | Idempotency or resource-state conflict | Distinguish conflict from retryable in_flight |
422 | Request refused by a business or network rule | Correct the amount, pair, destination, available funds, or resource state |
500 | Unexpected server error | Retry cautiously with the same key and original body |
503 | Service unavailable or outcome still uncertain | Back off and retry the original request; honor Retry-After when present |
The merchant API does not currently publish a fixed request quota or guarantee a quota-specific 429 response. If you receive a retryable 429, honor Retry-After; see rate limits.
Merchant error codes#
| Code | Status | Meaning |
|---|---|---|
validation_error | 400 | Request schema, missing/invalid idempotency key, cursor, or invoice amount/network validation |
unauthorized | 401 | The key cannot authenticate the request |
forbidden | 403 | Required permission missing |
api_key_ip_forbidden | 403 | IP restriction refused the request |
not_found | 404 | Resource absent from the authenticated scope |
conflict | 409 | Key reused for a different request, duplicate invoice external_id, or incompatible resource state |
in_flight | 409 | The identical keyed request is still executing |
unprocessable_entity | 422 | A business rule rejected the operation; currently shared by many amount, balance, destination, and admission refusals |
gate_unknown | 422 | Unknown currency/network pair |
gate_not_enabled | 422 | Invoice/address currency-network pair is known but not enabled for the merchant |
service_unavailable | 503 | A dependency or unresolved execution prevents a confirmed answer |
internal_error | 500 | Unexpected failure |
gate in a code means a currency/network pair. Each operation documents its own HTTP statuses and error codes. A code listed here does not apply to every operation. For example, invoice/address creation can return gate_not_enabled, while merchant payout/refund validation often uses the broader unprocessable_entity code. Follow the operation's description when deciding how to recover.
Payout funding refusals#
Create payout is the only published operation that can refuse on payout funding. Each of these codes names one refusal precisely instead of the broader unprocessable_entity; see funding from other balances.
| Code | Status | Meaning |
|---|---|---|
funding_policy_conflict | 409 | The saved funding policy changed before the payout was accepted |
funding_grant_conflict | 409 | The funding grant changed before the payout was accepted |
funding_not_granted | 422 | The selected funding preferences are outside the grant |
funding_allocation_limit | 422 | Funding the payout would exceed the grant's per-source allocation bound, or the payout-wide bound derived from it |
funding_balance_insufficient | 422 | Eligible native balances cannot fund the payout |
funding_route_unavailable | 422 | No eligible route with the required liquidity can fund the payout |
funding_conversion_fee_payer_invalid | 422 | The funding conversion fee payer must be the merchant or the platform |
The two 409 conflicts mean the configuration moved under the request: re-read the current policy or grant and decide again, rather than repeating the same body. The 422 refusals are decisions about this request; correct the amount, the source, or the funding override before creating another payout.
Idempotency and refusals#
A timeout does not establish whether a mutation succeeded. Reuse the same key and body. Change a request under an existing key only when the response confirms Idempotency-Key-Released: true. A status alone does not prove release. See idempotency.