code. It is a stable wire contract in SCREAMING_SNAKE_CASE.
error is prose for a developer reading a log — its wording can change, and it
is not written to be shown to a payer.
traceId identifies this exact request in our logs. Include it when you
contact support.
Client errors
403 vs 404 is deliberate. Reading a session belonging to another partner
returns
NOT_FOUND, not FORBIDDEN — telling you a session exists but is not
yours would leak that it exists. Do not read a 404 as proof the id is invalid.Server and upstream errors
Routing: 422 vs 503
The split is deliberate and worth branching on. UNSUPPORTED_ROUTE (422) means
the asset pair is one we cannot serve — retrying reproduces it, so surface a
different asset to the payer. ROUTE_TEMPORARILY_UNAVAILABLE (503) means the
pair is supported but has no route right now — retry with backoff and it may
clear on its own. Same failure surface, opposite response.
Retrying
Safe to retry — 429, 502, 503, 504
Safe to retry — 429, 502, 503, 504
Transient. Use exponential backoff with jitter.
QUOTE_STALE and
NO_QUOTE_AVAILABLE are worth re-quoting rather than replaying the same
request.Do not retry unchanged — 400, 401, 403, 404, 409, 413, 422
Do not retry unchanged — 400, 401, 403, 404, 409, 413, 422
The request is wrong, or the state is. Retrying reproduces the error.
Session creation is already idempotent
Session creation is already idempotent
Retrying a create with the same
orderId returns the EXISTING session with
200 and created: false rather than opening a second one — so a retry
after a timeout cannot double-charge.OK
OK is the success sentinel, returned alongside error: null. It is in the
same enum so that one field can be checked uniformly; it is not an error.