Skip to main content
Every failure answers with the same JSON envelope, including a request that hit the server’s 30-second timeout. Branch on error.code first, then on error.reason when the body carries one. Four errors tell you when to come back, in a Retry-After header: every 429, every 503, a 404 with pick_not_released, and a 408 on a GET or HEAD. A 402 is not one of them, because no timer clears it.

The envelope

A 408 on a POST, PATCH, or DELETE carries no Retry-After. The request may have completed on the server after the timeout fired. Check its state before you repeat it, and reuse its Idempotency-Key.

The 11 codes

error.code has 11 values. One code can arrive under more than one HTTP status, so the table has a row per status and code pair.

The 24 reasons

error.reason is additive. It names the specific cause when there is one more specific than the code, and it is omitted when the code already says everything. A 503 with no error.reason means the rate limiter itself is unavailable, so the API refuses requests rather than letting them through uncounted. Back off every authenticated route for Retry-After seconds.

Retry-After

Four errors carry Retry-After in seconds and error.retry_at as an RFC 3339 instant. Both name the same moment. Sleep against the header, because a duration in seconds is immune to clock skew. Use error.retry_at when you need to schedule an absolute wake.

Handle errors in code

Batch items

A batch endpoint can answer 200 with failed items inside it, so the HTTP status alone does not tell you the call worked. Read data[i].status on every item. When it is error, data[i].error carries a code and a message in the shape above.

What an error does not tell you

  • Whether a wallet exists. trader_not_tracked means the wallet is real and 0xinsider does not capture its fill history, while a plain 404 means the path or the ID is wrong.
  • When a 402 will clear. It never clears on its own. Someone reactivates the subscription, and the same key resumes working.
  • Whether the market moved. A 503 with read_model_warming is about one endpoint’s precomputed data, not about Polymarket.