statshawk
Getting started

Quotas

Plan tiers, monthly unit allowances, and what happens when you exceed.

Units

Every API request that reaches a data endpoint costs at least 1 unit, and heavier endpoints cost more: see the weights table below. Quota resets at the start of each billing period.

Health and readiness checks (/healthz, /readyz) are free and never counted.

Odds: discovery 1× · spot board 5× · history page 10×. See the table and Odds history pages below.

Plans

PlanPrice / moUnits / moAt the cap
Free$05,000hard stop
Hobby$3025,000hard stop
Pro$100100,000hard stop
Scale$5001,000,000hard stop
Growth$1,5005,000,000hard stop
EnterpriseCustom10,000,000 baseline, contract-sizedCustom

All paid plans have access to all competitions and all endpoints, including /v1/analysis/*. The free tier covers every endpoint except /v1/analysis/*, which returns 403 TIER_REQUIRES_PAID.

What 5,000 units actually buys you

Units are abstract: here's the translation in real calls. Pick the row that matches your workload.

WorkloadWeight per callWhat 5,000 units gives you
Raw lookups (person/team search, standings, contest detail, competitions, /v1/contests/{id}/odds/markets)≈ 5,000 lookups
Box scores, game logs, season stats, contest lists≈ 2,500 reads
Rosters and matchup boards≈ 1,600 pulls
Play-by-play (Statcast)≈ 1,000 games
Odds spot board (/v1/contests/{id}/odds or /v1/persons/{id}/odds: all markets, latest tick)≈ 1,000 boards
Odds history page (/v1/contests/{id}/odds/history or /v1/persons/{id}/odds/history: one market/entity, paged)10×≈ 500 pages
Analysis cards (/analysis/*)10×≈ 500 cards (paid tier)

The exact weight for each endpoint is published in the OpenAPI spec as x-statshawk-weight and shown on each REST reference page.

On a paid plan, 5,000 units covers about 500 analysis cards. Free accounts can use every non-analysis tool — including odds discovery, spot boards, and history — but cannot call analysis endpoints.

Odds history pages

GET /v1/contests/{id}/odds/history and GET /v1/persons/{id}/odds/history return one market/entity per request, newest-first. Cost is 10 units per page, not per tick: interval only changes how ticks are bucketed. Each extra page costs another 10 units.

History requires markets and/or measure. A request with neither is rejected. Person history without a contest also needs that filter plus a time window (default 24 hours).

ParamDefaultMaxMeaning
markets and/or measurerequiredScope the page to one market/entity
limit50100Rows per page. Accepted range is 1 to 100; 0 or anything above 100 is rejected with 400, not clamped
cursorPrefer this. Pass data.next_cursor back unchanged for the older page. Opaque token; tie-safe on raw pages, bucket-aligned on interval pages
beforeExclusive timestamp window, not a pager. Same-timestamp leftovers can be skipped
sinceInclusive lower bound on observed_at
intervalautoraw, 15m, 1h, or auto. auto coarsens for longer windows

Paging fields live on data (OddsHistoryPage), not on meta (ResponseMeta is only request_id, fetched_at, cache, version, optional source). When the tape is longer than one page, data.truncated is true and data.next_cursor is the token for ?cursor=. Treat the token as opaque: the current forms are raw|{observed_at}|{id} for raw pages and bucket|{start} for interval pages, and the wire format may change. data.next_before may also appear as a timestamp window; do not use it as the pager when next_cursor is present.

Discovery (/v1/contests/{id}/odds/markets) stays . The current spot board (/v1/contests/{id}/odds or /v1/persons/{id}/odds) is : all markets, latest tick, one entity. Odds stay Free-accessible; usage is the gate. Search pagination (limit / offset) is on Pagination.

Monitoring usage

Your current-period usage is visible on the Billing page. The response headers on metered customer endpoints also carry your real-time quota state. See Rate limits for the header names. (Unmetered routes, /v1/ingest/* and /v1/assets/*, carry no quota headers.)

Exceeding your quota

Hitting the monthly cap is a hard stop on every metered route for Free through Growth: further requests return 429 Too Many Requests with error.code: "QUOTA_EXCEEDED" until the period resets or you upgrade. The X-Account-Quota-Reset header carries the period-end timestamp. Enterprise cap handling is contract-defined.

There is no metered overage billing. You are never charged past your plan price.

Need more units? Upgrade from the Billing page, or compare allowances on Pricing. The new limit applies immediately.

See Errors for the full error shape and retry guidance.

On this page