Error Codes

All PAX errors return the canonical envelope { ok: false, error: { code, message, details? }, meta: { request_id } }. Reference request_id in support tickets.

Error response format

{
  "ok": false,
  "error": {
    "code":    "MARKET_NOT_FOUND",
    "message": "Market m_a1b2c3d4 does not exist or is not visible to your account.",
    "details": {
      "market_id": "m_a1b2c3d4"
    }
  },
  "meta": {
    "request_id":   "req_01hjk3n0abcdef",
    "server_ts_ms": 1786190400000
  }
}

Authentication errors (4xx)

HTTPCodeDescriptionResolution
401 MISSING_AUTH No credential header found Send X-Api-Key or Authorization: Bearer or 5×POLY_* HMAC headers
401 INVALID_KEY Key does not exist or is malformed Re-check key from dashboard. Note the sk_live_/sk_test_ prefix must match environment.
401 WRONG_ENV_KEY sk_live_* used on sandbox, or sk_test_* used on production Use the matching key for the environment you're calling. See Auth guide.
401 KEY_REVOKED Key was revoked via DELETE /v1/keys/{id} Mint a new key. Revoke takes effect within 5s cluster-wide.
401 INVALID_SIGNATURE HMAC signature does not match, or timestamp outside 30s skew Re-check signing code — see signing examples. Sync your clock (NTP).
401 SESSION_EXPIRED Session bearer token expired (7d idle or 24h without refresh) Re-authenticate via POST /api/auth/login.
403 INSUFFICIENT_PERMISSIONS Key permissions do not include the required action Mint new key with permissions: ["read","trade"]. Revoke old key.
403 PII_REDACTED Attempted to fetch PII fields (email/phone) via a public path Only self-view paths (/v1/account, /v1/account/*) expose PII.

Validation errors (400)

CodeDescriptionResolution
MISSING_FIELDRequired field absent from body/querySee details.field. Re-check REST spec for the endpoint.
INVALID_TYPEField has wrong type (e.g., number where string expected)Money fields must be decimal string, not JSON number. Timestamps in *_at_ms variant are integers.
INVALID_ENUMField value not in allowed setSee details.field + details.allowed. E.g., side must be buy or sell.
TEMPLATE_PARAMS_INVALIDParams don't match template.params_schema on POST /v1/marketsFetch template via GET /v1/markets/templates; re-check params_schema for required fields.
INVALID_ORDER_SIZEOrder size below template.min_bet or above max_betSee details.min / details.max.
INVALID_PRICEOrder price outside [0, 1] for probability markets, or not a multiple of tick_sizeSee details.tick_size. Round to nearest valid tick.
DUPLICATE_CLIENT_ORDER_IDSame client_order_id used within past 24hUse unique IDs (e.g., UUID). PAX guarantees idempotency for retries with same ID.

Resource errors (404 / 409)

HTTPCodeDescriptionResolution
404MARKET_NOT_FOUNDMarket ID does not exist or not visibleVerify market ID via GET /v1/markets.
404ORDER_NOT_FOUNDOrder ID does not exist or belongs to another accountVerify via GET /v1/account/orders.
404TEMPLATE_NOT_FOUNDTemplate ID does not exist or is deprecatedFetch active templates via GET /v1/markets/templates.
404SANDBOX_ONLYEndpoint (faucet/reset/mock-oracle) called on productionUse https://sandbox.predictasiax.com.
409ORDER_ALREADY_FILLEDCannot cancel — already filledNo action needed. Check final status via GET /v1/account/orders.
409MARKET_CLOSEDMarket has locked / settling / resolvedCheck market.status field before placing orders.

Funds errors (402 / 400)

HTTPCodeDescriptionResolution
402INSUFFICIENT_BALANCENot enough balance_free to cover order + feeCheck GET /v1/account. Sandbox: POST /v1/sandbox/faucet for 10k test USDT.
402INSUFFICIENT_CREATOR_DEPOSITAttempted POST /v1/markets but balance below template.min_creator_depositDeposit more, or pick a template with lower min_creator_deposit.
400SELF_TRADE_PREVENTIONOrder would match your own resting orderCancel resting order first, or set self_trade: cancel_taker on order.

Platform errors (5xx / 503)

HTTPCodeDescriptionResolution
503READ_ONLY_MODEAll write endpoints gated by ops team (safety / maintenance)Check status page. Reads (GET /v1/markets, WS subs) remain available.
503CIRCUIT_BREAKER_OPENTrading paused on this market/asset (extreme volatility, oracle deviation)Retry after 30s. WS circuit_breaker_cleared event fires when reopened.
503MAINTENANCEScheduled maintenance windowSee status page for expected duration.
500INTERNAL_ERRORUnexpected server error (bug, DB issue, etc.)Retry with backoff. Include request_id in support ticket if persistent.
502UPSTREAM_ERRORDownstream dependency failedRetry with backoff. Auto-recovers usually <30s.
504UPSTREAM_TIMEOUTDownstream did not respond within SLARetry once immediately; then backoff.

Rate limit errors (429)

CodeDescriptionResolution
RATE_LIMITEDPer-key rate limit exceededSee Retry-After header (seconds). See Rate limits.
IP_RATE_LIMITEDPer-IP burst limit exceeded (public reads)Same as above, plus mint API key to get per-key higher quota.
GLOBAL_RATE_LIMITEDGlobal burst on shared resourceRetry after Retry-After. Rare — indicates ops incident.

WebSocket errors

WS errors arrive as event messages with type: "error":

{ "type": "error", "code": "SUBSCRIPTION_NOT_ALLOWED", "channel": "account", "message": "AUTH required for private channel" }
CodeDescriptionResolution
SUBSCRIPTION_NOT_ALLOWEDSubscribed to private channel without AUTHSend {"method":"AUTH","token":"sk_..."} first.
INVALID_METHODUnknown method verbOnly SUBSCRIBE / UNSUBSCRIBE / AUTH / LOCALE supported.
HEARTBEAT_MISSEDClient did not respond to server ping within 60sConnection reaped. Reconnect + resubscribe.

Recommended retry policy

Always send client_order_id for POST /v1/orders. PAX guarantees idempotency within 24h — a network timeout followed by retry with the same client_order_id returns the original order without double-placement.