Budget your requests
Standard's 50,000 a month is about 69 an hour. Here is the arithmetic, not a reassurance.
On Standard your monthly allowance is 50,000 requests across roughly 720 hours, about 69 requests an hour, for everything. On Pro it is 150,000, about 208 an hour. Design against your own number; you will almost never reach the per-second rate limit. The shares on this page are of Standard's 50,000, so on Pro each one is a third as large.
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:
| Endpoint | Writes per hour |
|---|---|
/v1/cs2/matches | ~6 |
/v1/cs2/odds | ~665 |
That's roughly 110×. Polling both on the same timer spends half of every poll re-reading a fixture list that hasn't changed.
Two 30-day plans
| Strategy | Requests/month | Share of Standard |
|---|---|---|
| Both endpoints every 5 minutes | 17,280 | 35% |
| Odds every 5 minutes, fixtures hourly | 9,360 | 19% |
Same odds freshness, a bit over half the cost, and four-fifths of Standard's 50,000 left for detail calls. The timer that doesn't fit comfortably is a fast one. See the one-minute row below.
Work out your own number
requests/month = (60 / minutes_between_polls) × 24 × 30 × endpoints_polledSome anchors:
| Interval | Requests/month (one endpoint) |
|---|---|
| Every minute | 43,200, which is 86% of Standard's 50,000 on its own |
| Every 5 minutes | 8,640 |
| Every 15 minutes | 2,880 |
| Hourly | 720 |
| Daily | 30 |
Spending less
Open a WebSocket instead of polling for changes — it costs no quota at all. Not the ticket mint, not the connection, not a single frame pushed over it. Nothing about the WebSocket draws on your request allowance; a five-connection-per-key cap is what bounds it instead. For anything change-driven this is not merely cheaper than a timer, it is free — see connect a WebSocket. (Ticket mints do still draw on the per-second rate limit, so reuse a ticket for its full 60-second life rather than minting per reconnect.)
If you must poll, poll the change feed, not the list. ?changed_since=<rfc3339>&sort=changed_at
returns only matches that actually moved since you last looked. Page to the end, store the newest
changed_at you saw, and pass it back next time — overlapping your window by ten minutes and
de-duplicating on id. On a quiet hour that is one request returning an empty page instead of a
full fixture list you then diff yourself. To find out what changed and what it changed from,
follow up with match history on the handful of ids that moved.
Load the archive with /matches/bulk, not the list endpoint. Walking historical matches two
calls at a time is the single most expensive thing you can do with this API — one real key spent
6,788 requests in three days doing exactly that. /v1/{game}/matches/bulk returns many matches with
their sub-resources expanded in one request; see
backfilling history. It is the efficient path, so start with it
rather than finding it after a month of per-match calls. A Standard account that first subscribed on or after 30 October 2026 may make 250 bulk-export requests a month, so on that subscription keep the
bulk export for the archive pull and follow changes with the plain match list. Pro has no bulk cap.
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-quotaX-Quota-Remaining is the number to alarm on. Wire it into your own monitoring at, say, 20% — we
also email you when you pass 80% of the month's requests and again when you reach the limit, unless
you have switched those off in Settings.
Subscriptions no longer start with a trial. One that had already started keeps its own, smaller limits until it ends — see legacy trials.