Skip to main content

Base URL

https://api.oddsstream.io
All endpoints are under this base URL. No version prefix — the API is currently at v1.

Authentication

Every request requires an API key in the X-Api-Key header:
curl "https://api.oddsstream.io/api/odds" \
  -H "X-Api-Key: os_live_YOUR_KEY"
Keys are issued from your dashboard at oddsstream.io/dashboard/keys. Key format: os_live_<32-char-hex>.

Response Envelope

All successful responses follow this shape:
{
  "data": [...],
  "meta": {
    "count": 142,
    "rate_limit_remaining": 4987
  }
}
For single-object responses (e.g. GET /api/events/{id}), data is an object, not an array.

Error Format

{
  "error": {
    "code": "live_not_on_plan",
    "message": "Live odds require the Pro Live plan.",
    "upgrade_url": "https://oddsstream.io/pricing"
  }
}
HTTP StatusError CodeWhen
400bad_requestInvalid query parameter value
401unauthorizedMissing or invalid X-Api-Key
403live_not_on_planRequested is_live=true without Pro+ Live plan
403websocket_not_on_planRequested WS token without a plan that includes WebSocket
403bookmaker_not_configuredFree plan: no bookmaker selected in dashboard
403bookmaker_forbiddenFree plan: requesting a different bookmaker than selected
404not_foundEvent slug not found in active data
409key_limit_reachedAlready at the 5-key cap — revoke one first
429rate_limit_exceededToo many requests — see X-RateLimit-Remaining
500internal_errorServer error — safe to retry with backoff
503service_unavailableDatabase temporarily unavailable

Rate Limits

Limits are per API key:
PlanRate limitWebSocketLive endpoints
Free200 req/day30 connections/dayNo
Pro5,500 req/hrNot includedNo
Pro+ RT5,500 req/hrUnlimitedNo
Pro+ Live5,500 req/hrUnlimitedYes
Rate limit headers on every response:
X-RateLimit-Remaining: 187
X-RateLimit-Reset: 1745160060

Common Query Parameters

These filters are accepted on all list endpoints unless stated otherwise:
ParameterTypeDescription
sportstringFilter by sport name — case-insensitive (e.g. Football, Tennis, Basketball)
competitionstringFilter by competition code — exact, uppercase (e.g. EPL, NBA, LIG1)
bookmakerstringFilter by bookmaker name — exact, case-sensitive (e.g. Winamax, Betclic)
limitintegerMax results returned. Each endpoint has its own cap.

Competition Codes

Competition codes are short uppercase identifiers used across all endpoints. They are stable — they don’t change with bookmaker translations. Examples:
CodeCompetitionSport
EPLEnglish Premier LeagueFootball
LIG1Ligue 1Football
BUNDBundesligaFootball
SERASerie AFootball
LIGALa LigaFootball
UCLUEFA Champions LeagueFootball
NBANBABasketball
NFLNFLAmericanFootball
NHLNHLHockey
MLBMLBBaseball
ATPATP TourTennis
WTAWTA TourTennis
EFLEnglish Football LeagueFootball
EREDEredivisieFootball
MLSMLSFootball
Use GET /api/sports to discover all active competition codes at runtime.

Market Types

market_typeDescriptionSports
moneylineWin/Draw/Win (1X2) or Head-to-HeadAll
spreadAsian Handicap / Points SpreadFootball, Basketball, Hockey
totalOver/Under totalsAll
bttsBoth Teams to Score (Yes/No)Football
double_chanceDouble Chance (1X, X2, 12)Football
draw_no_betDraw No Bet (Home/Away)Football
3way_handicapEuropean Handicap (3-way)Football
total_gamesTotal Games Over/UnderTennis
games_handicapGames HandicapTennis
team_totalPer-team total (Home/Away Over/Under)Football, Basketball
player_propPlayer performance propsBasketball, Hockey, Baseball
yes_noBinary Yes/No marketsVarious

Period Values

The period field on every odds row indicates which portion of the match the market covers:
periodFootballBasketballHockeyTennis
0Full timeFull gameFull gameMatch
11st Half1st Quarter1st Period1st Set
22nd Half2nd Quarter2nd Period2nd Set
33rd Quarter3rd Period3rd Set
Full-time (period: 0) markets dominate. Half-time and quarter markets are available for most sports.