Odds API: Getting Started Guide
The Complete Guide
What you'll learn: How to authenticate with the OpticOdds API, discover available sports and markets, pull fixture data, retrieve real-time odds, stream live updates, monitor results, grade bets, and work with futures and player props. This guide covers every core (non-Copilot) endpoint in the OpticOdds v3 API.
What Is the OpticOdds API?
The OpticOdds API is a real-time sports odds aggregation platform that gives you access to odds from 100+ sportsbooks across 25+ sports — all through a single, unified API. Whether you're building a consumer-facing odds comparison tool, powering a trading desk, or feeding models for quantitative analysis, the API provides everything you need: fixtures, odds snapshots, live streaming, results, bet grading, futures, injuries, and more.
In plain terms: You query a single API and get back normalized odds from dozens of sportsbooks — in real time. No need to build and maintain individual integrations with each book.
What the API Gives You
- Multi-sportsbook odds — Pull odds from up to 5 sportsbooks per request, across 100+ supported books
- 25+ sports — Baseball, basketball, football, soccer, hockey, tennis, MMA, golf, and many more
- Real-time streaming — SSE-based live odds and results streaming
- Deep linking — Direct links into sportsbook apps (where available)
- Bet grading — Automatic settlement (Won, Lost, Refunded, Half Won, Half Lost)
- Futures markets — Season-long and tournament futures odds
- Injuries data — Player injury reports filtered by sport, league, and team
- Historical odds — Full price history with every movement tracked
- Player props — Comprehensive player-level markets and results
- Starting lineups — Pre-game lineup data for supported leagues
- Limits data — Max stake information where available
How the API Works — The Big Picture
Here's the typical integration workflow:
1. Authenticate → Use your API key via header or query param
2. Discover Resources → Get available sports, leagues, sportsbooks, and markets
3. Pull Active Fixtures → Find upcoming and live games with odds
4. Get Odds Snapshot → Pull current odds for specific fixtures + sportsbooks
5. Stream Live Updates → Listen for real-time odds changes via SSE
6. Monitor Results → Stream live scores and game status changes
7. Grade Bets → Settle bets using the grader endpoint
Step 1: Authentication
All API requests use your OpticOdds API license key. You can authenticate in two ways:
Option A: Header (recommended)
curl --location 'https://api.opticodds.com/api/v3/sports' \
--header 'X-Api-Key: YOUR_API_KEY'Option B: Query Parameter
curl 'https://api.opticodds.com/api/v3/sports?key=YOUR_API_KEY'Base URL:
https://api.opticodds.com/api/v3
Rate Limits
| Tier | Limit |
|---|---|
| Standard endpoints | 2,500 requests / 15 seconds |
| Streaming endpoints | 250 requests / 15 seconds |
| Historical endpoints | 10 requests / 15 seconds |
Step 2: Discover Your Resources
Before pulling odds, you need to know what's available. The API provides four discovery endpoints that return the full catalog of supported resources.
/sports — Get All Sports
/sports — Get All SportsReturns every sport OpticOdds supports, along with each sport's main markets.
GET https://api.opticodds.com/api/v3/sportsExample Response:
{
"data": [
{
"id": "baseball",
"name": "Baseball",
"main_markets": [
{ "id": "moneyline", "name": "Moneyline", "numerical_id": 953 },
{ "id": "run_line", "name": "Run Line", "numerical_id": 1245 },
{ "id": "total_runs", "name": "Total Runs", "numerical_id": 1367 }
]
},
{
"id": "basketball",
"name": "Basketball",
"main_markets": [
{ "id": "moneyline", "name": "Moneyline", "numerical_id": 953 },
{ "id": "point_spread", "name": "Point Spread", "numerical_id": 1172 },
{ "id": "total_points", "name": "Total Points", "numerical_id": 1358 }
]
}
]
}Currently supported sports include: Baseball, Basketball, Boxing, Cricket, Darts, eSports, Football (American), Golf, Hockey, Lacrosse, MMA, Motorsports, Rugby League, Rugby Union, Soccer, Table Tennis, Tennis, Volleyball, and more.
/leagues — Get All Leagues
/leagues — Get All LeaguesReturns all leagues for a given sport, including region and gender information.
GET https://api.opticodds.com/api/v3/leagues?sport=basketballKey fields in response:
id— League identifier (e.g.,nba,ncaab,euroleague)sport— Parent sport objectregion— Geographic region (e.g.,UNITED_STATES,INTERNATIONAL)region_code— ISO region code (e.g.,USA,INT)gender—menorwomen
Example leagues for basketball: NBA, NCAAB, NCAAW, WNBA, Euroleague, Eurocup, NBA Summer League, and many international leagues.
/sportsbooks — Get All Sportsbooks
/sportsbooks — Get All SportsbooksReturns every sportsbook OpticOdds has tracked, with active status and classification.
GET https://api.opticodds.com/api/v3/sportsbooksKey fields in response:
id— Sportsbook identifier (e.g.,draftkings,betmgm)name— Display namelogo— URL to sportsbook logois_onshore— Whether the book is a licensed US/regulated sportsbookis_active— Whether the sportsbook is currently being tracked
Major active sportsbooks include: bet365, BetMGM, BetRivers, Betsson, Betway, Bovada, bwin, Caesars, DraftKings, ESPN BET, Fanatics, BetMGM, Hard Rock, Novig, Betano, PrizePicks, Unibet, and 100+ more.
/markets — Get All Markets
/markets — Get All MarketsReturns all available markets, filterable by sport, league, and sportsbook. This tells you exactly which prop and game-level markets are available and where.
GET https://api.opticodds.com/api/v3/markets?sport=footballKey fields in response:
id— Market identifier (e.g.,moneyline,player_passing_yards)name— Display namenumerical_id— Numeric identifiersports→leagues→sportsbooks— Nested hierarchy showing exactly which books offer this market in each league
Optional Parameters:
| Parameter | Description |
|---|---|
sport | Filter by sport |
league | Filter by league |
sportsbook | Filter by sportsbook |
markets_only | Set to true to return just market names without the nested hierarchy |
Tip: Use
/markets?sport=basketball&league=nba&markets_only=trueto quickly see all available NBA markets.
/markets/active — Get Currently Active Markets
/markets/active — Get Currently Active MarketsReturns only the markets that currently have live odds available.
GET https://api.opticodds.com/api/v3/markets/active?sport=basketball&league=nbaStep 3: Pull Active Fixtures
Once you know which sports and leagues you want, the next step is pulling fixtures (games).
/fixtures/active — Get Fixtures with Odds
/fixtures/active — Get Fixtures with OddsReturns all fixtures that are currently active (not completed) and have or have had odds associated with them. This is the recommended starting point for most integrations.
GET https://api.opticodds.com/api/v3/fixtures/active?sport=football&league=nflKey difference from
/fixtures: The/fixtures/activeendpoint only returns fixtures that have ever had odds. The/fixturesendpoint returns all fixtures including those that may never have had odds (e.g., far-future scheduled games).
/fixtures — Get All Fixtures
/fixtures — Get All FixturesReturns a paginated list of all fixtures. Supports historical lookback and future scheduling.
GET https://api.opticodds.com/api/v3/fixtures?league=nfl&start_date=2025-01-15Important: You must pass at least one of: sport, league, id, or team_id.
Key Parameters:
| Parameter | Description |
|---|---|
sport | Sport ID or name |
league | League ID or name |
id | Specific fixture ID(s) |
team_id | Filter by team |
start_date | Fixtures on this date (ISO 8601: YYYY-MM-DDTHH:MM:SSZ) |
start_date_after | Fixtures after this date |
start_date_before | Fixtures before this date |
status | Filter by status (unplayed, live, completed, cancelled) |
is_live | Set to true for only live games |
include_starting_lineups | Set to true to include lineup data |
include_statsperform_id | Include StatsPerform IDs in source_ids |
season_year | Filter by season year |
season_week | Filter by season week |
season_type | Filter by season type (e.g., Regular Season, Playoffs) |
page | Page number for pagination |
Date default: If you don't pass any date parameters, this endpoint defaults to fixtures from 3 days ago.
Example Response (NFL):
{
"data": [
{
"id": "2025020987944BC9",
"numerical_id": 142834,
"game_id": "13602-17233-25-05",
"start_date": "2025-02-09T23:30:00Z",
"home_competitors": [
{
"id": "EDCC2866B795",
"name": "Philadelphia Eagles",
"abbreviation": "PHI",
"logo": "https://cdn.opticodds.com/team-logos/football/106.png"
}
],
"away_competitors": [
{
"id": "2D71E5BA64A5",
"name": "Kansas City Chiefs",
"abbreviation": "KC",
"logo": "https://cdn.opticodds.com/team-logos/football/96.png"
}
],
"status": "unplayed",
"is_live": false,
"sport": { "id": "football", "name": "Football" },
"league": { "id": "nfl", "name": "NFL" },
"has_odds": true,
"venue_name": "Caesars Superdome",
"venue_location": "New Orleans, LA, USA",
"venue_neutral": true,
"broadcast": "FOX | FOXD | TELE | TUBI",
"result": null,
"season_type": "Playoffs",
"season_year": "2024",
"season_week": "22"
}
],
"page": 1,
"total_pages": 1
}Key fields:
id— Unique fixture identifier (use this for odds requests)game_id— Internal game referencehome_competitors/away_competitors— Team details with logosstatus—unplayed,live,completed,cancelledis_live— Boolean for live gameshas_odds— Whether odds exist for this fixtureresult— Score data (populated when game has started)venue_name/venue_location/venue_neutral— Venue infohome_rotation_number/away_rotation_number— Rotation numbershome_starter— Starting pitcher (baseball)lineups— Starting lineups (wheninclude_starting_lineups=true)
/fixtures/tournaments — Get Tournament Fixtures
/fixtures/tournaments — Get Tournament FixturesFor tournament-style competitions (e.g., golf, tennis Grand Slams), use this endpoint to retrieve fixtures grouped by tournament.
Step 4: Get an Odds Snapshot
With your fixture IDs in hand, pull the current odds across your chosen sportsbooks.
/fixtures/odds — Get Current Odds
/fixtures/odds — Get Current OddsGET https://api.opticodds.com/api/v3/fixtures/odds?fixture_id=BCE4E01B8D3D&sportsbook=DraftKings&sportsbook=BetMGMRequired Parameters:
- At least one of:
fixture_id,team_id, orplayer_id - At least 1
sportsbook(max 5 per request)
Optional Parameters:
| Parameter | Description |
|---|---|
market | Filter by market (e.g., moneyline, point_spread) |
is_main | Filter for main lines only (true) or alternates only (false) |
odds_format | AMERICAN (default), DECIMAL, PROBABILITY, MALAY, HONG_KONG, INDONESIAN |
exclude_fees | Set to true to exclude fee adjustments |
Example Response:
{
"data": [
{
"id": "BCE4E01B8D3D",
"start_date": "2024-08-30T00:10:00Z",
"home_competitors": [
{ "id": "4F11A5896C24", "name": "Houston Astros", "abbreviation": "HOU" }
],
"away_competitors": [
{ "id": "E970E2EDDCAE", "name": "Kansas City Royals", "abbreviation": "KAN" }
],
"status": "unplayed",
"odds": [
{
"id": "60486-35183-2024-08-29-17:BetMGM:moneyline:houston_astros",
"sportsbook": "BetMGM",
"market": "Moneyline",
"name": "Houston Astros",
"is_main": true,
"selection": "Houston Astros",
"market_id": "moneyline",
"selection_line": null,
"player_id": null,
"team_id": "4F11A5896C24",
"price": -156,
"timestamp": 1724865905.59815,
"grouping_key": "default",
"points": null,
"deep_link": null,
"limits": { "max": 500 }
},
{
"id": "60486-35183-2024-08-29-17:BetMGM:moneyline:kansas_city_royals",
"sportsbook": "BetMGM",
"market": "Moneyline",
"name": "Kansas City Royals",
"is_main": true,
"price": 132,
"timestamp": 1724865905.59815,
"limits": { "max": 500 }
},
{
"id": "60486-35183-2024-08-29-17:BetMGM:run_line:houston_astros_-1_5",
"sportsbook": "BetMGM",
"market": "Run Line",
"name": "Houston Astros -1.5",
"is_main": true,
"price": 140,
"points": -1.5,
"grouping_key": "default:-1.5"
},
{
"id": "60486-35183-2024-08-29-17:BetMGM:total_runs:over_8",
"sportsbook": "BetMGM",
"market": "Total Runs",
"name": "Over 8",
"is_main": true,
"selection_line": "over",
"price": -110,
"points": 8,
"grouping_key": "default:8.0"
}
]
}
]
}Key fields on each odd:
id— Unique odd identifiersportsbook— Source sportsbookmarket/market_id— Market name and IDname— Full display name (e.g., "Houston Astros -1.5")is_main— Whether this is the primary lineprice— The odds value (format depends onodds_format)points— The spread or total value (null for moneyline)selection_line—over/underfor totalsplayer_id— Player ID for player propsteam_id— Team IDtimestamp— When this price was last updatedgrouping_key— Groups related odds together (e.g., Over/Under pairs)deep_link— Direct links into sportsbook apps (if enabled)limits— Max stake information (where available)
Best Practice: Sportsbook Redundancy Use a basket of sportsbooks — not a single source — as the foundation of your data. Books experience their own downtime (maintenance, outages, etc.). A multi-book setup ensures individual source failures degrade gracefully rather than taking your system offline.
Step 5: Stream Live Odds Updates
Instead of polling /fixtures/odds repeatedly, use the SSE streaming endpoint to receive real-time odds updates passively.
/stream/odds/{sport} — Real-Time Odds Stream
/stream/odds/{sport} — Real-Time Odds StreamGET https://api.opticodds.com/api/v3/stream/odds/basketball?sportsbook=DraftKings&sportsbook=BetMGM&league=NCAAB&market=MoneylineRequired Parameters:
{sport}— Path parameter (e.g.,basketball,football)sportsbook— At least one sportsbook (can pass multiple)
Optional Parameters:
| Parameter | Description |
|---|---|
league | Filter by league(s) |
fixture_id | Filter by fixture(s) |
market | Filter by market(s) |
is_main | Main lines only |
is_live | Live games only |
odds_format | Odds format |
last_entry_id | Resume from a specific point (for reconnection) |
include_fixture_updates | Set to true to receive game status changes |
include_deep_link | Set to true to include deep link data |
Event Types
odds — Fired when an odd is posted or updated (unsuspended)
event: odds
id: 1730079534820-2
data: {"data":[{"fixture_id":"A69FA4D64518","sportsbook":"BetMGM","market":"1st Half Moneyline","name":"Philadelphia Eagles","price":-230,"is_main":true,...}],"entry_id":"1730079534820-2","type":"odds"}
locked-odds — Fired when an odd is suspended or taken off the board
event: locked-odds
id: 1730079527180-0
data: {"data":[{"fixture_id":"8BDC2E0FF301","sportsbook":"DraftKings","market":"Player Passing Yards","name":"Dak Prescott Over 247.5","price":-115,...}],"entry_id":"1730079527180-0","type":"locked-odds"}
fixture-status — Game time or status changes (requires include_fixture_updates=true)
event: fixture-status
data: {"data":{"fixture_id":"FB0D30DCDD6C","league":"ATP","new_start_date":"2024-08-28T20:30:00+00:00","old_start_date":"2024-08-28T20:20:00+00:00","new_status":null,"old_status":null}}
connected — Confirmation that stream is active
event: connected
data: ok go
ping — Heartbeat to keep connection alive
event: ping
data: 2024-08-28T18:57:49Z
Python Example
import requests
from requests.exceptions import ChunkedEncodingError
import json
import sseclient # pip install sseclient-py
last_entry_id = None
while True:
try:
params = {
"key": "YOUR_API_KEY",
"sportsbook": ["DraftKings", "BetMGM", "Hard Rock"],
"market": ["Moneyline"],
"league": ["NCAAB"],
}
if last_entry_id:
params["last_entry_id"] = last_entry_id
r = requests.get(
"https://api.opticodds.com/api/v3/stream/odds/basketball",
params=params,
stream=True,
)
client = sseclient.SSEClient(r)
for event in client.events():
if event.event == "odds":
data = json.loads(event.data)
last_entry_id = data.get("entry_id")
print("odds:", data)
elif event.event == "locked-odds":
data = json.loads(event.data)
last_entry_id = data.get("entry_id")
print("locked-odds:", data)
else:
print(event.event, ":", event.data)
except ChunkedEncodingError:
print("Disconnected, attempting to reconnect...")
except Exception as e:
print("Error:", e)
breakNode.js Example
const EventSource = require("eventsource"); // npm install eventsource
const url = "https://api.opticodds.com/api/v3/stream/odds/basketball";
const params = {
key: "YOUR_API_KEY",
sportsbook: ["DraftKings", "BetMGM", "Hard Rock"],
market: ["Moneyline"],
league: ["NCAAB"],
};
let lastEntryId = null;
function connectToStream() {
const queryString = new URLSearchParams();
queryString.append("key", params.key);
params.sportsbook.forEach((sb) => queryString.append("sportsbook", sb));
params.market.forEach((m) => queryString.append("market", m));
params.league.forEach((l) => queryString.append("league", l));
if (lastEntryId) {
queryString.append("last_entry_id", lastEntryId);
}
const eventSource = new EventSource(`${url}?${queryString.toString()}`);
eventSource.addEventListener("odds", function (event) {
const data = JSON.parse(event.data);
lastEntryId = data.entry_id;
console.log("odds:", data);
});
eventSource.addEventListener("locked-odds", function (event) {
const data = JSON.parse(event.data);
lastEntryId = data.entry_id;
console.log("locked-odds:", data);
});
eventSource.onerror = function (event) {
console.error("EventSource failed:", event);
eventSource.close();
setTimeout(connectToStream, 1000);
};
}
connectToStream();Best Practices for Streaming
- Group up to 10 leagues per connection — Don't overload a single stream
- Always track
last_entry_id— Use it for seamless reconnection without missing data - Handle disconnections gracefully — Wrap your listener in a retry loop
- Use
is_main=true— If you only care about primary lines, filter to reduce noise - Recommended storage key:
fixture_id + sportsbook + market + namefor multi-book tracking, orfixture_id + market + namefor single-book
Understanding Main Line Changes
When a sportsbook moves the main line, the behavior depends on whether alternate lines exist:
No alternates: You'll receive locked-odds for the old line and odds for the new line.
With alternates: You'll receive odds events showing the new is_main assignments. No locked-odds are sent for the old main line — it simply becomes an alternate.
Step 6: Monitor Results
/stream/results/{sport} — Real-Time Results Stream
/stream/results/{sport} — Real-Time Results StreamListen for live score updates, game status changes, and in-play data via SSE.
GET https://api.opticodds.com/api/v3/stream/results/basketball?league=NBAEvent Types:
fixture-results— Score and stats updates during the gameconnected— Stream is activeping— Heartbeat
The results stream data format matches the /fixtures/results endpoint structure.
/fixtures/results — Get Results Snapshot
/fixtures/results — Get Results SnapshotPull the current results (scores, stats, in-play data) for specific fixtures.
GET https://api.opticodds.com/api/v3/fixtures/results?fixture_id=439A1AC1DBDBExample Response (Baseball):
{
"data": [
{
"sport": { "id": "baseball", "name": "Baseball" },
"league": { "id": "mlb", "name": "MLB" },
"fixture": {
"id": "439A1AC1DBDB",
"status": "live",
"is_live": true
},
"scores": {
"home": {
"total": 0,
"periods": { "period_1": 0, "period_2": 0, "period_3": 0 }
},
"away": {
"total": 3,
"periods": { "period_1": 0, "period_2": 3, "period_3": 0 }
}
},
"in_play": {
"period": "7",
"clock": "Top",
"balls": 0,
"outs": 2,
"strikes": 0,
"runners": {
"third": { "player_id": "19AA4BA7DD27", "player_name": "Colt Keith" },
"second": { "player_id": "48805399AB84", "player_name": "Wenceel Perez" },
"first": null
},
"batter": { "player_id": "8BDDD21FD738", "player_name": "Spencer Torkelson" }
},
"stats": {
"home": [{ "period": "all", "stats": { "rbi": 0, "hits": 4, "runs": 0, "at_bats": 22 } }],
"away": [{ "period": "all", "stats": { "rbi": 3, "hits": 9, "runs": 3, "at_bats": 28 } }]
}
}
]
}Key fields:
scores— Period-by-period scoring breakdownin_play— Live game state (period, clock, possession, down/distance for football, balls/strikes/outs for baseball, runners on base, etc.)stats— Team-level stats (sport-specific)extra— Decision/decision method (for combat sports)
/fixtures/player-results — Get Player Results
/fixtures/player-results — Get Player ResultsPull individual player stat lines for specific fixtures.
GET https://api.opticodds.com/api/v3/fixtures/player-results?fixture_id=439A1AC1DBDBStep 7: Grade Bets
/grader/odds — Settle a Bet
/grader/odds — Settle a BetGiven a fixture, market, and selection, the grader tells you whether the bet won, lost, or pushed.
GET https://api.opticodds.com/api/v3/grader/odds?fixture_id=B848DE682885&market=Total%20Rounds&name=Under%202.5Required Parameters:
| Parameter | Description |
|---|---|
fixture_id | The fixture the bet applies to |
market | The market label (use display name, e.g., Moneyline, not moneyline) |
name | The selection name (e.g., Buffalo Bills, Over 10.5, Aaron Judge Under 10.5) |
Optional Parameters:
player_id— Use if player names are ambiguous across sportsbooksshow_live_results— Get in-progress grading before game completion (use with caution)void_substitutes— Handle substitute player scenarios
Example Response:
{
"data": {
"fixture_id": "B848DE682885",
"away_team_display": "Tracy Cortez",
"home_team_display": "Rose Namajunas",
"status": "Completed",
"away_score": 0,
"home_score": 1,
"market": "Total Rounds",
"name": "Under 2.5",
"result": "Lost"
}
}Possible Results:
| Result | Description |
|---|---|
Won | Bet settled as a win |
Lost | Bet settled as a loss |
Refunded | Bet settled as a push |
Pending | Game not completed or results not confirmed |
Half Won | Applies to Asian markets |
Half Lost | Applies to Asian markets |
Error Codes:
| Code | Message |
|---|---|
| 100 | Game not found |
| 104 | Game is still live |
| 107 | Game has not started |
| 108 | Game has not completed |
| 109 | Game has been canceled |
| 201 | Score data not found |
| 212 | Unknown player |
Tip: Pass the
marketlabel exactly as it appears in the odds response (e.g.,Point Spreadnotpoint_spread).
Additional Endpoints
Futures
/futures — Get a list of available futures markets (e.g., "Super Bowl Winner", "MVP")
GET https://api.opticodds.com/api/v3/futures?sport=football&league=nfl/futures/odds — Get odds for futures markets across sportsbooks
GET https://api.opticodds.com/api/v3/futures/odds?sportsbook=DraftKings&league=nfl&market=Super%20Bowl%20Winner/grader/futures — Grade a futures bet
GET https://api.opticodds.com/api/v3/grader/futures?league=nfl&market=Super%20Bowl%20Winner&name=Kansas%20City%20ChiefsHistorical Odds
/fixtures/odds/historical — Get the full price history for specific odds
GET https://api.opticodds.com/api/v3/fixtures/odds/historical?id=ODDS_ID&sportsbook=DraftKingsReturns an array of every price change, lock, unlock, and settlement event with timestamps.
Rate limit: 10 requests per 15 seconds. Use this for analysis, not real-time tracking.
Injuries
/injuries — Get player injury reports
GET https://api.opticodds.com/api/v3/injuries?sport=football&league=nflFilter by sport, league, and team_id to get current injury reports.
Players
/players — Get player directory
GET https://api.opticodds.com/api/v3/players?sport=basketball&league=nbaReturns a paginated list of players with filtering options.
Squads / Rosters
/squads — Get team rosters
GET https://api.opticodds.com/api/v3/squads?team_id=TEAM_IDOdds Formats
The API supports six odds formats. Set via the odds_format query parameter:
| Format | Example | Description |
|---|---|---|
AMERICAN | -110, +150 | US standard (default) |
DECIMAL | 1.91, 2.50 | European standard |
PROBABILITY | 0.524, 0.400 | Implied probability |
MALAY | -0.91, 0.50 | Malaysian format |
HONG_KONG | 0.91, 1.50 | Hong Kong format |
INDONESIAN | -1.10, 1.50 | Indonesian format |
Complete API Endpoint Reference
Common / Discovery
| Method | Endpoint | Description |
|---|---|---|
| GET | /sports | List all sports |
| GET | /sports/active | List sports with active odds |
| GET | /leagues | List all leagues |
| GET | /sportsbooks | List all sportsbooks |
| GET | /sportsbooks/last-polled | Last polled time per sportsbook |
| GET | /markets | List all markets |
| GET | /markets/active | List markets with active odds |
| GET | /players | List players |
| GET | /squads | Get team rosters |
Fixtures
| Method | Endpoint | Description |
|---|---|---|
| GET | /fixtures | Get all fixtures (paginated) |
| GET | /fixtures/active | Get fixtures with odds |
| GET | /fixtures/tournaments | Get tournament fixtures |
Odds
| Method | Endpoint | Description |
|---|---|---|
| GET | /fixtures/odds | Get current odds snapshot |
| GET | /fixtures/odds/historical | Get full price history |
Results & Scores
| Method | Endpoint | Description |
|---|---|---|
| GET | /fixtures/results | Get fixture results/scores |
| GET | /fixtures/player-results | Get player stat lines |
Streaming (SSE)
| Method | Endpoint | Description |
|---|---|---|
| GET | /stream/odds/{sport} | Real-time odds stream |
| GET | /stream/results/{sport} | Real-time results stream |
Grading
| Method | Endpoint | Description |
|---|---|---|
| GET | /grader/odds | Grade a bet |
| GET | /grader/futures | Grade a futures bet |
Futures
| Method | Endpoint | Description |
|---|---|---|
| GET | /futures | List available futures |
| GET | /futures/odds | Get futures odds |
Injuries
| Method | Endpoint | Description |
|---|---|---|
| GET | /injuries | Get injury reports |
Parlay (SGP)
| Method | Endpoint | Description |
|---|---|---|
| POST | /parlay/odds | Price a same game parlay |
Recommended Integration Path
Here's the order we recommend for building your integration:
1. Authentication → Confirm your API key works with GET /sports
2. Discovery → Pull sports, leagues, sportsbooks, and markets
3. Fixtures → Pull active fixtures for your target leagues
4. Odds Snapshot → Pull odds from 2-3 sportsbooks per fixture
5. Streaming → Set up SSE stream for live odds updates
6. Results → Stream or poll for scores and game state
7. Grading → Wire up bet settlement via the grader
8. Futures → Add futures markets if applicable
9. Historical → Add historical analysis if needed
Best Practices
- Use multiple sportsbooks — Always pass 2-3+ sportsbooks per odds request for redundancy
- Track
last_entry_id— Store it on every stream event for seamless reconnection - Use
is_main=true— When you only care about primary lines, this dramatically reduces data volume - Group streams by sport — Use separate stream connections per sport, up to 10 leagues each
- Paginate fixtures — Use the
pageparameter and checktotal_pagesin responses - Use fixture IDs — Store fixture IDs from
/fixtures/activeand use them for odds, results, and grading - Handle locked-odds — When you receive a
locked-oddsevent, remove that line from your active offerings - Date format — Always use ISO 8601 (
YYYY-MM-DDTHH:MM:SSZ) for date parameters - Market labels for grading — The grader expects display names (e.g.,
Point Spread) not IDs (e.g.,point_spread)
Glossary
| Term | Definition |
|---|---|
| Fixture | A single game or match between two competitors |
| Market | A betting category (e.g., Moneyline, Point Spread, Total Points) |
| Main Line | The primary/given line for a market (e.g., the consensus spread) |
| Alternate Line | Non-primary lines (e.g., alternate spreads) |
| Selection | The specific pick within a market (e.g., "Buffalo Bills", "Over 45.5") |
| Selection Line | over or under for total markets |
| Points | The spread or total value (e.g., -6.5, 45.5) |
| Grouping Key | Groups related odds (e.g., an Over/Under pair share the same grouping key) |
| Deep Link | A URL that opens directly in a sportsbook's app |
| Limits | Maximum stake a sportsbook will accept on a given line |
| SSE | Server-Sent Events — a protocol for receiving real-time server push updates |
| Locked Odds | An odd that has been suspended or taken off the board |
| is_onshore | Whether a sportsbook is a licensed/regulated operator |
| Rotation Number | A standardized number assigned to teams by Las Vegas sportsbooks |
| Entry ID | A stream checkpoint used for reconnection (last_entry_id) |
Need Help?
- Developer Docs: developer.opticodds.com
- Guides: developer.opticodds.com/docs
- API Reference: developer.opticodds.com/reference
- Changelog: developer.opticodds.com/changelog
This guide covers the standard OpticOdds API endpoints. For automated odds generation with custom pricing rules, see the Getting Started with Copilot guide.
Updated 3 days ago