Guides / API Guide
Rate limits are per-day and per-key. Free keys get a small daily allowance; paid plans
raise it substantially, and the exact ceiling for your plan is reported as
dailyLimit on your dashboard alongside requests used
this month and how many were rate-limited. Check that number rather than assuming one.
Most accounts that hit a limit are not pulling too much data — they are making too many requests for the same data. In rough order of impact:
| Pattern | Fix |
|---|---|
| Re-fetching the category or market list every run | Cache it; it changes slowly |
| One request per timestamp | Pull the range once, index locally |
| Narrow windows in a loop (per-minute, per-hour) | One wide range plus pagination_key |
| Re-downloading history you already have | Persist it; settled markets never change |
| Polling for updates on a fixed timer | Use webhooks where available |
A day of 1m snapshots is ~1,440 rows — two requests at
limit=1000. Fetching it hour by hour is 24 requests for the same rows, and risks
gaps at every seam. Always prefer the widest range you need with proper cursor paging.
import time, random
def get_with_retry(path, attempts=5, **params):
for i in range(attempts):
res = session.get(f"{BASE}{path}", params=params)
if res.status_code != 429:
res.raise_for_status()
return res.json()
# Exponential backoff with jitter — a fixed sleep re-synchronizes
# parallel workers into the same retry spike.
time.sleep(min(2 ** i, 30) + random.random())
raise RuntimeError("rate limited after retries")
Honor Retry-After when present, and cap concurrency: parallel workers share
one key's budget, so eight threads exhaust it eight times faster.
Data from Kalshi and Polymarket. Search live API docs Pricing