Error catalog

Every error response has the same envelope:

{
  "error": {
    "code": "INVALID_INPUT",
    "message": "human-readable explanation",
    "request_id": "uuid-for-support"
  }
}

The code field is stable and machine-readable. The message is for humans and may change between releases. Log request_id and include it in any support request.

Error codes

CodeHTTPCommon causeFix
INVALID_INPUT400Missing required field, value out of range, bad format (e.g. non-numeric amount).Read the message; it names the offending field.
IDEMPOTENCY_REQUIRED400Idempotency-Key header absent or empty on a creation endpoint.Add Idempotency-Key: <uuid> to the request.
IDEMPOTENCY_KEY_REUSED_DIFFERENT_BODY422Same key submitted with a different request body than the original.Generate a new UUID for the new request.
INVALID_DESTINATION400Payout/refund destination address format doesn't match the chain.Verify the address is valid for the specified chain.
MEMO_NOT_ALLOWED400destination_memo supplied for a chain that doesn't use memos (EVM, Tron, etc.).Remove destination_memo; it’s only valid for TON/XRP/Stellar.
UNAUTHORIZED401Missing, expired, or malformed API key.Pass a valid Authorization: Bearer sspay_sec_test_demo_xxxxxxx header.
MISSING_SCOPE403The API key exists but lacks the scope required by this endpoint (e.g. invoices.write).Create a new API key in the cabinet with the required scope.
FORBIDDEN403IP not in the key's allowlist, or resource belongs to a different merchant.Check the key's IP allowlist in the cabinet.
IP_RATE_LIMITED429Too many requests from this IP in the current window (public checkout only, 30 req/min).Back off and retry.
RATE_LIMITED429General rate limit hit.Implement exponential backoff.
NOT_FOUND404Generic not-found (route, resource).Check the path and ID.
INVOICE_NOT_FOUND404No invoice with that public ID for your merchant account.Verify the invoice ID belongs to your account.
PAYOUT_NOT_FOUND404No payout with that ID for your merchant account.Verify the payout ID.
REFUND_NOT_FOUND404No refund with that ID for your merchant account.Verify the refund ID.
WEBHOOK_NOT_FOUND404Webhook subscription not found.Check the webhook ID in the cabinet.
MERCHANT_NOT_FOUND404API key references a merchant that no longer exists.Contact support.
DUPLICATE409Duplicate order_id: another invoice already uses this identifier.Use a unique order_id per invoice.
INVOICE_NOT_CANCELLABLE409Invoice is not in awaiting_deposit state.Only open invoices can be cancelled.
INVOICE_NOT_REFUNDABLE409Invoice is not in a paid state, or has already been fully refunded.Check the invoice status before requesting a refund.
REFUND_EXCEEDS_NET400Requested refund amount exceeds the net amount available (paid minus previous refunds).Reduce the refund amount.
INSUFFICIENT_BALANCE400Payout amount exceeds your available balance for that asset.Check your balance at GET /api/v1/merchant/balance.
DAILY_CAP_EXCEEDED403Payout would exceed your 24-hour withdrawal cap for this asset.Wait until the cap resets, or contact support to raise the limit.
PAY_IN_ASSET_NOT_ALLOWED400The currency+chain combination isn't enabled for your merchant account.Check the asset list in your merchant settings.
ASSET_NOT_ALLOWED400Asset not supported for payout on this chain.Use a supported asset/chain pair.
CHAIN_DISABLED503This network is temporarily unavailable.Try another chain, or retry later.
POOL_EXHAUSTED503Temporarily unable to start a new payment. Retry shortly.Retry after a short delay (seconds to minutes).
PAYOUTS_DISABLED503Payouts are temporarily unavailable.Check the status page or retry later.
LOCK_UNAVAILABLE503The service is busy. Retry with exponential backoff.Retry with exponential backoff.
INTERNAL500Unexpected server error.Retry once; if it persists, include request_id in a support ticket.
CONFIG_MISSING500Temporary server-side configuration error.Contact support with the request_id.