Plans and limits

What each plan allows, how usage is counted and what a limit looks like.

Every key belongs to a plan. A plan sets how many requests you can make a minute, how many objects you can receive a month, which bookmakers and leagues your responses include, and whether you can read recorded history.

PlanRequests a minuteObjects a monthBookmakersLeaguesHistory
Developer (free)102,500Sportsbet, TAB and LadbrokesMLB, NFL, AFL, NRL, Rugby League World Cup and Rugby League World Cup Women'sNo
Rookie50100,000Sportsbet, TAB, Ladbrokes, Neds, PointsBet, Unibet, Betfair Exchange, Dabble and BetrAll deliveredNo
Pro300No monthly capAll deliveredAll deliveredYes

Bookmakers are those delivering prices as of 12 October 2026. Plans also include bet365, which is not delivering yet. Prices and billing are on the pricing page.

How objects are counted

Each record in data counts as one object, and every bookmaker price inside it counts as one more. One event with three bookmakers each quoting a two-way market is 1 + 3 × 2 = 7 objects. Catalogue lists (sports, leagues, bookmakers, markets, teams, players) count one object per record. Ask for only the markets and bookmakers you use (markets=, bookmakers=, limit=) to make your allowance go further.

What happens at a limit

  • Requests a minute. The request after your limit gets 429 with the title "Rate limit reached" and a Retry-After header in seconds. Wait that long, then retry.
  • Objects a month. Once the month's allowance is used, requests get 429 with the title "Monthly allowance reached" until the next calendar month (UTC), or until you change plan.
  • Leagues. A request naming a league outside your plan gets 403 with the title "Plan restriction".
  • Bookmakers. Bookmakers outside your plan are left out of responses rather than refused, so a filter for one returns no prices for it.
  • History and streaming. Recorded history, opening and closing snapshots and the odds stream need Pro; other plans get 403.

A Developer key asking for a league outside the free plan:

curl -sS "https://api.sockodds.com/v1/odds?league=epl&limit=1" \
  -H "Authorization: Bearer $SOCKODDS_API_KEY"
const response = await fetch("https://api.sockodds.com/v1/odds?league=epl&limit=1", {
  headers: { Authorization: `Bearer ${process.env.SOCKODDS_API_KEY}` },
});
console.log(JSON.stringify(await response.json(), null, 2));
import json, os, urllib.error, urllib.request

request = urllib.request.Request(
    "https://api.sockodds.com/v1/odds?league=epl&limit=1",
    headers={"Authorization": "Bearer " + os.environ["SOCKODDS_API_KEY"]},
)
try:
    with urllib.request.urlopen(request) as response:
        print(json.dumps(json.load(response), indent=2))
except urllib.error.HTTPError as error:
    print(json.dumps(json.load(error), indent=2))

Response from a local copy of the API with invented test prices

{
  "type": "https://api.sockodds.com/problems/403",
  "title": "Plan restriction",
  "status": 403,
  "detail": "This league is not in your plan.",
  "instance": "/v1/odds?league=epl&limit=1"
}

Error responses follow Errors.

Need help?FAQ · Email support

Search across the SockOdds documentation and catalogue.