Docs/API reference/Errors

Errors

Apa uses conventional HTTP status codes and returns a consistent JSON error body. Branch on error.code for machine logic and surface error.message to humans.

Error format

Every error response has the same shape:

HTTP/1.1 422 Unprocessable Entity
{
  "error": {
    "code": "amount_below_minimum",
    "message": "The amount is too small to route economically.",
    "param": "amount",
    "request_id": "req_8fK2mQ5xR9"
  }
}
error.codestring
A stable machine-readable code you can branch on (see table below).
error.messagestring
Human-readable description. Safe to log; do not parse.
error.paramstring
The request parameter the error relates to, when applicable.
error.request_idstring
Unique id for this request (prefixed req_). Include it when contacting support so we can trace the call.

HTTP status codes

200 / 201success
Request succeeded. POST that creates a resource returns 201.
400bad_request
Malformed request — unparseable body or invalid syntax.
401unauthorized
Missing, invalid or revoked API key.
404not_found
The requested resource does not exist.
409conflict
Idempotency key reused with a different request body.
422unprocessable
Valid syntax but the request can't be fulfilled (e.g. no_route, amount_below_minimum).
429rate_limited
Too many requests — back off and retry.
500 / 503server_error
Something went wrong on Apa's side. Safe to retry idempotently.

Error codes

error.code is stable across API versions — prefer it over parsing messages.

unauthorized401
Authentication failed — the API key is missing, malformed or revoked.
forbidden403
Authenticated, but this key is not allowed to access the resource.
not_found404
No object exists for the given id.
validation_failed422
The request body failed validation — see error.param and any field errors.
conflict409
The request conflicts with current state — e.g. an Idempotency-Key reused with a different body.
rate_limited429
Request rate exceeded. Retry after the window resets.
server_error500
Something went wrong on Apa's side. Safe to retry idempotently.
invalid_api_key401
The API key is missing, malformed or revoked.
parameter_missing400
A required parameter was not supplied (see error.param).
parameter_invalid400
A parameter has the wrong type or an unaccepted value.
resource_missing404
No object exists for the given id.
idempotency_conflict409
An Idempotency-Key was reused with a different body.
payout_wallet_not_found422
payout_wallet_id does not reference a saved payout wallet.
asset_not_accepted422
The pay asset is disabled for this merchant or not on the Safe List.
amount_below_minimum422
The amount is too small to route economically — ask the customer to pay direct or use a larger amount.
no_route422
No safe route exists between the pay asset and the payout asset right now.
quote_expired422
The routing quote expired before the payment was submitted. Request a new one.

Handling errors

Recommended pattern
Treat 4xx as programmer/customer errors (fix the request or show the customer a message) and 429/5xx as transient — retry with exponential backoff and the same Idempotency-Key so you never create duplicate checkout sessions. For routing errors (no_route, quote_expired), prompt the customer to pick another asset or refresh the quote.