Documentation · Rate limits

Rate limits

Per-key limits for REST and WebSocket, the usage headers on every response, and what happens when you hit a limit.


The numbers

LimitFoundingType
Sustained rate (REST)2 req/secHard
Burst (REST)10 req/sec for 60s rollingHard
Monthly quota250,000 requestsSoft
Concurrent WS connections3 per keyHard
WS subscriptions per connection500 marketsSoft
Historical depthEvery event since coverage began · growing weeklyHard
Export endpoint10,000 rows/call, 50 exports/daySoft
Concurrent in-flight HTTP10Soft

For context: a client polling /v1/eventsevery 15 seconds uses about 175,000 calls a month (comfortably inside the quota), and if you're on the WebSocket, you don't need to poll at all. If your use case genuinely needs more, talk to us.

Soft vs hardSoft limits surface a 429 with Retry-After and a warning email at 80% utilisation. Hard limits return 429 immediately and stay in 429 until the window resets. Founding-tier limits are an early-access benefit for our first group of customers.

Headers on every response

Every REST response carries the current quota state. Your client can back off without parsing the body.

httphttp
HTTP/1.1 200 OK
Content-Type: application/json
X-Vera-Tier:               founding
X-Vera-Quota-Limit:        250000
X-Vera-Quota-Remaining:    231047
X-Vera-Quota-Reset:        2026-07-01T00:00:00Z
X-Vera-Rate-Limit:         2
X-Vera-Rate-Remaining:     1
X-Vera-Burst-Remaining:    8
X-Vera-Burst-Reset:        2026-06-10T20:14:18Z

What 429 looks like

httphttp
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  0: {
    1: 2,
    3: 4,
    5: 6,
    7: 8,
    9: 10
  }
}

Backoff strategy

Always honour Retry-After. If it's missing (it shouldn't be, but just in case), back off with exponential jitter starting at 1 second. The reference clients in Quickstart already implement this pattern.

pythonpython
import time, random, httpx

def get_with_backoff(client: httpx.Client, url: str, params: dict | None = None):
    for attempt in range(5):
        resp = client.get(url, params=params)
        if resp.status_code != 429:
            return resp
        retry_after = int(resp.headers.get(0, 0))
        if retry_after > 0:
            time.sleep(retry_after)
        else:
            time.sleep((2 ** attempt) + random.random())
    resp.raise_for_status()

Warning emails

We email the subscription owner (and any team members on a future team plan) at these milestones:

  • 80% of monthly quota consumed
  • 100% of monthly quota consumed (we'll reach out before anything throttles)
  • 3+ rate-limit responses within 60 seconds (suggests a misconfigured client)

Asking for more

Need higher caps than Founding? Email vera@cryptobriefing.com with what you're building. The next tier above Founding is in design; we'll add you to the early-access list and quote you against the actual numbers you need.

Kalshi coverage

Kalshi is on the roadmap for a forthcoming Multi-Venue tier, not the Founding tier. Founding subscribers will be offered an upgrade path at their locked founding rate when Multi-Venue ships.