Cessio Docs
Guides

Error handling

The stable error contract and what your bot should do for each case

Error bodies are {error, code?}. Match on the HTTP status and the machine-readable code; the error string is for logs and humans — its wording may change without notice.

The matrix

HTTPcodeMeaningBot action
400invalid body (zod validation text in error)fix the request, don't retry as-is
401unknown API keyfix config, don't retry
403not invited to the RFQ / not your quotedrop, don't retry
404RFQ or quote gone / already closeddrop, don't retry
409RETRY_LATERtransient precondition: quote anchoring or service activation in flightretry with backoff
409INSUFFICIENT_FUNDSa settlement leg cannot be fundedterminal for the trade
409WALLET_MAKER_UNSUPPORTEDthe self-custody wallet path is frozendon't retry until re-enabled
409(none)deadline passed · quote already settling · an explicit validUntil > deadline · contract contentionread error, usually drop
501the endpoint has no implementation for a self-custody party — only reachable by the frozen wallet mode, never by a self-registered makerdon't retry
503ledger unavailable / busy / auth hiccupretry with backoff

Batch execute: partial failure and retries

A signatures batch on POST /tx/execute answers 200 even when entries fail — check each entry's status. A failed entry carries retryable: true is transient (ledger unavailable or busy — retry that entry with backoff), false is terminal for that entry (unknown, expired, contract gone). The error text is for logs, as everywhere.

The reliable recovery after a failed or timed-out execute is GET /tx/pending: an action still listed wants its signature again; an action absent from the list is done — the desk executed it. A blind resend of the whole batch would instead report error for every entry that already succeeded.

WebSocket errors

The stream closes with 4401 on a bad apiKey. Any other close is operational — reconnect with backoff; the snapshot restores your state (see Subscribe to RFQs).

Practical notes

  • A 409 on POST /maker/quotes after the RFQ deadline is normal racing — RFQ deadlines are short by design. Drop the RFQ and move on.
  • trade.failed on the stream is not an HTTP error but is terminal the same way: the trade is dead, nothing moved, the RFQ is closed.
  • Malformed frames on the stream should be ignored, not fatal — parse defensively.

On this page