How-to

Budget your requests

20,000 a month is about 28 an hour. Here is the arithmetic, not a reassurance.

Your monthly allowance is 20,000 requests across roughly 720 hours — about 28 requests an hour, for everything. Design against that number; you will almost never reach the per-second rate limit.

The one fact that decides your budget

Fixtures and odds move at completely different speeds. Measured over a recent 7-day window of production data:

EndpointWrites per hour
/v1/cs2/matches~6
/v1/cs2/odds~665

That's roughly 110×. Polling both on the same timer spends most of your allowance re-reading a fixture list that hasn't changed.

Two 30-day plans

StrategyRequests/monthShare of plan
Both endpoints every 5 minutes17,28086%
Odds every 5 minutes, fixtures hourly9,36047%

Same odds freshness, a bit over half the cost. And note what the first row means honestly: a 5-minute poll on both consumes most of the plan before you make a single detail call.

Work out your own number

requests/month = (60 / minutes_between_polls) × 24 × 30 × endpoints_polled

Some anchors:

IntervalRequests/month (one endpoint)
Every minute43,200 — over budget on its own
Every 5 minutes8,640
Every 15 minutes2,880
Hourly720
Daily30

Spending less

Open a WebSocket instead of polling for changes. One ticket mint is one request; the connection then pushes score and odds changes for as long as it stays open at no further request cost. For anything change-driven this is strictly cheaper than a timer — see connect a WebSocket.

Poll fixtures slowly. Hourly is ample at ~6 writes/hour; for many uses a daily schedule refresh is fine.

Filter server-side. ?status=live, ?date_from=/?date_to=, ?tournament= cost the same one request as an unfiltered call and save you paging through rows you'd discard.

Ask for detail only where it exists. ?has=rounds,depth filters the list to matches that actually have those sub-resources, so you never spend a request discovering there was nothing.

Raise limit. Walking 1,000 teams at limit=100 is 10 requests; at limit=500 it's 2.

Expand instead of following links. ?include=teams,tournament,odds turns four requests into one — see fetching a full match.

Know where you stand

Every response carries your position, so you never have to count client-side:

curl -sS -D - -o /dev/null -H "Authorization: Bearer $ESPORTSODDS_API_KEY" \
  "https://api.esportsodds.gg/v1/cs2/matches?limit=1" | grep -i x-quota

X-Quota-Remaining is the number to alarm on. Wire it into your own monitoring at, say, 20% — the dashboard also emails at 80% and 100% if you leave those notifications on.

During a trial the allowance is 1,000, counted from when the trial started rather than by calendar month. That's sized for evaluating the API, not for bulk-loading history.

On this page