Skip to main content
Errors use a stable envelope:
Keep request_id when contacting support; every response also carries the same value in an X-Request-Id header. Trading-rule rejections may also include order_id, client_order_id, rule_id, and structured details. Validation failures (400) can include per-field details. Each entry names the wire field that failed, using body for problems with the payload as a whole. Other request errors may report only a code and message:
Two environment-specific responses are worth handling explicitly. A 401 with a message naming the other host means the key and hostname belong to different environments; see Sandbox and test keys. A 403 with the error code sandbox_access_expired means the account’s sandbox window lapsed; a new challenge purchase restores it.

Trader Lockout

A voluntary Trader Lockout applies to API keys, bots, and copied trades as well as the trading terminal. Order attempts on a locked account return 422 with code account_trader_lockout_active and details.expiresAt, the unlock time as Unix milliseconds. Stop submitting orders until that time; neither the API nor Support can remove the lock early. Activation preserves existing positions, working orders, and accepted schedules. Their execution, including stop-loss and take-profit exits, continues normally. The lock rejects new orders, modifications, cancellations, and manually submitted close orders until expiry. Positions remain exposed to losses and normal liquidation rules. Trading becomes available automatically at expiry.

Request budgets

Each API host allows about 300 requests per minute from one source IP address. The live and sandbox hosts count separately, and each Cloudflare location counts on its own, so treat the figure as approximate. A request over the limit returns 429 with a Retry-After header before it reaches the API. If the limit cannot be checked, the request is refused with 503 and a Retry-After header rather than let through; retry it after the delay. The limit is per address, not per API key. Several keys or bots sharing one address share its allowance. Do not build a continuous terminal by polling account, position, order, and quote endpoints every second. See API capabilities and the endpoint reference when choosing how to reconcile state. Orders also pass your account’s trading rules, which may limit how many trades you can place per minute, hour, or day. A rejected order returns 422 with the rule that applied. A reduce-only order, such as a take profit or stop loss, is never rejected by these limits when it triggers, but it still counts toward them. Account-wide cancel and close operations also share separate global budgets:
  • Empty operation snapshots: 60/minute, burst 12.
  • Planned work: 600 units/minute, burst 600. Each cancellation target reserves one unit; each close target reserves two.
  • Advancing work: 600 units/minute, burst 50. A cancel slice consumes one unit per target (up to five); a close slice consumes two units.
Completed bulk-operation replays skip those bulk budgets but still count toward the per-address request limit. A capacity rejection returns 429; wait for Retry-After and resume with the same idempotency key. Use exponential backoff with jitter for 429, 500, and 503. Reuse the same idempotency key when retrying a create or close request after an ambiguous network or server failure.