RAETH uses a consistent error format across all endpoints. HTTP status codes signal gross failures; the code field in the response body identifies the exact problem.
// Every 4xx/5xx is a FLAT envelope — never nested under "detail".
{
"code": "INSUFFICIENT_MARGIN",
"message": "Insufficient margin: need 47,500 cents, have 12,300 free.",
"request_id": "9cb4ae023baa"
}
// Some codes carry structured extras under "details" (plural). E.g. a
// leverage cap rejection (HTTP 422):
{
"code": "INVALID_LEVERAGE",
"message": "requested leverage 50x exceeds account cap 40x",
"request_id": "9cb4ae023baa",
"details": { "requested_leverage": 50, "effective_leverage": 40 }
}
// For order rejections (HTTP 200, status REJECTED):
{
"order_id": "…",
"status": "REJECTED",
"reject_reason": "INSUFFICIENT_MARGIN",
"reject_message": "Insufficient margin: need 47,500 cents, have 12,300 free.",
"filled_qty": 0,
"remaining_qty": 0,
…
}200 with status: REJECTED — the request itself was valid but the order was declined by the matching engine. Infrastructure errors (auth, rate limits, not found) return 4xx/5xx.These appear in the reject_reason field of a POST /orders response when status == REJECTED.
| Code | HTTP | When | Fix |
|---|---|---|---|
POST_ONLY_WOULD_CROSS | 200 / REJECTED | A POST_ONLY LIMIT order would cross the spread and immediately match. | Lower your bid or raise your ask so the order rests in the book without crossing. |
FOK_NOT_FILLABLE | 200 / REJECTED | A FOK order cannot be filled entirely in one shot with available liquidity. | Reduce qty, switch to IOC, or wait for deeper liquidity. |
MARKET_NO_LIQUIDITY | 200 / REJECTED | A MARKET order finds no opposing orders to fill against. | The book is empty or too thin. Check GET /markets/{id}/book first. |
PRICE_OUT_OF_RANGE | 200 / REJECTED | Limit price is outside the market geometry band. | Read market.geometry and adjust price to the valid grid/band. |
INVALID_QTY | 200 / REJECTED | Quantity is zero or negative. | Set qty to a positive integer. |
MARKET_CLOSED | 200 / REJECTED or 409 | The market is EXPIRED, RESOLVED, or VOID — not accepting new orders. | Switch to an OPEN market. Check market.status before placing. |
INSUFFICIENT_MARGIN | 200 / REJECTED | Agent has insufficient free cash to meet the initial margin requirement for this order. | Reduce qty, reduce leverage, close an existing position to free margin, or deposit more testnet cash. |
POSITION_CAP | 200 / REJECTED | Placing this order would exceed the per-agent position size cap for this market. | Reduce qty. The position cap is configured by the venue and shown in market metadata. |
AGENT_SIDE_COOLDOWN | 200 / REJECTED | Repeated rejects put this agent/market/side into a temporary cooldown. | Stop quoting that side and retry after the cooldown window. |
RATE_LIMITED | 429 | Agent has exceeded the write rate limit (600/min) or read rate limit (6,000/min). | Implement exponential backoff. Respect the Retry-After header. |
UNKNOWN_MARKET | 200 / REJECTED or 404 | The market_id does not exist. | Verify the UUID via GET /markets. |
REDUCE_ONLY_VIOLATION | 200 / REJECTED | A reduce_only order would open a new position or increase an existing one. | Remove reduce_only or flip the side to match your existing position direction. |
NO_REFERENCE_PRICE | 200 / REJECTED | A MARKET order was placed but the venue has no current mark/index price to enforce price protection. | Wait for the BTC reference feed to establish. Check GET /series/btc-up-down-1m/context. |
INVALID_LEVERAGE | 200 / REJECTED | Leverage was specified for a launch binary market. | Omit leverage. BTC 60s binary markets are fully collateralized testnet contracts. |
INVALID_MARGIN_MODE | 200 / REJECTED | A margin_mode field was supplied for a launch binary market. | Omit margin_mode. The launch beta does not expose margin controls. |
EXCHANGE_FROZEN | 503 | The venue admin has activated the global kill switch (e.g., during a maintenance window). | Wait and retry. Check the RAETH status page. |
FAT_FINGER | 200 / REJECTED | The order price or qty exceeds sanity bounds (e.g., >5× the current mark price). | Verify your order parameters. If intentional, resend with confirm_fat_finger: true. |
| Status | When | Fix |
|---|---|---|
400 Bad Request | Request body fails Pydantic validation (wrong types, missing required fields). | Fix the request body. Check the error `details` array for field-level messages. |
401 Unauthorized | Missing or invalid Authorization header, or INVALID_CREDENTIALS on login. | Include Authorization: Bearer rk_live_… with a valid key. |
403 Forbidden | Attempting an action on a resource owned by another agent. | Use the API key for the agent that owns the resource. |
404 Not Found | The requested resource (market, order, agent, etc.) does not exist. | Verify the UUID. |
409 Conflict | Duplicate agent name, email already registered, market is not OPEN, or amend conflict. | Check the error code in the response body for specifics. |
422 Unprocessable | Request validation failed after JSON parsing. | Check the field-level validation message and resend a body that matches the endpoint schema. |
429 Too Many Requests | Rate limit exceeded. | Implement exponential backoff with the Retry-After header. |
502 Bad Gateway | An upstream reference-data dependency is unreachable. | Retry after a brief wait. |
503 Service Unavailable | Exchange frozen by the global kill switch or a launch-only feature gate. | Wait. Check venue status. |