The Parlay API delivers real‑time sports data—including live odds, game details, player props, best‑book selections, market disagreement, injury reports, and news—across dozens of sports and sportsbooks, and also provides historical period‑market data and sandbox endpoints for testing.
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs.
GET
/v1/sports/{sport_key}/live/disagreement
Sports Live Disagreement
sport_key(path, required)
period(query) — FT / 1H / 2H / Q1-Q4 / OT / P1-P3 / F5 / F7 or 'all'
market(query) — spread / total / h2h
side(query) — Optional side filter (over/under for total, home/away for spread/h2h). Omit to get all sides per book.
anchor(query) — Reference for deviation: 'median' (across all books) or 'pinnacle'
max_age_s(query) — Drop books whose latest observation is older than this many seconds. Default 90s catches Bovada's slower polling cycle alongside Pinnacle's tight one. Lower it for stricter freshness, raise it for sparse periods (deep Q4, OT).
min_books(query) — Minimum number of books required to emit a row. Default 2 because rows with n_books=1 can't be disagreeing with anyone (max_deviation_pct=0 always). Pass 1 to also see markets where only one book has a recent quote (useful for diagnosing which books are slow to refresh).
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs.
keyword(query) — Optional case-insensitive headline substring match
limit(query, limit) — Max articles to return
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs.
GET
/v1/sports/baseball_mlb/probable-pitchers
Mlb Probable Pitchers
date(query) — YYYY-MM-DD. Default: all upcoming dates in cache (~3 days)
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs.
POST
/v1/meta/batch-quote
Batch Quote Credits
GET
/v1/alerts/prop-line
List Prop Line Alerts
enabled_only(query)
sport_key(query)
limit(query, limit)
POST
/v1/alerts/prop-line
Create Prop Line Alert
GET
/v1/alerts/prop-line/{alert_id}
Get Prop Line Alert
alert_id(path, required)
PATCH
/v1/alerts/prop-line/{alert_id}
Patch Prop Line Alert
alert_id(path, required)
DELETE
/v1/alerts/prop-line/{alert_id}
Delete Prop Line Alert
alert_id(path, required)
POST
/v1/clv/import-screenshot
Import Bet Screenshot
GET
/v1/affiliates
List Affiliates
country(query)
GET
/go/{book_key}
Affiliate Redirect
book_key(path, required)
utm_source(query) — Where the click came from: ai-claude, ai-chatgpt, partners-page, response-inline, etc
utm_campaign(query)
country(query)
state(query)
GET
/partners
Partners Page
country(query)
GET
/terms
Terms Of Service
GET
/legal/tos
Terms Of Service
GET
/legal/terms
Terms Of Service
GET
/privacy
Privacy Policy
GET
/legal/privacy
Privacy Policy
GET
/acceptable-use
Acceptable Use Policy
GET
/legal/aup
Acceptable Use Policy
GET
/legal/acceptable-use
Acceptable Use Policy
GET
/dmca
Dmca Policy
GET
/legal/dmca
Dmca Policy
GET
/legal
Legal Index
GET
/collections/ParlayAPI.postman_collection.json
Postman Collection Curated
GET
/datasets/nfl-week-1-opening-lines-2026.csv
Week1 Opening Lines Csv
GET
/datasets/nfl-week-1-opening-lines-2026.json
Week1 Opening Lines Json
GET
/v1/sandbox/sports
Sandbox Sports
GET
/v1/sandbox/sports/{sport_key}/odds
Sandbox Odds
sport_key(path, required)
regions(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
GET
/v1/sandbox/sports/{sport_key}/props
Sandbox Props
sport_key(path, required)
markets(query) — CSV of prop market keys Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — CSV of book keys (filter applied to output) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
min_volume(query) — Drop markets below this source-native volume
min_confidence(query) — Drop weak text matches
sort(query) — balanced or match
include_raw(query)
include_closed(query)
include_unpriced(query)
GET
/v1/event-markets/search
Search Event Markets
q(query, required) — Free-text market search
sources(query) — Comma-separated sources
limit(query, limit)
min_volume(query) — Drop markets below this source-native volume
min_confidence(query) — Drop weak text matches
sort(query) — balanced or match
include_raw(query)
include_closed(query)
include_unpriced(query)
GET
/v1/calc/kelly
Calc Kelly
bankroll(query, required) — Total bankroll in USD
odds(query, required) — Bet price (American or decimal, e.g. '-110' or '1.91')
win_prob(query, required) — Your estimated win probability (0 < p < 1)
fraction(query) — Kelly fraction multiplier (0.25 = quarter Kelly)
GET
/v1/calc/hedge
Calc Hedge
original_stake(query, required) — Stake you already placed
original_odds(query, required) — Odds you took (American or decimal)
hedge_odds(query, required) — Current available odds on the other side
target(query) — One of: equal_profit (lock in identical profit either side), guaranteed_minimum (max guaranteed return), free_roll (bet just enough to recover original_stake)
GET
/v1/calc/edge
Calc Edge
odds(query, required) — The price you can bet at (American or decimal)
true_prob(query) — Your estimated true win probability. Either this OR (sharp_over_odds + sharp_under_odds) required.
sharp_over_odds(query) — Sharp book's price on the SAME side as `odds`. Used with sharp_under_odds for no-vig fair-line derivation.
sharp_under_odds(query) — Sharp book's price on the OPPOSITE side. Used with sharp_over_odds for no-vig.
stake(query) — Stake to compute EV-in-dollars (default $100)
GET
/v1/calc/free-bet
Calc Free Bet
free_bet_usd(query, required) — Face value of the free bet
bet_odds(query, required) — Odds you'd take on side A using the free bet
hedge_odds(query, required) — Odds on side B at a different book for the hedge
GET
/v1/sports/{sport_key}/middles
Find Middles
sport_key(path, required)
min_gap(query) — Minimum middle-window width in points/runs/goals (default 1.0). A middle needs at least one whole number strictly inside the window to cash both sides, so 1.0 is the practical floor.
min_books(query) — Minimum distinct books across the group (default 2).
markets(query) — CSV of market_keys to limit the scan (e.g. markets=totals for game totals only, or markets=player_points). Omit to scan game totals, spreads, AND player-total props. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
include_props(query) — Include player-total props (points, strikeouts, ...) alongside game totals + spreads. Default true.
max_width(query) — Optional cap on window width. 0 (default) = no cap. Useful to hide implausibly wide 'middles' that pair a main line with a deep, stale alternate line.
GET
/v1/verdict
Verdict
sport(query, required) — sport_key, e.g. baseball_mlb
market(query) — h2h | spreads | totals | a player prop key (player_points, ...)
side(query, required) — Team name or home/away (h2h/spreads); over/under (totals/props)
home(query) — Home team (with `away`, to identify the game)
away(query) — Away team
event(query) — Alternative to home/away: 'Away @ Home'
team(query) — Alternative: one team name to find the game
player(query) — Player name (required for player-prop markets)
line(query) — Line/point for spreads, totals, props
book(query) — The book you'd bet at (grades that book's price)
price(query) — The price you're offered (American or decimal). Overrides `book` price.
region(query) — Where you can bet: us (default) | eu | uk | au | ca. Scopes the best-price/shop recommendation to books you can actually use. Omit to use your saved preference or US.
books(query) — Exact CSV of books you can bet at (e.g. draftkings,fanduel,novig). Overrides region; use this for state geo-blocks. Omit to use your saved preference.
bankroll(query) — Your bankroll. When the bet is +EV, returns a suggested Kelly stake amount.
kelly(query) — Kelly fraction for staking (default 0.5 = half-Kelly, the bankroll-safe standard).
sharpBook(query) — Sharp book to anchor the fair line
GET
/v1/verdict/prefs
Get Verdict Prefs
GET
/v1/meta/sla
Get Sla
GET
/v1/meta/sdks
Get Sdks
POST
/v1/verdict/prefs
Set Verdict Prefs
region(query) — Where you bet: us | eu | uk | au | ca
books(query) — Exact CSV of book keys you can bet at (overrides region)
POST
/v1/parlay/verdict
Parlay Verdict
GET
/v1/sports/{sport_key}/best-bets
Best Bets
sport_key(path, required)
region(query) — Where you can bet: us (default) | eu | uk | au | ca.
books(query) — Exact CSV of books you can bet at (overrides region).
limit(query, limit) — Max plays to return.
min_edge(query) — Minimum edge %% vs the no-vig fair line.
min_books(query) — Minimum books pricing a play (higher = more reliable).
markets(query) — Optional CSV of market_keys to restrict the scan. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
GET
/v1/try/verdict
Try Verdict
sport(query, required) — sport_key, e.g. baseball_mlb
side(query, required) — Team (h2h/spreads), or over/under (totals/props)
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs; browser EventSource cannot set headers, so this stays supported.
event_id(query) — Optional: filter to one game's event_id
bookmakers(query) — Comma-separated books, e.g. fanduel,pinnacle Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated prop market keys, e.g. player_points,player_rebounds Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
since(query) — Resume from this timestamp_ms. Skips initial replay of rows older than this.
diff(query) — If true, frames after initial_state include only fields that changed since the last frame for the same (event_id, bookmaker, market_key) tuple
max_age_s(query) — Drop game-line rows whose retained price/source timestamp is older than this many seconds. Defaults to 600; maximum 3600. The timestamp may remain unchanged when an upstream poll sees the same price.
GET
/v1/sse/hot/{sport_key}
Sse Odds
sport_key(path, required)
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs; browser EventSource cannot set headers, so this stays supported.
event_id(query) — Optional: filter to one game's event_id
bookmakers(query) — Comma-separated books, e.g. fanduel,pinnacle Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated prop market keys, e.g. player_points,player_rebounds Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
since(query) — Resume from this timestamp_ms. Skips initial replay of rows older than this.
diff(query) — If true, frames after initial_state include only fields that changed since the last frame for the same (event_id, bookmaker, market_key) tuple
max_age_s(query) — Drop game-line rows whose retained price/source timestamp is older than this many seconds. Defaults to 600; maximum 3600. The timestamp may remain unchanged when an upstream poll sees the same price.
GET
/v1/odds-drop/{sport_key}
Sse Odds Drop
sport_key(path, required)
apiKey(query) — API key. Prefer the X-API-Key header, which keeps the key out of URLs and logs; browser EventSource cannot set headers, so this stays supported.
threshold(query) — Minimum American-odds delta to trigger an event. Default 10 (a -110 becoming -120, or +100 becoming +110).
event_id(query) — Optional: filter to one game's event_id
bookmakers(query) — Comma-separated books Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated market keys Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
sports(query) — Comma-separated sport_keys for multi-sport subscription. Overrides path sport_key. Use 'all' as a sentinel to subscribe to every sport_key with recent activity (last 5 min).
direction(query) — both | toward_favorite | toward_dog. Filter by which way the line moved.
heartbeat_s(query)
GET
/v1/sports
List Sports
all(query) — Include inactive sports
GET
/v1/meta/api-info
Api Info
GET
/v1/meta/credit-costs
Credit Costs
POST
/v1/meta/quote
Quote Credits
GET
/v1/meta/endpoints
List Endpoints
tag(query) — Filter to endpoints carrying this tag (e.g. 'Metadata', 'Calculators', 'Sports & Odds').
method(query) — Filter to a specific HTTP method (GET, POST, etc.).
GET
/v1/meta/webhooks
Webhooks Spec
GET
/v1/meta/provider-state
Provider State
GET
/v1/meta/source-quality
Source Quality
minutes(query)
limit(query, limit)
GET
/v1/meta/source-health
Source Health Alias
minutes(query)
limit(query, limit)
GET
/v1/meta/collector-flush
Collector Flush Meta
GET
/v1/meta/latest-state
Latest State Meta
limit(query, limit)
latency_window_s(query)
GET
/v1/meta/per-book-sla
Meta Per Book Sla
GET
/v1/meta/parser-coverage
Meta Parser Coverage
window_hours(query)
source(query) — Optional filter to one book.
sport_key(query) — Optional filter to one sport.
GET
/v1/meta/book-coverage
Meta Book Coverage
window_minutes(query)
include_warn(query)
GET
/v1/asyncapi.json
Get Asyncapi Spec
GET
/v1/pricing
Get Pricing
GET
/v1/regions
List Regions
GET
/v1/markets
List Markets
GET
/v1/bookmakers
List Bookmakers
all(query) — Include non-active (merged/decommissioned) entries
include_endpoints(query) — Attach endpoints[] + example_paths per book. Set false for the lean catalog.
GET
/v1/bookmakers/{key}
Get Bookmaker
key(path, required)
GET
/v1/bookmakers/{key}/freshness
Get Bookmaker Freshness
key(path, required)
GET
/v1/sports/{sport_key}/events
List Events
sport_key(path, required)
dateFormat(query)
eventIds(query) — Comma-separated event IDs
commenceTimeFrom(query)
commenceTimeTo(query)
GET
/v1/sports/{sport_key}/participants
List Participants
sport_key(path, required)
GET
/v1/sports/{sport_key}/events/canonical
List Canonical Events
sport_key(path, required)
GET
/v1/sports/{sport_key}/odds
Get Odds
sport_key(path, required)
regions(query) — Comma-separated: us,us2,uk,eu,au. Default 'us'. iter_047 #420: was previously required (...). Made optional with 'us' default so consumers running pre-existing The-Odds-API-style code (which defaulted to us) don't 422. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated. Servable here: h2h, spreads, totals, alternate_spreads, alternate_totals, outrights, and any player_*/batter_*/pitcher_*/anytime_*/futures_* prop key. Any other key is still accepted and still answered, but it is NOT billed and returns nothing here: period keys (h2h_1st_half, totals_1st_5_innings, ...) belong to /v1/sports/{sport_key}/live/period_markets. The response says which keys were billed (x-markets-served), which were not (x-markets-unservable) and where those are served (x-markets-served-elsewhere). Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
dateFormat(query)
bookmakers(query) — Comma-separated bookmaker keys (overrides regions) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
eventIds(query) — Comma-separated event IDs
commenceTimeFrom(query)
commenceTimeTo(query)
date(query) — Shortcut: events whose commence_time falls on this UTC date (YYYY-MM-DD). Sugar for commenceTimeFrom= T00:00:00Z and commenceTimeTo= T23:59:59Z. Explicit commenceTime* values win.
include(query) — Comma-separated. Shape tokens: normalized (default, every field we build), slim (drops raw_json from any row that carries one), raw (the identifying fields plus the bookmakers tree and raw_json, dropping derived fields such as canonical_event_id, sport_title, probable_pitchers and starting_lineups). Events on this endpoint do not currently carry a raw_json field, so slim returns the same fields as normalized here and raw differs only by the derived fields it drops. Add 'verification' to include verified_at, line_changed_at, and is_current per bookmaker.
includeLinks(query) — Include a link on eligible FanDuel game outcomes with a matching native quote observed within five minutes. Missing metadata is omitted; availability varies by market.
includeSids(query) — Include the native FanDuel selection ID as sid on eligible game outcomes. Missing or mismatched metadata is omitted.
verified(query) — Alias for include=verification. Adds verified_at, line_changed_at, and is_current per bookmaker.
live(query) — Live games only (commence_time at or before now). Equivalent to passing commenceTimeTo= . No extra cost.
include_live(query) — Include in-progress games in the response (off by default; /odds is for pregame analysis). Set true to get both pregame and live in one call.
GET
/v1/sports/{sport_key}/events/{event_id}/odds
Get Event Odds
sport_key(path, required)
event_id(path, required)
regions(query, required) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
dateFormat(query)
bookmakers(query) — Comma-separated bookmaker keys. Overrides regions. Returns only the listed books that have data for this event+market. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
min_matches(query) — Minimum matches required for a player to appear
window_days(query) — Recency window for source matches
GET
/v1/sports/{sport_key}/scores
Get Scores
sport_key(path, required)
daysFrom(query) — Days of history (1-14). Costs a second credit, and only on sports we hold score history for; on any other sport it is ignored and you are charged the base 1 credit. For longer windows use the historical endpoints.
dateFormat(query)
GET
/v1/historical/sports/{sport_key}/odds
Get Historical Odds
sport_key(path, required)
date(query) — ISO 8601 timestamp OR YYYY-MM-DD date. Omit to get the most recent snapshot. See doc note below for behavior.
regions(query) — Comma-separated: us,us2,uk,eu,au. Default us. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated: h2h,spreads,totals. Default h2h. Those three are the whole servable list here; any other key is answered but billed zero and routed by the x-markets-served-elsewhere header. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
GET
/v1/historical/sports/{sport_key}/matches
Get Historical Matches
sport_key(path, required)
date(query) — Shortcut for dateFrom=dateTo=date (YYYY-MM-DD)
dateFrom(query) — Start date YYYY-MM-DD
dateTo(query) — End date YYYY-MM-DD
sources(query) — Comma-separated sources, e.g. hltv,opendota,vlrgg,pinnacle
pricedOnly(query) — Only rows that include real odds/prices
includeRaw(query) — Include raw source payload
limit(query, limit)
GET
/v1/historical/sports/{sport_key}/coverage
Get Historical Coverage
sport_key(path, required)
dateFrom(query) — Start date YYYY-MM-DD
dateTo(query) — End date YYYY-MM-DD
GET
/v1/sports/{sport_key}/line-movement
Get Line Movement
sport_key(path, required)
eventId(query)
event_id(query)
source(query)
bookmaker(query)
market(query) — Filter to market_key (e.g. player_points)
market_key(query) — Alias for market
player(query) — Filter to specific player
hours(query) — Lookback window in hours (max 168)
window_minutes(query) — Lookback window in minutes (max 10080)
markets(query) — Comma-separated prop market keys (e.g. player_pass_yds,player_points) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — Comma-separated bookmaker keys Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
player(query) — Filter by player name (partial match)
eventId(query) — Filter by event ID
oddsFormat(query)
dfsOdds(query) — DFS normalization for legacy flat-payout rows: 'midpoint' = +100/-100 (default, zero-vig), 'effective' = per-book implied. Explicit Pick6 offers ignore this option and return null American prices with available_sides and selection_by_side payout metadata.
limit(query, limit) — Max rows returned (default 5000, max 10000)
offset(query, offset) — Page offset within the result set. Combine with limit for pagination. For results past 10000 rows, narrow via ?markets= or ?bookmakers= filters instead.
grouped(query) — Return one entry per prop with a books[] array (recommended) instead of one row per book
include_event_markets(query) — Include futures and prediction-market rows that lack a single home/away_team (Polymarket yes/no questions, Underdog season-longs, etc). Auto-enabled when bookmakers includes 'polymarket'.
maxAgeSec(query) — Only return prop rows written within this many seconds. Every row already carries age_seconds; this drops any older than the bound (and any whose write time can't be parsed). Omit to serve the full recency window (up to 3600s / 60 min).
include(query) — Accepted only as 'normalized', which is what this endpoint already returns. /props serves one shape, so any other token (for example 'raw' or 'slim') is rejected with 400 instead of being ignored. The shape tokens live on GET /v1/sports/{sport_key}/odds.
includeLinks(query) — Include validated FanDuel per-side betslip links when the stored observation marked the native market OPEN and runner ACTIVE.
includeSids(query) — Include validated FanDuel per-side native selection IDs.
GET
/v1/sports/{sport_key}/props/coverage
Get Props Coverage
sport_key(path, required)
markets(query) — Comma-separated prop market keys Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — Comma-separated bookmaker keys Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
player(query) — Filter by player name
eventId(query) — Filter by event ID
oddsFormat(query)
dfsOdds(query)
limit(query, limit)
GET
/v1/sports/{sport_key}/odds/coverage
Get Odds Coverage
sport_key(path, required)
regions(query) — Comma-separated: us,us2,uk,eu,au. Same meaning and same default as /odds. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — Comma-separated market keys. Same meaning and same default as /odds. The spread and total columns only count what you asked for. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — Comma-separated bookmaker keys (overrides regions). Same meaning as on /odds. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
commenceTimeFrom(query) — Same meaning as on /odds. Your window wins over the pregame default.
commenceTimeTo(query) — Same meaning as on /odds. Your window wins over the pregame default.
date(query) — Shortcut for commenceTimeFrom= T00:00:00Z and commenceTimeTo= T23:59:59Z, exactly as on /odds.
eventIds(query) — Comma-separated event IDs. Same filtering and cache semantics as /odds.
live(query) — Report the in-play board only, exactly as /odds?live=true would serve it.
include_live(query) — Report pregame and in-play together, exactly as /odds?include_live=true would serve it.
fresh_within_seconds(query) — Only count a book's prices when its last_update is within this window.
GET
/v1/pinnacle-coverage
Pinnacle Coverage
GET
/v1/status
Status Json
GET
/v1/sports/{sport_key}/props/markets
List Prop Markets
sport_key(path, required)
GET
/v1/historical/sports/{sport_key}/closing-odds
Get Historical Closing Odds
sport_key(path, required)
markets(query) — Comma-separated. Game lines: h2h, spreads, totals. Player props: player_strikeouts, player_total_bases, player_points, player_rebounds, player_assists, player_pass_yds, player_rush_yds, player_shots_on_goal, etc. (any market_key from prop_closing_lines). Mix freely: markets=h2h,player_strikeouts. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — Comma-separated. Game-line queries default to pinnacle. Prop-only queries default to all tracked books. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
season(query) — Season filter for game lines (e.g. 2023-24)
date(query) — Specific date YYYY-MM-DD (shortcut for dateFrom=dateTo=date)
dateFrom(query) — Start date (YYYY-MM-DD)
dateTo(query) — End date (YYYY-MM-DD)
player(query) — Filter props to a specific player name (substring match)
include_imports(query) — Also include rows you've imported via POST /v1/historical/closing-lines/import
limit(query, limit) — Rows per PUBLIC leg (game lines, props) for this page, 1..5000. Omit for the full row cap, which is exactly the behaviour this endpoint had before paging existed.
offset(query, offset) — Rows to skip in each PUBLIC leg. Use with the same limit to read past the row cap, including the case where one game_date fills a whole page and dateTo paging cannot advance. Both public legs are ordered on a unique key, so offset paging neither skips nor repeats rows.
oddsFormat(query)
POST
/v1/historical/closing-lines/import
Import Customer Closing Lines
DELETE
/v1/historical/closing-lines/import
Delete Customer Closing Imports
sport_key(query) — Filter to a sport_key (optional)
confirm(query) — Must be true to actually delete
GET
/v1/historical/coverage
Historical Coverage
sport_key(query) — Restrict coverage to this exact sport, intersected with source when supplied.
source(query) — Restrict coverage to this exact source, intersected with sport_key when supplied.
min_rows(query) — Hide array entries below this row count; does not change summary scope.
GET
/v1/historical/stats
Get Historical Stats
GET
/v1/historical/closing-lines.json
Closing Lines Json
date(query, required) — YYYY-MM-DD (UTC). One day per request.
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
daysFrom(query)
oddsFormat(query)
limit(query, limit) — sleep_iter_15 #514: max closing-line rows returned. Default 10000 effectively returns all (preserves prior behavior). Lower for top-N quick views.
offset(query, offset) — Page offset within the result set. Combine with limit for pagination.
GET
/v1/sports/{sport_key}/futures
Get Futures
sport_key(path, required)
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query) — american (default) | decimal. Selections get a matching `decimal` field alongside the existing `american` keys when decimal is requested.
GET
/v1/sports/{sport_key}/live
Get Live Odds
sport_key(path, required)
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — h2h, spreads, totals (comma-separated) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
regions(query) — us, eu, uk, au (comma-separated) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
max_age_hours(query) — Only include events whose commence_time is within the last N hours. Default 6 covers a typical MLB or NBA game plus extra innings / overtime. Raise to 12 for events with longer windows (long tennis matches, soccer with stoppage time), or lower to 3 for stricter in-play filtering.
GET
/v1/sports/{sport_key}/compare
Compare Odds
sport_key(path, required)
markets(query) — Market type Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
bookmakers(query) — CSV of bookmaker keys to include. Omit for all books. iter_060 #466. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
GET
/v1/sports/{sport_key}/best-line
Best Line Alias
sport_key(path, required)
markets(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
oddsFormat(query)
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
GET
/v1/usage
Get Usage
by_endpoint(query) — Include a per-endpoint credit-usage breakdown for the current billing period. iter_060 #469: customers asked for 'where did my credits go this month'. Off by default so the response stays lean.
GET
/v1/account
Get Usage
by_endpoint(query) — Include a per-endpoint credit-usage breakdown for the current billing period. iter_060 #469: customers asked for 'where did my credits go this month'. Off by default so the response stays lean.
GET
/v1/stats
Get Stats
GET
/pricing
Pricing
GET
/v1/sports/{sport_key}/odds/props
Odds Props Alias
sport_key(path, required)
markets(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
bookmakers(query) — Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
player(query)
eventId(query)
oddsFormat(query)
dfsOdds(query)
limit(query, limit)
offset(query, offset)
grouped(query)
include_event_markets(query)
maxAgeSec(query)
include(query)
includeLinks(query)
includeSids(query)
GET
/v1/inplay/arbs
Get Inplay Arbs
minProfit(query) — Minimum profit % to include
min_profit(query) — Alias for minProfit (snake-case)
min_profit_pct(query) — Alias for minProfit (alt snake-case)
sport(query) — Filter by sport_key
sport_key(query) — Alias for sport
sports(query) — CSV alias for sport (single value)
limit(query, limit)
POST
/v1/parlay/price
Price Parlay
POST
/v1/clv
Grade Clv
POST
/v1/clv/history
Clv History
POST
/v1/sgp/price
Sgp Price
GET
/v1/sports/{sport_key}/arbitrage
Find Arbitrage
sport_key(path, required)
include_live(query) — Include games that have already started or finished. Off by default: these endpoints rank BETS, and a bet on a finished game is not actionable. Set true to see commenced games too.
minProfit(query) — Minimum profit % to include (e.g. 1.5)
exclude_exchanges(query) — Exclude arbs where either side is anchored on an exchange (novig, prophetx). Exchange asks can be no-volume 'shill' orders that aren't actually takeable. iter_062 #473. When false (default), arbs still surface with an `is_exchange_anchored` flag so callers can choose.
exclude_books(query) — CSV of book keys to exclude from EITHER side of every arb. iter_064 #481. Example: `exclude_books=prophetx,novig` to drop arbs anchored on exchanges. Cleaner than exclude_exchanges when you want to drop additional books.
markets(query) — CSV of market_keys to limit the arb scan to. iter_064 #481. Example: `markets=h2h,spreads,totals` for game lines only; `markets=player_points` to focus on points props. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
limit(query, limit) — sleep_iter_14 #513: max arb opportunities returned per call. Default 10000 effectively returns all (preserves prior behavior since typical query yields <500). Lower it (e.g. limit=20) for a top-N quick view.
offset(query, offset) — Page offset within the sorted (best profit first) arb list. Combine with limit for pagination.
GET
/v1/sports/{sport_key}/ev
Find Positive Ev
sport_key(path, required)
include_live(query) — Include games that have already started or finished. Off by default: these endpoints rank BETS, and a bet on a finished game is not actionable. Set true to see commenced games too.
sharpBook(query) — Sharp book to use as true odds baseline
minEdge(query) — Minimum edge % to include (default 2.0)
min_edge_pct(query) — Snake-case alias for minEdge
markets(query) — CSV of market_keys to include (e.g. player_points,player_assists) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
min_books(query) — Minimum books_compared per row
limit(query, limit) — Max EV picks returned (default 200, max 500). sleep_iter_13 #512: prior hardcoded 200 cap is now caller-controllable. Combined with offset for pagination.
offset(query, offset) — Page offset within the sorted EV pick list. Combine with limit for pagination.
GET
/v1/sports/{sport_key}/consensus
Get Consensus
sport_key(path, required)
include_prediction_markets(query) — Include Kalshi/Polymarket prices in the consensus rollup. Defaults to False because prediction markets often price derivative questions (e.g. 'Phillies win series') that look like h2h ML but skew the average. Set true if you specifically want their prices mixed in.
bookmakers(query) — CSV of bookmaker keys to include in the rollup. Omit to include all books for the sport. iter_060 #465. Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
markets(query) — CSV of market_keys to filter to (e.g. h2h,player_points) Repeating this parameter is the same as the comma form: ?markets=h2h&markets=spreads and ?markets=h2h,spreads are one request, billed identically, and return the union. A value repeated across occurrences is counted once.
GET
/v1/exchange/{sport_key}/markets
Get Exchange Markets
sport_key(path, required)
exchange(query) — Filter by exchange: novig, kalshi
market_type(query) — Filter: MONEY, SPREAD, TOTAL, PLAYER_GOALS, etc.
min_volume(query) — Minimum volume in USD
GET
/v1/exchanges
List Exchanges
GET
/collections/postman.json
Postman Collection
POST
/v1/try/sgp/price
Try Sgp Price
GET
/v1/meta/movers
Meta Movers
sport_key(query) — Optional sport filter. Defaults to all sports.
window_minutes(query) — Lookback window in minutes (5 to 360, default 60).
limit(query, limit) — Top N movers to return (default 15).
pre_game_only(query) — If true (default), only return events whose commence_time is still in the future. Filters out the in-play price-collapse cases that otherwise dominate (tennis match in progress, late-game hockey, etc). Pass false to include live-game moves.
GET
/v1/meta/limits
Meta Limits
GET
/v1/key/successor
Key Successor
GET
/v1/meta/api-key-check
Meta Api Key Check
GET
/v1/meta/usage
Meta Usage
days(query) — Days of usage history to summarize (default 7, max 90).
GET
/v1/meta/diagnostic
Meta Diagnostic
GET
/v1/meta/status-history.json
Meta Status History Json
days(query) — Days of history to return (default 30, max 180).
GET
/v1/meta/book-catalog
Meta Book Catalog
class(query) — Filter to a single class (e.g. us_retail, uk, br, exchange). Omit for all classes.
live(query) — true: only books that produced rows in past 24h. false: only scaffolded-not-live. Omit for all.
region(query) — Filter to books with this region tag (e.g. US-NJ, BR, ES, FR, DE, AU). Matches against the regions list of each entry in /v1/meta/source-stack (when available).
GET
/v1/meta/event-search
Meta Event Search
q(query, required) — Search query. Matches against home_team, away_team, or both.
sport_key(query) — Optional sport filter (e.g. baseball_mlb).
hours_ahead(query) — Only return events with commence_time within the next N hours (default 168=7 days).
limit(query, limit) — Max results to return (default 20).
GET
/v1/meta/markets
Meta Markets
GET
/v1/meta/regions
Meta Regions
GET
/badge/{kind}.svg
Status Badge Svg
kind(path, required)
GET
/v1/try/{sport_key}/odds
Try Odds
sport_key(path, required)
GET
/v1/try/{sport_key}/arbitrage
Try Arbitrage
sport_key(path, required)
GET
/v1/try/{sport_key}/ev
Try Ev
sport_key(path, required)
GET
/v1/try/{sport_key}/middles
Try Middles
sport_key(path, required)
GET
/
Root
GET
/changelog.json
Changelog Json
GET
/v1/meta/changelog
Meta Changelog Json
limit(query, limit)
GET
/v1/meta/incidents
Incidents Json
status(query) — Filter by status: 'resolved' (closed), 'investigating', 'identified', 'monitoring', 'open' (all non-resolved). Omit for all.
since(query) — ISO 8601 date (YYYY-MM-DD) to filter incidents started on or after this date.
limit(query, limit)
GET
/v1/meta/uptime
Uptime Stats
by_endpoint(query) — If true, include per-endpoint breakdown (templated paths only, capped at 200).
sort_by(query) — When by_endpoint=true: sort by '5xx' (default; descending), 'total' (descending), or 'path' (alphabetical).
limit(query, limit) — When by_endpoint=true: cap on number of endpoints in response.
GET
/v1/metrics
Prometheus Metrics
GET
/api
Api Root
GET
/v1/keys
List Api Keys
230 endpoints auto-detected
Authentication
This API uses an API key, passed in the "X-API-Key" header. No OAuth required.
curl -X GET \
"https://parlay-api.com/docs/v1/health" \
-H "X-API-Key: YOUR_API_KEY"