Rate Limits

Rate limits protect the platform from abuse and ensure fair access for all users. Limits are enforced per-IP for unauthenticated requests and per-API-key for authenticated requests.

API Key Tiers

Each API key is assigned a rate limit tier that governs the overall request throughput:

TierLimitDescription
standard10 req/sDefault for new keys
premium50 req/sPremium integrations
market_maker100 req/sHigh-frequency market makers

Administrators can also set per-key custom overrides via the rate_limit_override field. Custom overrides take precedence over the tier default. The override is a JSON object:

{ "requests": 200, "window_seconds": 1 }

Per-Endpoint Limits

Individual endpoints have their own rate limits. These per-endpoint limits apply to anonymous (per-IP) and session traffic. For HMAC API-key traffic the tier limit replaces the per-endpoint default on every endpoint - a market_maker key gets its 100 req/s ceiling on each endpoint it calls (per endpoint, per key; the tier is not an aggregate account budget).

Public Endpoints

MethodEndpointLimitWindow
GET/v1/markets100 req1 min
GET/v1/markets/:id200 req1 min
AllAll other unlisted endpoints30 req1 min

Authentication Endpoints

MethodEndpointLimitWindow
POST/v1/auth/privy10 req1 min
POST/v1/auth/callback10 req1 min
GET/v1/auth/oauth/:provider10 req1 min
POST/v1/auth/refresh5 req1 min
POST/v1/auth/revoke10 req1 min
POST/v1/auth/revoke-all5 req1 min
GET/v1/wallets/link/nonce10 req1 min
POST/v1/wallets/link10 req1 min

Fiat Endpoints

MethodEndpointLimitWindow
POST/v1/user/fiat/offramp/sessions5 req1 min
POST/v1/user/fiat/onramp/sessions10 req1 min
POST/v1/user/fiat/onramp/sessions/:id/complete20 req1 min

Trading Endpoints

MethodEndpointLimitWindow
POST/v1/orders10 req1 sec
DELETE/v1/orders/:hash20 req1 sec
GET/v1/orders/:hash20 req1 sec
POST/v1/orders/cancel-replace10 req1 sec
PUT/v1/orders/:hash/amend10 req1 sec

Market makers: the 10/s in this table is the anonymous/session default. An API key's tier limit replaces it - a market_maker key gets 100/s on single-order POST /v1/orders (and 100/s on each other endpoint, per endpoint). POST /v1/orders/batch (up to 15 orders per call) still multiplies placement throughput per request and is the recommended way to quote.

Batch Trading Endpoints

MethodEndpointLimitWindow
POST/v1/orders/batch5 req1 sec
DELETE/v1/orders/batch5 req1 sec
DELETE/v1/orders/cancel-all2 req1 sec
DELETE/v1/orders/cancel-market2 req1 sec
POST/v1/orders/heartbeat1 req1 sec

Deployment Endpoints

MethodEndpointLimitWindow
POST/v1/markets/:id/deploy20 req1 min

Admin Endpoints

MethodEndpointLimitWindow
POST/admin/markets10 req1 min
POST/admin/markets/:id/resolve5 req1 min

Response Headers

Responses evaluated by the API rate limiter include its exact decision and configured policy:

HeaderDescription
X-RateLimit-Decisionallowed, quota_denied, or dependency_unavailable
X-RateLimit-LimitMaximum requests per configured window
X-RateLimit-Window-SecondsConfigured window length in seconds
X-RateLimit-RemainingAuthoritative requests remaining; omitted when the Redis authority is down
X-RateLimit-ResetUnix timestamp when the current window resets; omitted when authority is down

Exceeded Limits

When you exhaust your rate limit, the API returns 429 Too Many Requests with X-RateLimit-Decision: quota_denied:

{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMITED"
}

Back off and retry after the X-RateLimit-Reset timestamp.

RATE_LIMIT_DEPENDENCY_UNAVAILABLE

If Redis cannot authoritatively read the counter, production fails closed with the same HTTP status but a distinct decision:

{
  "error": "Rate limit authority is temporarily unavailable",
  "code": "RATE_LIMIT_DEPENDENCY_UNAVAILABLE"
}

That response has X-RateLimit-Decision: dependency_unavailable and a short Retry-After, but deliberately omits X-RateLimit-Remaining and X-RateLimit-Reset. It is an infrastructure retry, not evidence that your quota is exhausted and not a reason to upgrade a plan or key tier.

Best Practices

  • Use batch endpoints to reduce request count (up to 15 orders per batch - see /api/v1/batch-operations)
  • Cache market data locally and use WebSocket for real-time updates
  • Monitor the decision - distinguish quota_denied from dependency_unavailable; only the former proves an exhausted counter
  • Monitor headers - check X-RateLimit-Remaining on authoritative allowed/quota_denied responses to avoid hitting limits
  • Use cancel-all instead of individual cancels when unwinding positions
  • Upgrade your tier - contact support if you need higher limits
  • Use heartbeat wisely - the 1 req/s heartbeat limit is intentional; send exactly one per second