Error Handling
Every API response uses standard HTTP status codes with structured JSON error bodies.Error Response Format
By default, the/v1/* surface returns the Polymarket-shape
single-field envelope — one error key holding a human-readable
description:
For stable error handling, branch on the
X-Polysim-Code header, not
on the body text — the body holds the prose, the header holds the code.
The X-Request-Id header echoes the request id for log correlation.
402 UPGRADE_REQUIRED is the one carve-out to the PM-shape default:
its body adds feature_key and upgrade_url alongside error so SDKs
can render an upsell flow without an extra round-trip. Every other
status code (401, 403, 404, 429, 5xx, …) sticks with the single-field
shape and exposes the machine code via X-Polysim-Code.
ACCESS_RESTRICTED — an already-issued
key whose account isn’t on the API v1 allowlist, or is flagged / under
review), the body is PM-shape and the code is in the header:
POST /v1/keys
and POST /v1/keys/bootstrap return 403 CLOSED_BETA (the default for
every non-admitted caller, including paying Pro / Pro+; the
API_PRO_COMING_SOON variant appears only once self-serve issuance is
enabled) with the machine code in the X-Polysim-Code header and the
human message in the body’s error field. The feature_key /
upgrade_url hints are body fields only on 402 responses, not these
403s. See Closed Beta Errors below.
HTTP Status Codes
Common Error Codes
Trading Errors
This table is the canonical trading error-code reference — other trading pages link here rather than restating the codes.There is no
409 LIMIT_PRICE_NOT_MET, 409 IDEMPOTENCY_CONFLICT,
CANNOT_CANCEL, or HTTP_409 trading code — those names appeared in
earlier drafts but are not emitted by the engine. Use the codes above.Order status values
OrderResponse.status (and the status filter on GET /v1/orders) use
the PolySimulator-native enum — note the double-L CANCELLED:
SDKs ported from Polymarket read the PM-shape
ORDER_STATUS_* enum from
GET /v1/data/orders instead — where the cancelled member is the
single-L ORDER_STATUS_CANCELED (PM’s exact spelling). The native
GET /v1/orders path uses double-L CANCELLED; the PM-shape
GET /v1/data/orders path uses single-L ORDER_STATUS_CANCELED. See
CLOB Compatibility.
No naked shorts — INSUFFICIENT_POSITION explained
PolySimulator (and Polymarket itself) requires every SELL order to be backed by an
existing position in that exact token_id. There is no margin, no borrow, no
synthetic short. If you try to sell shares you don’t hold, the order is rejected
with 400 INSUFFICIENT_POSITION (header X-Polysim-Code: INSUFFICIENT_POSITION).
For binary markets (every /markets/{id} with two outcomes), the standard
market-maker idiom is a two-sided buy rather than a buy + a short:
GET /v1/account/positions to check
your inventory per token_id before submitting a SELL.
Authentication Errors
Rate Limit Errors
The backend emits two distinct 429 codes (in theX-Polysim-Code
header). Both are retryable and both carry Retry-After — branch on
either, or simply treat any 429 as a back-off signal:
The per-tier limits (authoritative source:
GET /v1/keys/tiers):
Closed-beta cohort keys run at the enterprise tier until the cutoff
(2026-08-31), then auto-downgrade to free + read-only. If a static value
here ever disagrees with
GET /v1/keys/tiers, the endpoint wins.
Closed Beta Errors
The API is in an ongoing closed beta. Key issuance is cohort-gated:
Beta-issued keys carry an
X-API-Beta-Cutoff response header on every request after the cutoff date — SDKs can pivot to read-only mode without an extra round-trip.
Retry Strategy
WebSocket Error Handling
WebSocket connections use custom close codes:Best Practices
Always check status codes
Never assume a 2xx response. Parse the status code and handle each category appropriately.
Use Retry-After header
On 429 responses, the
Retry-After header tells you exactly how long to wait. Don’t guess.Don't retry 4xx errors
Client errors (400-422) indicate a problem with your request. Fix the payload instead of retrying.
Log error details
Always log the full error response body for debugging — the
details field often contains actionable info.