How quotas work
Every API key has a daily quota that resets at midnight UTC. Every
request to /api/v1/* (and the MCP server) counts as one.
| Tier | Daily quota |
|---|
trial | 50 requests/day |
pro | 500 requests/day |
admin | Unlimited |
MCP requests count against the same quota as REST API requests. There’s no
separate MCP allowance.
Every response includes three headers:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 2026-04-15T00:00:00+00:00
| Header | Meaning |
|---|
X-RateLimit-Limit | Your daily quota |
X-RateLimit-Remaining | Requests left until reset |
X-RateLimit-Reset | When the counter resets (ISO 8601, UTC) |
The rate_limit field in the response body contains the same information:
{
"data": { "..." },
"meta": {
"rate_limit": {
"limit": 500,
"remaining": 487,
"reset": "2026-04-15T00:00:00+00:00"
}
}
}
Handling 429 responses
When you exceed your quota:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-04-15T00:00:00+00:00
Content-Type: application/json
{
"error": "rate_limit_exceeded",
"message": "Daily limit of 500 reached."
}
Recommended handling
import time
from datetime import datetime, timezone
def call_with_retry(fn, max_retries=3):
for attempt in range(max_retries):
resp = fn()
if resp.status_code != 429:
return resp
reset = resp.headers.get("X-RateLimit-Reset")
if not reset:
time.sleep(60)
continue
reset_ts = datetime.fromisoformat(reset).timestamp()
wait = max(0, reset_ts - time.time())
# Don't wait more than an hour — surface the error instead
if wait > 3600:
raise RuntimeError(f"Rate limited until {reset}")
time.sleep(wait + 1)
raise RuntimeError("Max retries exceeded")
Planning your quota
The underlying GEX data updates every 15 minutes (Lambda capture). Polling
more often than that doesn’t yield new data. A typical trading bot pattern:
term-oi for BTC + ETH every 15 min = 2 × 4 = 8 req/hour
by-strike-enhanced for 2-3 expirations every 15 min = ~10 req/hour
- Discovery endpoints (rare, cached locally) = 1-2 req/day
Total: ~430 req/day for a busy bot — comfortably within the 500/day Pro quota.
Running out of quota?
- Cache responses locally. The data only changes every 15 min.
- Use the virtual
all exchange instead of calling each exchange separately.
- Reduce polling frequency to once every 30 min if you don’t need sub-15-min latency.
- Contact us at admin@gammaflip.io if you need a higher custom limit.