Skip to content
datasportsAPI

Get startedPlans, quota & rate limits

Documentation

/

Type to filter the docs by title or path.

Getting started · Plans, quota & rate limits

How much, how fast, how far back

Each plan is three numbers: a request quota, a per-minute rate and a history window. Here is how each one is measured, what the response headers tell you, and exactly what happens when you reach an edge.

Per account, not per keyUTC calendar
01

The plans side by side

PlanPrice / monthQuotaRequests / minHistoryKeysWebSocketPremium endpoints
Free$01,000 requests / day10Last 7 days1 API keyNot includedNot included
Starter$49250,000 requests / month120Last 30 days2 API keysNot includedNot included
Pro$1991,000,000 requests / month600Last 6 months5 API keysNot includedYes
Business$99910,000,000 requests / month6,000Full historyUnlimited API keysFull + replayYes
02

Two limits, counted separately

Both apply to every authenticated /v2 call and both belong to the account: all of its keys draw from the same two pools.

The quota

How many, per period

  • Paid plans count by UTC calendar month; Free counts by UTC day.
  • Reported on every response in three RateLimit headers.
  • Once it is used up: 429quota_exceeded, and Retry-After tells you how many seconds remain until the reset.

The rate

How many, per minute

  • Fixed one-minute windows that protect against bursts.
  • No headers of its own — you only notice it when you cross it.
  • When you cross it: 429rate_limited, with Retry-After pointing at the next minute. Not counted against the quota.
03

The quota and its headers

On Starter, Pro and Business the quota covers a UTC calendar month and resets on the 1st at 00:00 UTC. On Free it covers a UTC day and resets each night at 00:00 UTC. It is not a rolling window: a request made at 23:59 UTC on the last day of the month still uses the old month's allowance.

Every response tells you where you stand, so a client can slow itself down long before it hits zero. When the quota is gone the API answers 429 quota_exceeded until the reset; the error message states which period ran out and when it resets, and Retry-After holds the seconds left. Retrying sooner only produces more 429s.

Response headers
HTTP/1.1 200 OK
Content-Type: application/json
RateLimit-Limit: 250000
RateLimit-Remaining: 187412
RateLimit-Reset: 1036800
HeaderHolds
RateLimit-LimitYour plan's quota for the current period.
RateLimit-RemainingRequests still available in this period.
RateLimit-ResetSeconds until the period ends and the quota refills.
04

The per-minute rate

The rate is a burst guard, counted in fixed windows that start on the minute. Each plan's figure is in the table above.

Requests counted inside each one-minute window
  • accepted
  • 429 rate_limited
  • your plan's limit
Fixed one-minute rate windowsIn the first minute requests stay under the limit. In the second minute the limit is reached after about twenty seconds and every further request that minute is refused with rate_limited. The count resets at the start of the third minute.

Minute 1
under the limit

Minute 2
limit hit · rest refused

Minute 3
count starts again

Crossing the rate returns 429 rate_limited. Retry-After gives the seconds until the next window opens, which is never more than a minute. These refusals are not charged to your quota, so waiting and retrying costs nothing.

The two 429s need opposite reactions — a short wait for one, a full stop for the other — so always read error.code rather than the status alone. The official SDKs already retry rate_limited for you.

Telling the two 429s apart
const API = "https://api.datasportsapi.com";
const headers = { Authorization: `Bearer ${process.env.DATASPORTSAPI_API_KEY}` };
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

export async function get(path: string, attempts = 3) {
  for (let i = 1; ; i++) {
    const res = await fetch(API + path, { headers });
    if (res.status !== 429) return res.json();

    const { error } = await res.json();
    // A spent quota will not come back for hours or days: stop and alert.
    if (error.code === "quota_exceeded" || i === attempts) throw new Error(error.message);

    // rate_limited: Retry-After points at the start of the next minute.
    await sleep(Number(res.headers.get("Retry-After") ?? 1) * 1000);
  }
}
05

How far back you can read

A plan's history window is measured back from the start of today in UTC. Upcoming and live data are never limited.

History window, counted back from 00:00 UTC today
  • Free7 days
  • Starter30 days
  • Pro6 months
  • BusinessFull history
← further backtoday · upcoming and live always open →

Anything that starts before the window is refused or trimmed, depending on what you asked for:

  • A single old record — a fixture that kicked off earlier, the day list for an earlier date, or a league season that is already over (its standings, rounds, top players and top teams, or team and player season statistics) — answers 403 history_not_in_plan.
  • A list that reaches back — a team's or player's fixtures, the fixtures of a round — leaves the older fixtures out and reports the cut-off in meta.historyFrom.

The refusal carries historyFrom, the first day your plan can read, so you can clamp a date picker to it. These refusals count against your quota like any other answered request.

403 Forbidden
{
  "error": {
    "code": "history_not_in_plan",
    "message": "this fixture is older than your plan's history",
    "historyFrom": "2026-11-03"
  }
}
06

What counts as a request

Requests are requests: no credits. Every plan has all 24 sports and the core match data.

Counts as one

  • Every answered /v2 call, whichever endpoint it hits.
  • Each stream ticket — POST /v2/stream/ticket is an ordinary call.
  • Every refresh of an embedded widget, in every visitor's browser.
  • Calls made through the SDKs and the dsa CLI.
  • Refusals for history_not_in_plan.

Never charged

07

Premium endpoints

30 endpoints — our win-probability model, AI commentary, betting odds and the deeper match and player analytics — are reserved for Pro and Business. On Free and Starter they answer 403 endpoint_not_in_plan, and that refusal costs nothing.