Skip to main content
All API errors use one JSON shape. Read the HTTP status first, then errors[].code.

Response format

One response can hold several entries, for example one per invalid field.

On-chain order errors look different

Errors raised by the signed-order checks are sent as a 400 with two entries. The first carries the message. The second has attr: "code" and puts the code in detail. Both entries have code: "invalid".
400 Bad Request
To read the code of a 400, look for the entry with attr == "code" and take its detail. Some on-chain errors have no such entry; match those on the message entry (attr == "detail").
python

Authentication and limits

Wallet-derived API keys

Returned by POST /api-keys/derive/.

Order validation

Returned by POST /orders/ before any signature check. In batch endpoints the same errors appear inside each item’s errors instead of as an HTTP error.

On-chain order errors

Returned by POST /orders/ on the phase-one preview host, in the two-entry form. All are 400. On-chain errors without a code entry: POST /orders/signing-context/ returns 400 with one entry (attr: "detail") and one of these messages: No Safe registered for this chain., Safe is not deployed on-chain yet., No enabled pool wallet for this chain., No ledger account for <currency>.
After any failed create, fetch a new signing context before you sign again. Do not reuse the previous nonce or maxUsdcRaw.

Cancel

Batch cancel and cancel-all report per-order results in a 200 response instead.

Wagers

Websocket authorization

POST /pusher/auth/ answers with a plain {"detail": "..."} body, not the format above: 400 when channel_name or socket_id is missing, 401 without valid credentials, and 403 for a private channel that is not your own private-user-{user_id}.

Server errors

A 5xx with type: "server_error" means the request did not complete. For an order create, list your orders before retrying: the order may exist.