DocsGetting StartedRate Limits

Rate Limits

Throttling with standard headers, so your integration can self-regulate.

Limits

API access requires the Quant plan
The API is included with the Quant plan - it is the only plan with API access. Without an active subscription, requests return 403 plan_restricted.
EndpointsRequests / min
Default (wheels, journal, earnings, alerts)120
Screener, optimal roll, playground orders, GEX history30
GEX heatmap, AI explanations10

All endpoints share a single 60-second sliding window per API key - every v1 request counts toward the same budget. The numbers above are the thresholds each endpoint checks against that shared window: a heatmap call is rejected when your key has made 10+ requests (to any endpoint) in the last 60 seconds, even if none of them were heatmap calls. Heavy endpoints compute live options chains, which is why they get tighter thresholds.

Ordering matters for tight endpoints
If your workflow mixes chatty endpoints with tight ones (heatmap, AI), call the tight ones first - once the shared window holds 10+ requests, they 429 until traffic ages out.

Rate limit headers

Responses carry your current budget.

response headers
HTTP/2 200
x-ratelimit-limit: 120
x-ratelimit-remaining: 87

Handling 429s

A throttled request returns 429 with a Retry-After header and retry_after_seconds in the body. Respect it - retrying earlier just burns budget.

429 Too Many Requests
{
  "error": "Rate limit exceeded (120 requests/min). Retry in 12s.",
  "code": "rate_limited",
  "retry_after_seconds": 12,
  "contact": "hello@quantwheel.com"
}
retry.py
import time, requests

def qw_get(url, **kwargs):
    for attempt in range(5):
        resp = requests.get(url, **kwargs)
        if resp.status_code != 429:
            return resp
        # Server tells you exactly how long to wait
        time.sleep(int(resp.headers.get("Retry-After", 2 ** attempt)))
    resp.raise_for_status()
Polling exposure data?
Live GEX responses are cached ~60 seconds server-side, and stored snapshots update every ~5 minutes for SPY/SPX/QQQ (about every 30 minutes for other names). Polling faster returns the same data and wastes your quota.