sportsdata-mcp
The sportsdata-mcp server exposes ~500 read-only tools across 28+ sports-data providers, enabling AI agents to compare odds, fetch live scores and stats, analyse racing form, access prediction markets, and retrieve content from official league APIs.
Cross-bookmaker odds comparison – Compare prices across 11+ bookmakers (Sportsbet, TAB, Ladbrokes/Entain, PointsBet, BetR, Unibet, Pinnacle, Betfair Exchange, Dabble, FanDuel) using capability-tagged tools (e.g. sport.event_markets) for direct cross-provider comparison.
Real-time sports data – Fixtures, results, standings, player/team stats, and match details for:
AFL, NRL, NBA, MLB, Premier League, LaLiga, Serie A, NBL, WTA, Cricket Australia
Formula 1 (OpenF1): lap timing, pit stops, telemetry, race control messages
ESPN: scoreboard, standings, news across any sport/league ESPN covers
Racing (thoroughbred, greyhound, harness) – Race meetings, racecards, form guides, tote pools, price fluctuations, market movers, and next-to-jump feeds from Sportsbet, TAB, PointsBet, BetR, Betfair, FanDuel Racing, and Racing and Sports.
Prediction markets – Query Kalshi (CFTC-regulated) and Polymarket (crypto) for market catalogues, order books, price history, and trades.
Fantasy & analytics – SuperCoach projections, ownership, and prices across 7 sports (AFL, NRL, EPL, NBA, NBL, NFL, BBL); Data Golf skill ratings, strokes-gained breakdowns, pre-tournament/in-play predictions, and DFS projections.
Content & social – News, video, photos, and articles from AFL and Cricket Australia APIs; Twitter/X tweet search, user timelines, and trends (requires Bearer token).
Discovery & configuration – Meta-tools (list_available_groups, list_tools_by_capability) let models discover enabled providers and find comparable tools. Enable only the tool groups you need via YAML config or environment variables; specs can be refreshed OTA without reinstalling.
Allows retrieval of Contentful CMS entries (e.g., promotions, major-event navigation) via the Entain/Ladbrokes provider.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sportsdata-mcp compare AFL odds for Collingwood vs Essendon across Sportsbet and Entain"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sportsdata-mcp
Ask your AI which bookmaker is paying more — and get a real answer.
Free & open source (MIT). ~862 tools across 66 providers in Claude Desktop,
Cursor, or any MCP client. uvx sportsdata-mcp serve and you're done.
You: Which book has the best price on Parramatta v Penrith, and how big is the spread?
Claude queries five books at once and comes back with:
Book | Eels | Panthers |
Betfair | 1.18 | 6.20 |
BetR | 1.17 | 5.00 |
PointsBet | 1.17 | 4.80 |
Pinnacle | 1.17 | 4.78 |
Sportsbet | 1.19 | 4.75 |
Real captured odds. The same bet on Penrith pays $6.20 at Betfair and $4.75 at Sportsbet — a 30% spread on identical risk. That gap is invisible unless something is reading every book at once.
What this one is for: comparing prices, not just fetching scores. Plenty of sports MCP servers will get you fixtures and standings. This one is built around disagreement between books — eleven bookmakers, the Betfair exchange, and two prediction markets (Kalshi, Polymarket) side by side on the same market, plus twenty-seven official league/stats feeds. Deep on AU/NZ books (Sportsbet, TAB, Ladbrokes, PointsBet, BetR, Dabble) and on racing — thoroughbred, greyhound and harness with tote pools and exchange money — which most catalogues skip entirely. Capability tags make providers interchangeable, so "compare odds across books" is one question rather than forty-three integrations.
Is this for you?
Worth being straight about, because it decides whether the first thing you ask works or looks broken.
Best fit — you follow or bet into Australian markets. The cross-book edge above is the reason this exists, and it is built on 159 tools across eight Australian books: Sportsbet, TAB, PointsBet, BetR, Ladbrokes/Neds, Betfair, Dabble, Unibet. Nothing else exposes that, and racing — thoroughbred, greyhound and harness, with tote pools and exchange money — is covered to the same depth.
Also good — you want sport data anywhere in the world. The other 703 tools across 58 providers are not region-locked: MLB, NBA, NFL, NHL, the Premier League, cricket, golf, tennis, F1, UFC, fantasy (ESPN, Sleeper, FPL), plus Pinnacle and the Kalshi and Polymarket prediction markets. 491 of those need no key at all.
Not a fit — you want US sportsbook odds. Those eight books are licensed for Australia and block traffic from outside it. From the US you get Pinnacle, FanDuel, Kalshi and Polymarket for prices; the stats and fantasy side works in full. If cross-book US pricing is what you came for, this is not the tool.
It can now place bets. Read this bit.
Since 0.31.0 the catalogue includes sportsbet_place_bet, tab_place_bet,
entain_place_bet and unibet_place_bet. These stake real money from your own
account, using credentials you supply. Nothing calls them on its own — they are
ordinary tools, so whatever you connect this server to decides when they run.
Two things follow, and neither is optional reading:
An LLM with these tools in scope can place a bet. If that is not what you want, do not enable the account groups; every other group is unaffected, and
list-groupsshows exactly what you have turned on.Only Sportsbet and TAB have been round-tripped against a real account. Unibet and Ladbrokes/Neds have their request shape captured from placements made in a browser, which proves the request and says nothing about whether a stored credential alone is accepted.
The agent workbench applies its own policy on top of this — everything starts in
paper mode and stakes nothing until you opt a book in — but that is the app's
guardrail, not this server's. On its own, this package does what it is asked.
Rather than take that on trust, ask it:
sportsdata-mcp coverageIt probes every provider from your machine and prints what answered, what your location blocks, and what needs a key — so an empty result is never ambiguous between "no data" and "wrong country".
Built on this server
Two live terminals, both open source, both running on nothing but these tools:
sportsdata-ai.com/sports — prediction markets + exchange as a de-vigged sharp line, every book measured against it.

sportsdata-ai.com/board — racing money flow: which runners are firming, fair price vs the field, win%/ROI scorecard.

Try these once it's installed
"Compare head-to-head odds across every book for tonight's NRL games."
"Which AFL games have the biggest price disagreement between bookmakers?"
"What does Betfair imply for the Panthers vs what Sportsbet is offering?"
"Show me Pinnacle's line on every MLB game today."
"Pull the ladder and last five results for Hawthorn."
An MCP server that exposes sports-data APIs (bookmakers, league/governing-body feeds, aggregators) as tools, configurable so you only load the tool groups you need. A capability-tag system makes tools from different providers interchangeable wherever they answer the same question — so the model can compare odds across bookies or stats across data sources with one discovery call.
The catalogue spans bookmakers, league/governing-body feeds, and stats
aggregators, and it keeps growing. New providers are added by dropping a YAML
spec into src/sportsdata_mcp/specs/ — the engine needs no code changes — so
the exact provider and tool counts move over time. Run sportsdata-mcp list-groups for the live inventory, and three meta-tools (group discovery,
capability lookup, resource listing) are always on regardless of what you
enable.
Install
One-liner (any MCP client config, via uv):
uvx sportsdata-mcp serve # or: pip install sportsdata-mcpPrebuilt app (no Python needed): grab the latest
release
(macOS + Windows), unzip, and run sportsdata-mcp setup — it writes the config
for Claude Desktop / Cursor for you. The macOS build is unsigned for now:
right-click → Open the first time.
From source:
git clone https://github.com/DanielTomaro13/sportsdata-mcp.git
cd sportsdata-mcp
pip install -e . # add ".[dev]" for the test + lint toolchainRelated MCP server: Sports Hub MCP Server
Quickstart
sportsdata-mcp version # print version info
sportsdata-mcp list-groups # see every available tool group
sportsdata-mcp lint # validate the packaged specs
sportsdata-mcp doctor # probe enabled groups for reachability + auth
sportsdata-mcp serve # start the MCP stdio server (default command)
sportsdata-mcp update-specs # OTA-refresh provider specs (signed bundle); --clear revertsProvider endpoints drift (e.g. Entain rotates its GraphQL persisted-query hashes).
update-specs fetches a signed spec bundle and applies it into an overlay under
~/.sportsdata/spec-overlay, which the loader prefers over the packaged copy — so a drift
fix doesn't need a whole new app build. The bundle is Ed25519-verified against a baked key
(a product build refuses an unsigned/forged bundle; anti-rollback refuses a stale replay).
Publish one with scripts/publish-spec-bundle.py; point --url / $SPORTSDATA_SPEC_FEED_URL
at the asset. Restart the server after applying.
Enable tool groups with a config file or the SPORTSDATA_MCP_GROUPS env var:
SPORTSDATA_MCP_GROUPS="afl.public.core,sportsbet.racing,entain.graphql" sportsdata-mcp serveSee examples/ for Claude Desktop / Claude Code config snippets,
a worked cross-bookie odds-comparison prompt,
and an NBA shot-chart + box-score walkthrough that
shows the nba_stats_call dispatcher pattern end to end.
Configuration
Config is resolved in this order (first hit wins):
--config <path>flag$SPORTSDATA_MCP_CONFIG./sportsdata-mcp.yaml~/.config/sportsdata-mcp/config.yamlbuilt-in defaults
# sportsdata-mcp.yaml
enabled_groups:
- afl.public.core
- sportsbet.racing
- entain.graphql
providers: # all optional; sensible defaults apply
sportsbet:
request_timeout_seconds: 30
rate_limit_rps: 10 # sustained requests/sec (token bucket)
max_response_bytes: 0 # 0 = no cap (default); set a positive byte count to guard context
secrets: {} # for authenticated providers; prefer env vars in prodA provider whose auth reads env: SOME_VAR is satisfied by the real environment
variable first, then by a secrets: { SOME_VAR: "..." } entry of the same name
(a local-dev convenience — keep real secrets in the environment in production).
Environment variables
Variable | Effect |
| Group selector; overrides |
| Path to a config file (see resolution order above). |
| Global response-size cap in bytes for every provider that doesn't set its own |
| Seconds to cache identical GET responses (default |
| Serve over HTTP instead of stdio (same as |
| Dormant — the product is free; nothing requires a licence. The signed-entitlement machinery remains for anyone self-hosting gated premium feeds (see below). |
| Only relevant with the dormant entitlement gate above. Normally unset. |
The (dormant) entitlement gate
This project used to be a paid product. It's free now — no licence exists or is
needed, and every group serves by default — but the signed-entitlement machinery
(Ed25519-verified feed grants, offline caching, 15-min revalidation) is kept dormant
rather than deleted: it's tested, harmless when unset, and useful to anyone
self-hosting this server who wants to gate premium feeds for their own users. Set
SPORTSDATA_LICENSE + SPORTSDATA_ENTITLEMENT_URL against your own issuing service
to activate it; leave them unset (the default) and nothing changes.
Keyed feeds. A few providers need an upstream credential you supply yourself —
e.g. DATAGOLF_KEY for DataGolf, X_BEARER_TOKEN for Twitter/X. Everything else
needs no key at all.
Meta-tools (list_available_groups, list_tools_by_capability, list_resources)
are always registered regardless of what is enabled, so a fresh install can still
guide the model to turn groups on.
On the response-size cap. There is no cap by default — every tool returns
whatever the upstream API sends. If you want to guard the model's context window you
can opt in to a cap: precedence is providers.<id>.max_response_bytes >
SPORTSDATA_MCP_MAX_BYTES > the default (0, unlimited). Be aware that very large
payloads (e.g. Sportsbet's full *_event_markets firehose, ~2 MB) won't fit in
Claude's ~200 K-token context regardless — for those, prefer a narrower tool such as
sportsbet_sports_card with includeTopMarkets: true.
Tool groups
Run sportsdata-mcp list-groups for live counts and descriptions.
AFL — api.afl.com.au
Group | Tools | Notes |
| 22 | Competitions, seasons, rounds, fixtures, ladders, match stats |
| 9 | Broadcast regions, guides, providers |
| 8 | News/articles, videos, photos |
| 1 | CFS premium ops — needs the anonymous |
| 1 | StatsPro ops — needs the |
| 1 | HLS video URL signing |
Sportsbet — sportsbet.com.au
Group | Tools | Notes |
| 15 | Race meetings, racecards, results, futures, SRMs |
| 14 | Sport events, markets, prices, SGMs |
| 12 | Live status, commentary, ladders, promos, video |
| 2 | Resulted events by date |
| 1 | Persisted GraphQL gateway ( |
Entain / Ladbrokes — ladbrokes.com.au
Group | Tools | Notes |
| 13 | Navigation quick-links and REST surfaces |
| 1 | 127 persisted GraphQL ops ( |
| 1 | Contentful CMS entries (promotions, major-event nav) |
PointsBet — pointsbet.com.au
Group | Tools | Notes |
| 10 | Sports catalogue, competition/event feeds, full event markets, in-play, search |
| 11 | Meetings, racecards, results, futures, SRMs, tips, form |
| 3 | Promotions, promo-code splash, + |
TAB — tab.com.au
Group | Tools | Notes |
| 9 | Dates, meetings, racecards (fixed + parimutuel), form, next-to-go, jackpots, futures |
| 9 | Sports/competitions tree, full match markets + SGM, focused match markets, next-to-go, results, multi-builder |
| 4 | Featured/live recommendations + |
Unibet — unibet.com.au
Group | Tools | Notes |
| 1 |
|
| 3 |
|
BetR — betr.com.au (BlueBet platform)
Group | Tools | Notes |
| 8 | Next-to-jump, today's/grouped racecards, race card, form, fluctuations, movers |
| 7 | Event types, competition categories, event markets, match detail, popular SGMs |
| 4 | Promotions + featured racing + popular market links |
Pinnacle — pinnacle.com (sharp odds)
Group | Tools | Notes |
| 13 | Sports/leagues, full + highlighted + live + per-league matchups, carousel, matchup detail, straight + parlay markets (American-odds prices) |
| 4 | Enums, market-label dictionary, teaser definitions, API status |
Betfair Exchange — betfair.com.au (exchange odds)
Group | Tools | Notes |
| 3 |
|
| 1 |
|
| 5 | Live scores, event details, timeline (single + batch), scores+broadcast |
Dabble — dabble.com.au (iOS app backend)
Group | Tools | Notes |
| 5 | Discover any competition (active list / name lookup / sports), then its fixtures (embedded markets + decimal odds) + the full per-fixture book (400+ markets + Pick'em props) |
The Australian social-betting app's backend, read directly. Reached by posing
as the iOS app — the spec bakes the app's User-Agent + x-device-id +
x-app-version so the public feeds return JSON anonymously. AU-only and
Cloudflare-fronted (403s from non-AU IPs, like the other AU books). Works for
any competition — dabble_active_competitions lists the ~269 currently-bettable
ones across all sports. Read-only odds — no bet placement.
Composes with the other books via sport.event_markets / sport.prices.
SuperCoach — supercoach.com.au (News Corp / Champion Data fantasy)
Group | Tools | Notes |
| 6 | One uniform surface across all 7 games (afl/nrl/epl/nba/nbl/nfl/bbl) × 2 modes ( |
News Corp / Champion Data's salary-cap fantasy game. Every feed lives under
/{year}/api/{sport}/classic/v1/… — pass sport (one of the seven) and year
(the season key: current calendar year for afl/nrl, currently 2025 for the
others, which run across the new year). No auth, not geo-blocked (runs in CI).
The core supercoach_players feed is per-round and large (~1–3 MB); use ppts1
(the real projection), not ppts. Adds the fantasy / projections angle via
stats.fantasy_projections alongside Data Golf. See
documentation/SuperCoach.md.
NBL — nbl.com.au (Australian National Basketball League)
Group | Tools | Notes |
| 16 | Seasons, teams, ladder, schedule (scores), one game's box score and play-by-play, players + rosters, per-player season stats + game-log box scores, team stats, season stat leaders (sortable), and news |
The league's own site data API — a Redis-cached proxy ("rosetta") over Genius
Sports stats at prod.rosetta.nbl.com.au/get/…. No token, but referer-gated
(403s without an nbl.com.au Origin + Referer — both baked into the spec). Every
response is enveloped {type, count, source, data:[…]}. Season-scoped by year
(the season start year: 2026 = NBL27, current); stat-leaders takes the season UUID
from nbl_seasons. Distinct from the SuperCoach nbl fantasy feed — this is the
official box-score source. See documentation/NBL.md.
WTA — wtatennis.com (Women's Tennis Association, official)
Group | Tools | Notes |
| 8 | Official WTA API: singles/doubles rankings, player catalogue + profiles + match history, tournament calendar + per-edition results + entry lists (seeds) |
The WTA's official data API (api.wtatennis.com/tennis/…) — public Spring REST,
no auth/key, no geo-block, runs in CI. Rankings need type+metric
(rankSingles+singles or rankDoubles+doubles); tournaments are keyed by
tournamentGroup.id + year (Australian Open = group 901). Fills the tennis gap on
the stats side, composing with the bookmakers' live tennis markets. See
documentation/WTA.md. (ATP has no equivalent open API —
atptour.com is Cloudflare bot-protected — so it isn't modelled.)
Racing and Sports — racingandsports.com.au
Group | Tools | Notes |
| 3 | Today's race meetings (all codes, verified) + sports match list + per-race odds (token) |
PuntersEdge — puntersedge.online (AU + NZ odds aggregator, demo needs no key)
Group | Tools | Notes |
| 3 | No key — next-to-go racing, best odds + arb flag, one book's prices for one sport |
| 7 | Every book's price per race, best win/place/tote per runner, the card, results, movers, venues, closing-line archive |
| 3 | Sports catalogue, per-book prices by |
An aggregator over the Australian book panel rather than a book itself, not geo-blocked
unlike most of the AU books, with a permanent closing-line archive for CLV and
backtesting work. The demo tools need no key; the rest read PUNTERSEDGE_API_KEY. See
documentation/PuntersEdge.md.
Data Golf — datagolf.com (needs a key)
Group | Tools | Notes |
| 3 | Player list, tour schedule, current event field |
| 11 | DG rankings, pre-tournament (+ archive) + in-play model probabilities, skill + approach-skill ratings, player/live SG decompositions, live strokes-gained, live hole stats, DFS projections |
| 3 | Outright + matchup + all-pairings odds across ~13 books (incl. model line) |
| 9 | Archived raw round data, event-level results (finishes/earnings/points), historical bookmaker odds (outrights + matchups) and DFS results |
Needs a Data Golf API key in the DATAGOLF_KEY env var (a personal subscription
key — sourced via the static_query auth scheme, never stored in the repo).
FanDuel — fanduel.com (US)
Group | Tools | Notes |
| 4 |
|
| 2 |
|
NRL — mc.championdata.com
Group | Tools | Notes |
| 4 | Champion Data match centre: competitions, fixture, per-match player stats, app settings |
Plus the nrl://stats/definitions resource (dictionary of every NRL stat code).
NBA — cdn.nba.com + stats.nba.com
Group | Tools | Notes |
| 5 | Open CDN JSON: today's scoreboard, full schedule, live box score + play-by-play, odds |
| 2 |
|
nba_stats_call fronts the whole stats.nba.com /stats/ analytics surface (player/team
dashboards, box scores v2+v3, shot charts, play-by-play, leaders, standings, draft, hustle,
tracking, …). Browse every operation, its required params and its defaults in the
nba://stats/operations resource.
ESPN — espn.com JSON feeds
Group | Tools | Notes |
| 5 | Site API convenience endpoints: scoreboard, teams, standings, game summary, news |
| 1 |
|
| 1 |
|
| 1 |
|
| 1 |
|
All ESPN tools are parametric over sport + league slugs (e.g. football/nfl,
basketball/nba, soccer/eng.1), so the five groups cover every league ESPN
carries. Browse each dispatcher's operations in its espn://{site,core,web,cdn}/operations
resource.
OpenDota — api.opendota.com (Dota 2 esports, no key)
Group | Tools | Notes |
| 4 | Heroes, hero meta by skill bracket, pro teams, leagues |
| 3 | Pro matches, full match detail, public ladder matches |
| 4 | Profile + rank, match log, win/loss, hero pool |
The catalogue's first esports provider. Sides are Radiant/Dire rather than home/away, and hero stats are paired pick/win counts per skill bracket rather than rates — both documented, both test-pinned. The 4.4 MB pro-player list is deliberately not exposed. See documentation/OpenDota.md.
OpenLigaDB — api.openligadb.de (German football, no key)
Group | Tools | Notes |
| 8 | Bundesliga 1/2/3 + DFB-Pokal: fixtures, results, tables, matchdays |
Fills the big-five hole — you had the Premier League, La Liga and Serie A but no
Bundesliga. Crowd-maintained, so the long tail can lag. Note scores live in
matchResults, which holds both half-time and full-time entries. See
documentation/OpenLigaDB.md.
EuroLeague — api-live.euroleague.net (basketball, no key)
Group | Tools | Notes |
| 7 | EuroLeague + EuroCup: seasons, clubs, rounds, games, box scores |
Completes basketball alongside the NBA and NBL. One letter selects the competition
(E/U), season codes are E2024, home/away are local/road, and box scores carry
PIR rather than an NBA-style efficiency number. See
documentation/EuroLeague.md.
NCAA — ncaa-api.henrygd.me (US college sports, no key)
Group | Tools | Notes |
| 3 | Scoreboards, conference standings, AP/coaches polls across every college sport |
ESPN already gives you college scores; this adds the NCAA's own polls and conference standings in a normalised shape. A third-party mirror of NCAA.com rather than an official feed. See documentation/NCAA.md.
Fantasy Premier League — fantasy.premierleague.com (official, no key)
Group | Tools | Notes |
| 2 | Every player with price, form, ownership, xG/xA; one player in full depth |
| 3 | Clubs with strength ratings, all 38 gameweeks with deadlines, scoring rules |
| 5 | Fixtures with difficulty 1-5, live per-player scoring, dream team, set-piece takers |
| 6 | Any manager's squad, history and picks; classic and H2H leagues; your own team |
The world's most-played fantasy game — 4,085,510 registered squads — and public except for your own squad.
One quirk shapes the whole provider: bootstrap-static is a single 1.37 MB blob whose
player rows alone are ~362,000 tokens, with no server-side field selection. Four tools
hit that one URL and each return one slice, so fpl_players lands at ~58k tokens instead
of being unusable. Nothing is invented or renamed — only removed.
Watch the units: now_cost is tenths of a million (145 = £14.5m), form and the
expected-goals family are strings, and team is FPL's own 1-20 id rather than the
Premier League's. See documentation/FPL.md.
UFC — ufc.com JSON:API (official, no key)
Group | Tools | Notes |
| 3 | Events with per-segment card times and venue, full fight cards, bouts back to UFC 1 |
| 2 | Fighter search and profiles with statistics attached |
| 2 | The FightMetric career statistics table and divisional rankings |
| 2 | Single-round record book, plus the JSON:API resource index |
The obvious source, ufcstats.com, is a dead end — it serves a JavaScript
proof-of-work bot challenge with noindex and zero data rows in the HTML, so reading it
would mean building bot-detection evasion. ufc.com turns out to be better anyway: it runs
Drupal with JSON:API exposed, and athlete_stat carries the same FightMetric dataset,
down to the same fightmetric_id identifiers.
48 statistics per fighter — significant strikes split by position (standing/clinch/ground) and target (head/body/leg), takedowns landed/attempted/accuracy/defence, submission and knockdown averages, strikes landed and absorbed per minute, career records by finish method.
Two traps worth knowing: related records never inline (without include=athlete_stat
a fighter has no statistics at all), and filters silently return 0 rows on the stat
collections rather than erroring — so those parameters are not exposed, and sorting is the
leaderboard mechanism instead. Rate-limited to 0.5 rps because robots.txt asks for
crawl-delay: 15. See documentation/UFC.md.
Football-Data.co.uk — historical results with closing odds (no key)
Group | Tools | Notes |
| 1 | A league season per call: results, shots, cards, and closing prices from ~10 bookmakers, back to the 1990s |
The only source here you can backtest against. Every other football provider tells
you what happened; this one tells you what the market thought would happen, match by
match. Pull a completed season, compare closing prices to results, and you have a CLV
baseline to measure today's live sportsbet/pinnacle/betfair prices against.
Published as CSV — the one provider using the engine's response_format: csv, so the
model still receives ordinary JSON. See
documentation/FootballDataUK.md.
Motorsport beyond F1 — MotoGP, Formula E, NASCAR (no key)
Group | Tools | Notes |
| 6 | MotoGP/Moto2/Moto3/MotoE back to 1949: events, sessions with track conditions, classifications, championships |
| 5 | Formula E from 2014-15: calendar, driver and team championships with per-race points |
| 2 | Cup/Xfinity/Truck: full season summaries and weekend feeds with practice, qualifying and race results |
With openf1 (live telemetry) and jolpicaf1 (history), the motorsport preset now
covers five series. Each has a structural quirk documented in its page — MotoGP needs a
four-level uuid walk, Formula E wraps races but not standings, and NASCAR's results
array is unsorted and includes non-starters at position 0, so results[0] is not
the winner. See MotoGP.md,
FormulaE.md, NASCAR.md.
Jolpica F1 — api.jolpi.ca (F1 history 1950 →, no key)
Group | Tools | Notes |
| 4 | Seasons, drivers, constructors, circuits |
| 1 | Race calendars with per-session times |
| 5 | Race, qualifying and sprint results, lap timings, pit stops |
| 2 | Drivers' and constructors' championships |
The community successor to Ergast, deprecated at the end of 2024. Complements
openf1 rather than overlapping it: OpenF1 is live telemetry from 2023 onward,
Jolpica is every race since 1950. "Who won the 1976 Japanese GP" and "what lap is
Verstappen on" are different providers. Responses use Ergast's double MRData
envelope and return all values as strings — see
documentation/JolpicaF1.md.
Chess — lichess.org + api.chess.com (no key)
Group | Tools | Notes |
| 6 | Per-time-control ratings, leaderboards, user status, daily puzzle, arenas |
| 7 | Profiles, ratings by format, leaderboards, titled players, monthly game archives |
Both major chess platforms. Note that ratings are not comparable across them — different pools and formulas — and only Chess.com serves game history as JSON, because Lichess streams its exports as NDJSON. See Lichess.md and ChessCom.md.
Squiggle — squiggle.com.au (AFL prediction models)
Group | Tools | Notes |
| 6 | 41 independent AFL forecasting models: what each tipped, its confidence and margin, plus actual and projected ladders |
Not another results feed — the market of opinions about AFL games, which is the
natural counterpart to a bookmaker's price. Pull a round's tips, pull the same games
from the books, de-vig the prices, and you're comparing a 41-model consensus against
the market. squiggle_ladder also carries swarms, the simulated finishing-position
distribution behind each projection. One volunteer's server, so the provider ships an
honest contact User-Agent and a deliberately gentle rate limit — see
documentation/Squiggle.md.
NHL — api-web.nhle.com (official web API, no key)
Group | Tools | Notes |
| 3 | Seasons, club rosters by position group, player bio/draft/career |
| 2 | League schedule by week, and a club's full season game log |
| 3 | Live scoreboard, box scores with per-player ice time, scoring summaries |
| 3 | Standings with division/conference/wildcard sequencing, skater and goalie leaders |
The league's own API — the one nhl.com reads (the old statsapi.web.nhl.com is dead).
The espn.* groups already answer "what's the NHL score"; this is the depth layer.
Two conventions worth knowing: season ids are concatenated years (20242025), and
/now paths 307-redirect. See documentation/NHL.md.
Sleeper — api.sleeper.app (fantasy football, fully public)
Group | Tools | Notes |
| 3 | Season/week state, username → user id, platform-wide trending adds/drops |
| 8 | Settings, rosters, managers, weekly matchups, transactions, playoff bracket, traded picks |
| 3 | League drafts, draft settings, and every pick with player names |
The other major fantasy platform, and the easier of the two to reach: Sleeper's read
API needs no key and no cookie — a league id is enough. Joins espnfantasy on the
fantasy.* capabilities, so "show me my league" works across both. The 15 MB player
catalogue is deliberately not exposed; draft picks carry player names instead. See
documentation/Sleeper.md.
ESPN Fantasy — your own fantasy league
Group | Tools | Notes |
| 6 | Games catalogue (resolves the current season + week), season status, pro teams + bye weeks, player universe, scoring presets, player news |
| 14 | Settings, teams, rosters, standings, matchups, draft board, transactions, message board, league history, plus the undocumented |
| 5 | Box scores (lineups with actual and projected points), matchup scores, scoreboard, live scoring, positional ratings |
| 2 | Free-agent / waiver pool with ownership and projections; deep per-player stat splits |
The fantasy platform, not the ESPN scoreboard (that's espn.* above) — one URL per
league whose payload is chosen by a repeatable view param, covering all five games
(ffl football, flb baseball, fba basketball, fhl hockey, wfba WNBA) via a
game param on every tool. Public leagues need no credentials; set
ESPN_FANTASY_COOKIE to espn_s2=…; SWID={…} and the same tools reach your private
leagues. Fantasy playerIds are ESPN athlete ids, so rosters here join straight to the
real-world espn.* feeds. See documentation/ESPNFantasy.md
for the view catalogue, the x-fantasy-filter cookbook and the id decoder tables.
OpenF1 — api.openf1.org (Formula 1, no key)
Group | Tools | Notes |
| 3 | Grand Prix weekends (meetings), sessions (the fixtures feed), driver roster |
| 5 | Session classification, starting grid, drivers'/constructors' championship standings, overtakes |
| 5 | Per-lap sector + speed-trap timing, pit stops, tyre stints, live gaps/intervals, track position |
| 2 | Car telemetry (speed/throttle/brake/gear/RPM/DRS) + (x,y,z) location at ~3.7 Hz |
| 3 | Race-control messages (flags/SC/incidents), team-radio clips, weather |
Free, no-auth public REST surface (auth: none). Scope feeds by session_key /
meeting_key (both accept the literal latest) and driver_number; discover keys
with openf1_sessions / openf1_meetings first.
Cricket Australia — cricket.com.au (no key)
Group | Tools | Notes |
| 7 | Fixtures (the |
| 3 | Full scorecard (innings batting/bowling/wickets), run-graph series, live video streams |
| 2 | Pulselive CMS: video/text/audio/playlist content list + curated playlists |
Two no-auth hosts (apiv2.cricket.com.au/web + the Pulselive CMS). The apiv2
endpoints carry jsconfig=eccn:true by default so they return the documented
camelCase shape; flow is cricketaustralia_fixtures → cricketaustralia_scorecard?fixtureId= →
cricketaustralia_players?playerIds=.
MLB — statsapi.mlb.com (official Stats API, no key)
Group | Tools | Notes |
| 22 | Sports/leagues/divisions/conferences, teams (+ single, affiliates, history, uniforms), rosters, alumni, coaches, personnel, players (profile, batch, search, season catalogue, changes feed), venues, seasons (current + full history) |
| 5 | Games by date / range / team, plus postseason (schedule, series, tune-in) and tied games |
| 10 | Boxscore, linescore, play-by-play, v1.1 |
| 9 | Standings, season stats, one-player stats, league + team leaders, team-season stats, game pace, high/low records |
| 15 | Draft (+ prospects), awards (catalogue + recipients), attendance, transactions, free agents, jobs (umpires/datacasters/scorers), Home Run Derby, All-Star ballots |
| 1 |
|
The official MLB Stats API the MLB-StatsAPI library wraps, read directly (no key) —
comprehensive coverage of the public surface. sportId=1 is MLB; discover ids
with mlb_teams / mlb_schedule / mlb_player_search, then drill into a game or
player. Most tools accept the API's hydrate string to embed related objects in one
call.
Premier League — premierleague.com (no key)
Group | Tools | Notes |
| 7 | Competitions, season structure, awards, the league table, current gameweek, geo |
| 10 | Teams (+ batch), squads, form (single + all-teams), team stats, next fixture, club metadata |
| 8 | Fixtures/results feed + match centre: detail, events, lineups, team stats (~200 Opta metrics), officials, commentary |
| 8 | Player directory, profiles (basic/career/season), batch lookup, season + competition stats, metadata |
| 2 | Player + team stat leaderboards (sort by any Opta metric) |
| 8 | Editorial content/search, latest+popular news/video, broadcasting schedule |
The private JSON APIs that power premierleague.com, read directly (no key,
no cookies) across three hosts (the SDP stats platform, the editorial/
broadcast api.premierleague.com, and static config on resources.premierleague.com).
Underlying data is Opta. Premier League = competition 8; season id is the
starting year (2025 = 2025/26). Flow: pl_teams → pl_matches → a match id →
pl_match/pl_match_stats; pl_standings for the table. Unofficial/undocumented —
respect the ~5 rps rate limit. The SDP wire params (_limit, _sort,
kickoff>/kickoff<) are exposed under clean tool names (limit, sort,
kickoff_after/kickoff_before).
LaLiga — apim.laliga.com (public key shipped)
Group | Tools | Notes |
| 6 | Competitions, season instances (subscriptions), league table, rounds/matchweeks |
| 3 | Season team list, single team, club squad |
| 3 | Every-player season stats (≈749, full Opta metrics), player profile + stats |
| 2 | Matches feed + single-match detail |
The private JSON API behind laliga.com (Azure APIM), read directly. Underlying
data is Opta. A public Ocp-Apim-Subscription-Key is shipped as a
working default, so it runs out of the box — but the key rotates; override it
with LALIGA_SUBSCRIPTION_KEY (env or secrets:) when reads start 401-ing
(re-harvest from laliga.com's __NEXT_DATA__). A "subscription" is a season
instance (slug laliga-easports-2025 = 2025/26); detail endpoints are keyed by
slug. Pairs with the Premier League provider for cross-league football
comparison via the shared stats.ladder / sport.fixtures_by_date /
stats.player_season tags.
Serie A — api-sdp.legaseriea.it (no auth)
Group | Tools | Notes |
| 3 | All competitions, the 41-season catalogue, single-season detail |
| 6 | League table (overall/home/away), the 20 teams, every-player + team Opta stats (paginated), all 380 matches, match lineups |
The public SDP JSON API behind legaseriea.it, read directly (no auth).
Underlying data is Opta. The Serie A competition id is baked in, so you only
ever supply a seasonId (discovered from seriea_seasons; seasonName like
2025/2026). Player stats return identity and ~279 Opta metrics in one call
(no squad endpoint), paginated 30/page with category=General|Goalkeeping.
Completes the big-three football leagues alongside Premier League + La Liga via
the shared stats.ladder / sport.fixtures_by_date / stats.player_season tags.
Kalshi — kalshi.com (prediction markets, no key)
Group | Tools | Notes |
| 6 | Market catalogue + detail, order book, public trades, OHLC candlesticks (single + batch) |
| 9 | Events, series catalogue (by category), single series, milestones, MVE combo collections, entity registry |
| 3 | Exchange status, trading schedule, announcements |
The CFTC-regulated US event-contract exchange. Market data is public — no
key required; optionally set KALSHI_API_KEY_ID + KALSHI_PRIVATE_KEY(_PATH)
and every request is RSA-signed for Kalshi's higher authenticated rate limits
(needs pip install "sportsdata-mcp[kalshi-auth]"). Trading surfaces stay out
of scope (read-only provider). Id chain:
kalshi_series_list(category) → kalshi_events → kalshi_markets →
orderbook/trades/candles by ticker. Prices are dollar-denominated.
Polymarket — polymarket.com (prediction markets, no key, geo-gated)
Group | Tools | Notes |
| 9 | Markets/events/series/sports/tags catalogue + site search (the discovery plane) |
| 6 | Order book, best price, midpoint, spread, price history, CLOB catalogue |
| 2 | Public trade tape + top holders |
The largest crypto prediction market. All read endpoints are anonymous —
the wallet keys Polymarket's SDKs use are for order placement only (out of
scope). ⚠️ Geo-gated: Polymarket drops connections at the network edge
from restricted jurisdictions (verified: AU IPs time out on every host) — run
from an unrestricted region or VPN. Flow: polymarket_events → a market's
clobTokenIds → polymarket_book / polymarket_price_history.
X (Twitter) — api.x.com (needs a Bearer token)
Group | Tools | Notes |
| 7 | 7-day search, volume counts, post lookup (batch + single), quote/repost/like engagement |
| 6 | Profile lookup (handle/id, batch), user timelines, mentions |
| 2 | Trends by location (WOEID) + project usage/cap monitor |
The X API v2 read surface — no anonymous tier, so a Bearer token is
required: env X_BEARER_TOKEN first (an operator can ship a deployment-wide
token for all its users), then the config secrets: block (each user their
own). The env var holds the bare token; the spec adds Bearer . Mind your
tier's monthly read cap (twitter_usage); the spec throttles ~0.5 req/s and
never auto-retries 429s. Write/user-context surfaces (posting, DMs, follows)
are out of scope. Flow: twitter_user_by_username("AFL") → id →
twitter_user_tweets; search with X operators ("Storm" lang:en -is:retweet).
Bring your own key
Eighteen providers need a key you sign up for yourself. They are excluded from the free
preset and from the default group set, so nothing here changes unless you opt in — set
the environment variable and add the group.
Provider | Env var | Tools | What it adds that nothing else here has |
|
| 20 | Ten sports on one key — and the only rugby-union coverage here |
|
| 6 | Odds from ~40 international books, with historical snapshots for CLV work |
|
| 5 | 274 bookmakers across 34 sports, down to padel, bandy and gaelic football |
|
| 7 | Player props with stable market ids you can join across books and time |
|
| 9 | DFS salaries and projections (DraftKings/FanDuel), which no official feed publishes |
|
| 8 | Football lineups, events and per-player stats on a genuinely free tier |
|
| 10 | College-football analytics: SP+, Elo, advanced box scores, historical lines |
|
| 10 | European competitions with no official feed here — UCL, Eredivisie, Championship |
|
| 10 | One consistent shape across NBA, NFL, MLB and EPL |
|
| 8 | Esports beyond Dota 2 — CS2, LoL, Valorant, R6 |
|
| 7 | ATP and ITF draws, H2H and rankings ( |
|
| 8 | International and franchise cricket ( |
|
| 7 | Highlight video across five sports — the only video surface here that isn't single-league |
|
| 5 | US majors on a free non-commercial tier, with clean per-game player logs |
|
| 5 | Asian-handicap odds across Asian books |
|
| 5 | Cricket ball-by-ball commentary (deeper than |
|
| 2 | 30k+ golf courses with per-hole par, yardage and stroke index |
|
| 6 | StartWho, Draft Sharks, CBS Sports and FFToday projections, NFL.com's official injury report and Statcast boards, via Firecrawl Alexandria |
export THE_ODDS_API_KEY=...
sportsdata-mcp serve --groups "free,theoddsapi.*"Two things to know before you rely on these
Their response shapes are documented, not verified. The exception is
firecrawl_alexandria, whose shapes were probed live with a key. We hold no key for the others,
so the shapes in each spec come from the vendor's own documentation rather than from a
live probe. Every one of the others carries an explicit note telling the model to
inspect the payload it actually received rather than trusting the sketch. Elsewhere in
this catalogue the shapes were probed and corrected — roughly one in three turned out to
differ from what the docs implied — so treat this tier as the lower-confidence one until
you have run it with your key. If you do, a PR flipping shapes_verified: true with the
corrections is the single most useful contribution available.
Four of them report failures with HTTP 200. apitennis answers a bad key with
200 {"error":"1", …}, cricketdata with 200 {"status":"failure","reason":"Invalid API Key"}, isportsapi with 200 {"code":2,"message":"Invalid [api_key]…"}, and apisports
returns 200 with a populated errors object and an empty response when you
exhaust the daily quota. That last one is the nastiest: a
model asking for today's fixtures gets an empty list and reports "no matches today", so
a blown quota is indistinguishable from a quiet Tuesday. All four specs declare
error_signals, and the engine raises a real error naming the variable to set. If you
consume these APIs outside this server, check the body — the status code will lie to
you.
Odds-API.io is /v3/, not /v2/. The vendor's own pages advertise v2 paths; every
one of them 404s. Caught by probing before the spec was written — otherwise all five
tools would have shipped broken.
Not included
Three candidates were probed and rejected rather than shipped broken:
SportDevs — as of 2026-08-10 sportdevs.com, api.sportdevs.com and
rugby.sportdevs.com have no DNS record at all. The service is gone, so the
rugby/volleyball/handball coverage it advertised is not available from it. (Rugby union
is instead covered by apisports.)
Live Golf API — use.livegolfapi.com resolves, but every path including the root
returns 404 {"message":"Application not found"}. The host is up; the application
behind it is not deployed.
Fighting Tomatoes — the documented API paths under fightingtomatoes.com/API/…
return the site's 404 page. The domain serves a web app, not the API it advertises.
TheSportsDB's free tier returns silently truncated data — an EPL table comes back with 5 rows of 20, with nothing marking it as partial. A provider that quietly answers with a fifth of the table is worse than no provider, so it is excluded rather than shipped with a warning.
Telemetry
Nothing is transmitted unless you turn it on. There is no default that sends, no first-run prompt that defaults to yes, and consent is readable only from an environment variable — never from a config file, because a config file can be committed to a repo or baked into someone else's Docker image.
What IS always on is local recording, which is yours:
sportsdata-mcp statsPer-tool call counts, error rates, error codes and empty-result counts, worst first. A
model can read the same thing mid-session via sportsdata_session_stats — usually the
fastest way to tell a missing key (100% errors, code AUTH_REQUIRED) from an upstream
with no data (no errors, high empty).
To share it, two deliberate acts are required, and neither alone transmits:
export SPORTSDATA_TELEMETRY=1
export SPORTSDATA_TELEMETRY_ENDPOINT=https://your/collectorTool arguments are never recorded, and that guarantee is structural rather than a
filter: Telemetry.record() has no parameter that could accept them. This matters here
more than in most projects — an ESPN Fantasy league id identifies a league and its
members, and a Sleeper username is a username.
sportsdata-mcp telemetry --show-payloadprints the exact JSON a transmission would contain, so the claims are checkable rather than promised. Full detail, including what the one free-text field does: docs/TELEMETRY.md.
For adoption numbers that touch no user at all — PyPI downloads, unique cloners,
referrers — python scripts/metrics.py reads public data about the package instead.
Cross-provider comparison
Every tool is tagged with provider-agnostic capability slugs (e.g.
sport.event_markets, racing.race_card). Tools sharing a slug answer the same
question and are directly comparable across providers. The discovery flow:
list_tools_by_capability("sport.event_markets")→ every enabled tool exposing itCall each provider's tool concurrently with the resolved event ids
Compare the raw snapshots (schemas are not normalised — the model reconciles them)
See examples/comparator-prompt.md for a full
"compare Storm v Cowboys odds across bookies" walkthrough.
Per-provider notes
Sportsbet — anonymous public APIs; no secrets needed. REST events are keyed by integer
eventId; a persisted-GraphQL gateway is exposed viasportsbet_graphql_call(browsesportsbet://graphql/operations).Entain / Ladbrokes — a persisted-GraphQL gateway; the model supplies an operation name + variables (discover them in
entain://graphql/operations). Hashes can drift when the front-end bundle ships; refresh them withsportsdata-mcp refresh-hashes entain.AFL —
afl.public.*is anonymous.afl.premium.*mints an anonymousx-media-mis-tokenautomatically; some premium endpoints still return 401 for anonymous callers.NRL — the anonymous Champion Data match-centre CDN (
mc.championdata.com), the same static JSON the official nrl.com match centre reads. No secrets, no cache-buster params needed. Resolve acompetitionIdfromnrl_competitions(e.g. 12999 = 2026 NRL Premiership), amatchIdfromnrl_fixture, then pull per-player match stats fromnrl_match; decode stat codes vianrl://stats/definitions.NBA — two surfaces, no secrets.
cdn.nba.comis wide open (it even serves JSON astext/plain, which the client accepts).stats.nba.comsits behind Akamai, which black-holes any request missing a full browser header bundle — the spec ships that bundle inprovider.default_headers, so it just works. Akamai also rate-limits hard, so the spec'sdefaultsblock throttles NBA to ~1 req/2.5 s, sets a 45 s timeout, and retries transient429/5xxwith exponential backoff (all overridable viaproviders.nba.*). The/stats/family is one dispatcher (nba_stats_call): pick anoperation(the path segment, e.g.leaguedashplayerstats) and passquery_params— each operation already carries NBA's full default param set, so you override only what matters. Most responses are column-oriented (resultSets:[{name, headers, rowSet}]}); v3 box scores are nested.ESPN — four public hosts, no auth, no API key:
site.api.espn.com(scores, teams, standings, news, summaries),sports.core.api.espn.com(the canonical$ref-linked model — odds, win-probability, plays, venues, drafts, coaches),site.web.api.espn.com(search + athlete views) andcdn.espn.com(the live core feed, needs?xhr=1). Nearly every URL is.../sports/{sport}/{league}/{resource}, so the tools takesport+leagueas parameters and cover every ESPN league parametrically — NFL, NBA, MLB, NHL, college, soccer (eng.1,esp.1, …), golf, racing, tennis, MMA and more. Discovery:espn_scoreboard(sport, league)→ aneventid →espn_game_summaryor the deepespn_core_call(event_*)ops. The spec throttles to ~5 req/s and retries transient429/5xx(overridable viaproviders.espn.*). Note the core API path usesleagues/{league}(plural); core list responses are lazy{count, items:[{$ref}]}envelopes — follow the refs for detail.PointsBet — anonymous public APIs, no secrets.
api.au.pointsbet.comserves the sportsbook (sports + racing);pointsbet.com.auserves static CMS/nav assets via thepointsbet_content_calldispatcher. Sports discovery:pointsbet_sport_competitions(sportKey)→ a competition key →pointsbet_event(eventKey)for the full market book. Racing:pointsbet_racing_meetings(startDate, endDate)→ araceId→pointsbet_racing_race. Many feeds return a top-level JSON array.TAB (Tabcorp) — anonymous public data, no secrets.
api.beta.tab.com.ausits behind Akamai (the spec ships a browser header bundle + ~2.5 rps throttle, like NBA);cmsapi.tab.com.auserves CMS feeds viatab_cms_call. Every endpoint needs ajurisdiction(defaults toNSW). The API is HATEOAS and name-based — paths embed sport/competition/match/venue names with spaces (…/AFL Football/competitions/AFL/matches/Adelaide v Geelong), which the HTTP layer percent-encodes; pass raw names. Racing:tab_racing_meetings(date)→raceType+venueMnemonic→tab_racing_race. Sports:tab_sport→tab_competition→tab_matchfor the full market book.Unibet — anonymous AU data, no secrets, two surfaces. Racing is persisted-GraphQL (
unibet_racing_call, thegraphql_persisteddispatcher) atrsa.unibet.com.au— race ids areeventKeys like202606040200.T.AUS.hawkesbury.1; the endpoint enforces Apollo CSRF so aContent-Type: application/jsonheader is sent. Sport is the Kambi offering API (unibet_kambi_callover*.kambicdn.com, market AU): group tree, events, bet offers, in-play, bet-builder. Browse ops inunibet://{racing,sport}/operations.BetR — anonymous AU data, no secrets. BetR runs on the BlueBet platform, so the API is
web20-api.bluebet.com.au— a flat REST surface covering racing (next-to-jump, grouped racecards, race cards, form, fluctuations) and sport (event types → categories → markets, SGMs). Thebetr.com.auNext.js_next/data/{buildHash}blobs are skipped (fragile per-deploy hash; the API serves the same data).Racing and Sports —
www.racingandsports.com.auracing/form data, no auth.racingandsports_todays_racing(/todays-racing-json-v2) is the verified feed — today's meetings across thoroughbred/harness/greyhound, by country. The site is behind Cloudflare, which whitelists that feed but JS-challenges the other paths from datacenter IPs (they work from a residential/browser IP); the form/fields/ results are HTML pages, andGetOddsneeds a per-race token, so only the JSON feeds are modelled.Betfair Exchange — anonymous, the open read-only web APIs keyed by the public
_akquery param. The crown jewel isbetfair_market_prices(ero …/bymarket) — exchange back/lay prices, the sharpest reference odds. Discover market ids by walkingbetfair_navigation(scan …/bynode, e.g.EVENT_TYPE:7= Horse Racing) down to MARKET nodes; live scores/details come from theipsin-play service.string_csvid params take a list. (Theapiedsracing widgets are Cloudflare-gated from datacenter IPs and theappsyncGraphQL needs a session, so they're out of scope — racing is covered via navigation→bymarket.)Pinnacle — anonymous, no key. The Arcadia "guest" API (
guest.api.arcadia.pinnacle.com) — the open feed the web sportsbook reads. Sports only (sharp-odds book, no racing); prices are American odds. Flow:pinnacle_sports→pinnacle_sport_matchups(sportId)→pinnacle_matchup_markets(matchupId). The provider sends Pinnacle's public web-clientX-API-Key, which unlocks the full per-sport + per-league matchup lists and the parlay markets.FanDuel (US) — anonymous US data, no secrets, two surfaces under one provider. Racing is the first full-query GraphQL provider:
fanduel_racing_callPOSTs the literal query text (thegraphql_querydispatcher kind, sibling to the persisted-hashgraphql_persisted), with boilerplate variables (brand/product/device/profile) baked as per-opdefault_variables— most calls need none, override only what varies ({results: 12},{trackCode, raceNumber}). Sportsbook is REST (fanduel_sb_call) keyed by the static public_akweb key, region NJ. The two halves need differentOriginheaders, so the sportsbook dispatcher overridesOrigin+x-sportsbook-regionover the racing-origin provider default. Browse ops infanduel://{racing,sportsbook}/operations. (US data — composes with other US sources via capability tags.)
CLI reference
Command | Purpose |
| Start the MCP stdio server (default when no subcommand) |
| Print every group with tool count + description |
| Validate specs against the schema + capability catalogue (nonzero on failure) |
| What works from your location: reachable providers, what your region blocks, what needs a key |
| Per-provider reachability + auth + REST-contract probe (nonzero on failure) |
| Refresh persisted-query hashes from the live front-end bundle ( |
| Print version info |
-v / --verbose enables DEBUG logging (and un-silences httpx/httpcore).
Contributing
See documentation/ADDING_A_PROVIDER.md for
the full guide, with separate playbooks for adding a bookmaker vs a sports website /
data API. In short, adding a provider is a spec-only change in the common case:
Write
src/sportsdata_mcp/specs/<provider>.yaml(copy an existing spec).Tag each tool with capability slugs from
specs/_capabilities.yaml; add a new slug there if none fits (two providers sharing a slug makes them comparable).sportsdata-mcp lint— must pass.sportsdata-mcp doctor(with the new groups enabled) — probes it live.pytest -m "not live"— offline suite; drop the marker filter to run live tests.Add a row to
tests/contract/test_api_contracts.pyso the new provider's documented response shape is verified live on every PR (see below).
pip install -e ".[dev]"
pytest -m "not live" # offline suite (the CI gate)
pytest -m contract # live response-contract checks (see below)
ruff check .CI
Every push/PR runs three jobs (.github/workflows/ci.yml):
test — ruff,
sportsdata-mcp lint, and the offline suite (pytest -m "not live") across Python 3.11–3.13. The deterministic gate.contract —
pytest -m contract: live response-contract checks that hit each upstream API and assert it still returns the documented shape (top-level keys, and the documented keys on list items). It is resilient by design — it skips on anything outside our control (network errors,5xx,401/403/429, geo-blocks, a missingDATAGOLF_KEY, or an empty feed) and only fails on a genuine shape regression or a broken spec (wrong path/params →4xx). Bookmaker APIs that geo-block GitHub's runners simply skip there.package — builds the wheel and proves the CLI loads the packaged specs from a clean install.
Support this project
sportsdata-mcp is free, MIT-licensed, and has no paid tier — every provider and every tool is in the box. Keeping 62 provider specs working against APIs that change without notice is the ongoing cost. If it saves you time, you can chip in at ko-fi.com/danieltomaro.
Entirely optional, and nothing is gated behind it. Starring the repo, filing a good bug report, or adding a provider spec helps just as much.
License
MIT. Copyright (c) 2026 Daniel Tomaro. Free to use, copy, modify and
distribute, with the copyright notice and permission notice retained — see
LICENSE.
mcp-name: io.github.DanielTomaro13/sportsdata-mcp
Available Tools
844 toolsafl_broadcast_channelsARead-onlyIdempotent
List broadcast channels (272) with media types (VIDEO/AUDIO/TEXT).
Returns: {pageInfo, content:[{id, name, abbreviation, broadcaster, channelTypes:[{name, mediaType}]}]}
Auth: none needed.
Inputs: page, pageSize.
afl_broadcasters_listARead-onlyIdempotent
List broadcasters (49: Foxtel, Channel 7, BBC, ESPN, …).
Returns: {pageInfo, content:[{id, name, abbreviation, logo, restrictedCountries}]}
Auth: none needed.
Inputs: pageSize.
afl_broadcast_event_getARead-onlyIdempotent
Get a single broadcast event by id.
Returns: {id, name, startDateTime, channels:[...], contentReference}
Auth: none needed.
Inputs: eventId (required).
afl_broadcast_eventsBRead-onlyIdempotent
Broadcast schedule — one entry per match per channel.
Returns: {pageInfo, content:[{id, name, startDateTime, channels:[...], contentReference:{id, type}}]}
Auth: none needed.
Inputs: round, toDate, fromDate, pageSize, +1 more.
afl_broadcast_match_eventsBRead-onlyIdempotent
Broadcast events scoped to one (compseason, round).
Returns: {pageInfo, content:[{id, name, startDateTime, channels}]}
Auth: none needed.
Inputs: round (required), compseason (required), pageSize.
afl_broadcast_region_getARead-onlyIdempotent
Get a single broadcast region by id.
Returns: {id, name, timezone}
Auth: none needed.
Inputs: regionId (required).
afl_broadcast_regionsARead-onlyIdempotent
List broadcast regions (26) with timezones.
Returns: {pageInfo, content:[{id, name, timezone}]}
Auth: none needed.
Inputs: page, pageSize.
afl_cfs_callARead-onlyIdempotent
Call any of the AFL CFS premium operations (api.afl.com.au/cfs/afl/...). Requires the anonymous x-media-mis-token (minted automatically). Path params use provider IDs (CD_M*/CD_R*/CD_S*/CD_I*/CD_T*) — map integer ids via the idmap endpoints/resources. Read afl://cfs/operations for the full op list.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
afl_club_getARead-onlyIdempotent
Get a single club by id.
Returns: {clubs:[{id, providerId, name}]}
Auth: none needed.
Inputs: clubId (required).
afl_clubs_listARead-onlyIdempotent
List AFL/AFLW clubs (32).
Returns: {clubs:[{id, providerId, name, abbreviation, nickname}]}
Auth: none needed.
Inputs: page, pageSize.
afl_competition_compseasonsARead-onlyIdempotent
List comp seasons within one competition.
Returns: {meta, compSeasons:[...]}
Auth: none needed.
Inputs: competitionId (required), pageSize.
afl_competition_getARead-onlyIdempotent
Get a single competition by integer id.
Returns: {meta, competitions:[{id, providerId, code, name}]}
Auth: none needed.
Inputs: competitionId (required).
afl_competitions_listARead-onlyIdempotent
List all AFL competitions (AFL, AFLW, VFL, SANFL, …).
Returns: {meta:{pagination}, competitions:[{id, providerId, code, name}]}
Example: All 16 competitions {"pageSize": 50}
Auth: none needed.
Inputs: page, pageSize.
afl_compseason_getARead-onlyIdempotent
Get a single comp season (embeds its full rounds array + currentRoundNumber).
Returns: {meta, compSeasons:[{id, providerId, name, shortName, season, rounds:[...], currentRoundNumber}]}
Auth: none needed.
Inputs: compSeasonId (required).
afl_compseasons_listARead-onlyIdempotent
List comp seasons across all competitions (2012–present).
Returns: {meta:{pagination}, compSeasons:[{id, providerId, name, competition, season}]}
Auth: none needed.
Inputs: page, pageSize.
afl_content_photo_getARead-onlyIdempotent
Get a single photo content item by id.
Returns: {id, type:'photo', title}
Auth: none needed.
Inputs: id (required).
afl_content_photo_listARead-onlyIdempotent
List photo content.
Returns: {pageInfo, content:[{id, type:'photo', title, leadMedia}]}
Auth: none needed.
Inputs: limit, offset, tagNames, tagExpression, +1 more.
afl_content_promo_getARead-onlyIdempotent
Get a single promo content item by id.
Returns: {id, type:'promo', title, links:[...]}
Auth: none needed.
Inputs: id (required), limit.
afl_content_promo_listARead-onlyIdempotent
List promo / marketing cards (each embeds a links[] of CTAs).
Returns: {pageInfo, content:[{id, type:'promo', title, links:[{promoUrl, linkText}]}]}
Auth: none needed.
Inputs: limit, tagNames, referenceExpression.
afl_content_text_getARead-onlyIdempotent
Get a single text article by id.
Returns: {id, type:'text', title, body, author, references, tags}
Auth: none needed.
Inputs: id (required).
afl_content_text_listARead-onlyIdempotent
List text articles (news) with reference/tag filters.
Returns: {pageInfo, content:[{id, type:'text', title, date, tags, references, body, author}]}
Example: AFL+AFLW news index {"referenceExpression": "(AFL_COMPETITION:1) or (AFL_COMPETITION:3)", "tagExpression": "("News")", "limit": 17}
Auth: none needed.
Inputs: page, sort, limit, offset, +5 more.
afl_content_video_getARead-onlyIdempotent
Get a single video content item by id.
Returns: {id, type:'video', title, duration, onDemandUrl}
Auth: none needed.
Inputs: id (required).
afl_content_video_listARead-onlyIdempotent
List video content (highlights, replays, press conferences).
Returns: {pageInfo, content:[{id, type:'video', title, duration, onDemandUrl, additionalInfo}]}
Auth: none needed.
Inputs: limit, offset, tagNames, references, +2 more.
afl_keyserver_url_signingARead-onlyIdempotent
Sign an AFL HLS video URL for playback (returns a token-signed CDN URL).
Returns: {signedUrl} (anonymous tokens may return {code: KEYSERVER001, status: 401})
Auth: none needed.
Also answers this: cricketaustralia_streams, entain_video_channels, pointsbet_inplay_streaming.
Inputs: url (required).
afl_ladders_getARead-onlyIdempotent
Competition ladder up to a comp season's current round.
Returns: {compSeason, round, ladders:[{entries:[{position, team, played, thisSeasonRecord}]}]}
Example: 2026 AFL ladder {"compSeasonId": 85}
Auth: none needed.
Inputs: compSeasonId (required).
afl_live_audioARead-onlyIdempotent
Live AFL audio streams (empty when no game is live).
Returns: {pageInfo, content:[{id, name, channels:[...]}]}
Auth: none needed.
Also answers this: openf1_team_radio.
Inputs: round, pageSize, compseason.
afl_live_videoARead-onlyIdempotent
Live AFL video streams (empty when no game is live).
Returns: {pageInfo, content:[{id, name, channels:[{streamUrl, type:'LIVE'}]}]}
Auth: none needed.
Also answers this: cricketaustralia_streams, entain_video_channels, pointsbet_inplay_streaming.
Inputs: round, pageSize, compseason.
afl_matches_idmapARead-onlyIdempotent
Map every match providerId (CD_M*) to its integer id (~48 KB).
Returns: {entityType:'match', idMapResponse:{ids:{'CD_M20260141201':8139, ...}}}
Auth: none needed.
Inputs: no named parameters.
afl_matches_listARead-onlyIdempotent
List matches with filters (competition, season, round, team, status, date).
Returns: {meta:{pagination}, matches:[{id, providerId, round, home, away, venue, utcStartTime, status}]}
Example: Live + upcoming AFL matches from a date {"status": "L,U", "startDate": "", "competitionId": "1"}
Auth: none needed.
Inputs: page, sort, status, teamId, +6 more.
afl_match_getARead-onlyIdempotent
Get a single match by integer id (teams, venue, time, score when started).
Returns: {meta, matches:[{id, providerId, home, away, venue, utcStartTime, status, score?}]}
Auth: none needed.
Inputs: matchId (required).
afl_player_getARead-onlyIdempotent
Get a single player by id (bio, draft, height/weight).
Returns: {players:[{id, providerId, firstName, surname, draftYear, debutYear, recruitedFrom}]}
Auth: none needed.
Inputs: playerId (required).
afl_players_idmapARead-onlyIdempotent
Map every player providerId (CD_I*) to its integer id (~98 KB, 17k+).
Returns: {entityType:'player', idMapResponse:{ids:{...}}}
Auth: none needed.
Inputs: no named parameters.
afl_players_listARead-onlyIdempotent
List players (17k+ all-time catalogue).
Returns: {players:[{id, providerId, firstName, surname, dateOfBirth, draftYear, heightInCm}]}
Auth: none needed.
Inputs: page, pageSize.
afl_rounds_listARead-onlyIdempotent
List rounds for a comp season (incl. byes, start/end times).
Returns: {rounds:[{id, providerId, roundNumber, abbreviation, byes, utcStartTime, utcEndTime}]}
Auth: none needed.
Inputs: compSeasonId (required), pageSize, roundNumber.
afl_season_getARead-onlyIdempotent
Get a single calendar-year season by id.
Returns: {meta, seasons:[{id, year}]}
Auth: none needed.
Inputs: seasonId (required).
afl_seasons_listBRead-onlyIdempotent
List calendar-year season records.
Returns: {meta, seasons:[{id, year}]}
Auth: none needed.
Inputs: page, pageSize.
afl_statspro_callARead-onlyIdempotent
Call any of the AFL StatsPro operations (api.afl.com.au/statspro/...). Requires the anonymous x-media-mis-token (minted automatically). Path params use provider IDs (CD_S*/CD_R*/CD_I*). Read afl://statspro/operations for the list.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
afl_team_getARead-onlyIdempotent
Get a single team by id (incl. social/home-venue metadata).
Returns: {teams:[{id, providerId, name, club, teamType, metadata}]}
Auth: none needed.
Inputs: teamId (required).
afl_teams_idmapARead-onlyIdempotent
Map CD_T* team providerIds to integer aflapi ids (and vice versa).
Returns: {entityType:'team', idMapResponse:{ids:{'CD_T10':1, ...}}}
Auth: none needed.
Inputs: no named parameters.
afl_teams_listARead-onlyIdempotent
List teams (150 incl. AFL men, AFLW, state leagues, historical).
Returns: {teams:[{id, providerId, name, abbreviation, nickname, club, teamType, metadata}]}
Auth: none needed.
Inputs: page, pageSize.
afl_venue_getARead-onlyIdempotent
Get a single venue by id.
Returns: {venues:[{id, providerId, name, location, state, timezone}]}
Auth: none needed.
Inputs: venueId (required).
afl_venues_listARead-onlyIdempotent
List venues (191) incl. location, state, timezone, landOwner.
Returns: {venues:[{id, providerId, name, location, state, timezone, landOwner}]}
Auth: none needed.
Inputs: page, pageSize.
apisports_baseball_gamesARead-onlyIdempotent
Baseball games (MLB, NPB, KBO and others) by date or league.
Returns: {response:[{id, date, status, league, teams, scores:{home:{hits, errors, innings:{'1','2',…, extra}, total}, away:{…}}}]} — SHAPE FROM VENDOR DOCS. Innings are keyed by NUMBER-AS-STRING. For MLB itself, the keyless official mlb provider is deeper.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": "2024-07-04"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apisports_basketball_gamesARead-onlyIdempotent
Basketball games worldwide (NBA, EuroLeague, NBL and many more) by date or league.
Returns: {response:[{id, date, status:{long, short}, league:{id, name, season}, teams:{home, away}, scores:{home:{quarter_1, quarter_2, quarter_3, quarter_4, over_time, total}, away:{…}}}]} — SHAPE FROM VENDOR DOCS. Note season is a '2023-2024' STRING here; the football host uses an integer year.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": "2024-01-15"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season, +1 more.
apisports_basketball_standingsARead-onlyIdempotent
Basketball standings for a league and season.
Returns: {response:[[{position, team, league, group:{name}, games:{played, win:{total, percentage}, lose:{…}}, points:{for, against}, form}]]} — SHAPE FROM VENDOR DOCS. Double-nested like football's.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A league table {"league": 12, "season": "2023-2024"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: league (required), season (required), team.
apisports_football_fixturesARead-onlyIdempotent
Football fixtures and results by date, league or team. Give at least one filter.
Returns: {results, response:[{fixture:{id, date, timestamp, venue:{name, city}, status:{long, short, elapsed}}, league:{id, name, country, season, round}, teams:{home:{id, name, winner}, away:{…}}, goals:{home, away}, score:{halftime, fulltime, extratime, penalty}}]} — SHAPE FROM VENDOR DOCS. goals is the 90-minute score; score.penalty decides a shootout, so a cup tie needs both.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's fixtures {"date": "2024-08-17"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: id, date, last, next, +5 more.
apisports_football_fixture_statisticsARead-onlyIdempotent
Team match statistics for one fixture — shots, possession, corners, and expected goals where covered.
Returns: {response:[{team:{id, name}, statistics:[{type:'Shots on Goal'|'Ball Possession'|'expected_goals'|…, value}]}]} — SHAPE FROM VENDOR DOCS. NOTE this is LONG format keyed by a HUMAN-READABLE type string, and value is sometimes a string with a percent sign ('54%'). Do not assume a numeric type.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One fixture's team stats {"fixture": 1035037}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: fixture (required), team.
apisports_football_h2hARead-onlyIdempotent
Every past meeting between two clubs.
Returns: {response:[{fixture, league, teams, goals, score}]} — same fixture shape as apisports_football_fixtures. SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Two clubs' history {"h2h": "33-34", "last": 10}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: h2h (required), last, league.
apisports_football_leaguesARead-onlyIdempotent
Football leagues and cups worldwide, with the seasons available on your plan.
Returns: {response:[{league:{id, name, type:'League'|'Cup', logo}, country:{name, code, flag}, seasons:[{year, start, end, current, coverage:{fixtures:{events, lineups, statistics_fixtures}, standings, players, odds, predictions}}]}]} — SHAPE FROM VENDOR DOCS. coverage matters: it tells you which of the tools below will actually return anything for that league.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: English competitions {"country": "England"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: id, season, country, current.
apisports_football_oddsARead-onlyIdempotent
Pre-match odds from many bookmakers for a fixture or league.
Returns: {response:[{fixture, league, update, bookmakers:[{id, name, bets:[{id, name:'Match Winner', values:[{value:'Home', odd:'1.85'}]}]}]}]} — SHAPE FROM VENDOR DOCS. ODDS ARE STRINGS, not numbers. For AU markets the direct providers here (sportsbet, tab, pointsbet) are deeper and live.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One fixture's odds {"fixture": 1035037}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: bet, page, league, season, +2 more.
apisports_football_playersARead-onlyIdempotent
Player season statistics for a team or league. season is required.
Returns: {paging:{current, total}, response:[{player:{id, name, age, nationality, height, weight, injured, photo}, statistics:[{team, league, games:{appearences, lineups, minutes, position, rating}, goals:{total, assists, conceded, saves}, shots, passes, tackles, duels, dribbles, fouls, cards, penalty}]}]} — SHAPE FROM VENDOR DOCS. statistics is a LIST — one entry per competition — so a player in a league and a cup has two.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A club's squad statistics {"team": 42, "season": 2023}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: season (required), id, page, team, +2 more.
apisports_football_predictionsARead-onlyIdempotent
The vendor's own model prediction for a fixture, with the comparison data behind it.
Returns: {response:[{predictions:{winner:{id, name, comment}, win_or_draw, under_over, goals:{home, away}, advice, percent:{home, draw, away}}, league, teams, comparison:{form, att, def, poisson_distribution, h2h, goals, total}, h2h:[…]}]} — SHAPE FROM VENDOR DOCS. percent values are STRINGS with a % sign. This is a vendor model, not a market price: compare it against squiggle-style model output, not against a bookmaker's line.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A fixture's prediction {"fixture": 1035037}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: fixture (required).
apisports_football_standingsARead-onlyIdempotent
League table. Both league and season are required.
Returns: {response:[{league:{id, name, standings:[[{rank, team:{id, name}, points, goalsDiff, group, form, status, description, all:{played, win, draw, lose, goals:{for, against}}, home:{…}, away:{…}}]]}}]} — SHAPE FROM VENDOR DOCS. NOTE the DOUBLE nesting: standings is a list OF TABLES (one per group in a group stage), each a list of rows.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Premier League table {"league": 39, "season": 2023}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: league (required), season (required), team.
apisports_football_teamsARead-onlyIdempotent
Clubs, by league/season, country, or name search.
Returns: {response:[{team:{id, name, code, country, founded, national, logo}, venue:{id, name, address, city, capacity, surface}}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Search a club {"search": "Arsenal"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: id, league, search, season, +1 more.
apisports_formula1_racesARead-onlyIdempotent
Formula 1 races and sessions for a season.
Returns: {response:[{id, competition:{id, name, location}, circuit:{id, name}, season, type, laps:{current, total}, distance, timezone, date, status}]} — SHAPE FROM VENDOR DOCS. jolpicaf1 (keyless) covers F1 history back to 1950 and openf1 (keyless) covers live telemetry — prefer those unless you need this one key to span sports.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A season's races {"season": 2023}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: next, type, season, competition.
apisports_handball_gamesARead-onlyIdempotent
Handball games (EHF Champions League, Bundesliga, LNH and others) by date or league.
Returns: {response:[{id, date, time, status, league, teams, scores:{home, away}, periods:{first, second}}]} — SHAPE FROM VENDOR DOCS. Handball scores run to 25-35 per side; a value under 10 usually means the match is still in the first half, not a low-scoring game.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": ""}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apisports_hockey_gamesARead-onlyIdempotent
Ice-hockey games (NHL, KHL, SHL and others) by date or league.
Returns: {response:[{id, date, status, league, teams, scores:{home, away}, periods:{first, second, third, overtime, penalties}}]} — SHAPE FROM VENDOR DOCS. For the NHL itself the keyless official nhl provider is deeper and live.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": "2024-01-15"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apisports_mma_fightsARead-onlyIdempotent
MMA fights (UFC and others) by date or season.
Returns: {response:[{id, date, slug, category, status, is_main, fighters:{first:{id, name, winner}, second:{…}}}]} — SHAPE FROM VENDOR DOCS. winner is null until the fight is resulted, and BOTH may be false on a draw or no-contest — do not infer the loser from one flag.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A card {"date": "2024-03-09"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: id, date, season, category.
apisports_nfl_gamesARead-onlyIdempotent
American-football games (NFL, NCAA) by date, season or team.
Returns: {response:[{game:{id, stage, week, date:{date, time, timezone}, status}, league, teams, scores:{home:{quarter_1,…, total}, away:{…}}}]} — SHAPE FROM VENDOR DOCS. NOTE this host wraps the identity under game, unlike the basketball and hockey hosts.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week of NFL {"league": 1, "season": 2023}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apisports_rugby_gamesARead-onlyIdempotent
Rugby games (Six Nations, Super Rugby, NRL, Premiership) by date or league. The catalogue's only rugby-union coverage.
Returns: {response:[{id, date, time, status, league, teams, scores:{home, away}, periods:{first, second, overtime}}]} — SHAPE FROM VENDOR DOCS. For the NRL specifically, the keyless nrl provider is official and deeper.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": "2024-03-09"}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apisports_statusARead-onlyIdempotent
Your subscription and how much of today's quota is left. Costs no quota — call it first when something returns empty.
Returns: {response:{account:{firstname, lastname, email}, subscription:{plan, end, active}, requests:{current, limit_day}}} — SHAPE FROM VENDOR DOCS. requests.current vs limit_day is the check worth making before blaming the data.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Quota check
Auth: needs your own key in API_SPORTS_KEY.
Inputs: no named parameters.
apisports_volleyball_gamesARead-onlyIdempotent
Volleyball games (Italian SuperLega, Polish PlusLiga, CEV and others) by date or league.
Returns: {response:[{id, date, status, league, teams, scores:{home, away}, periods:{first, second, third, fourth, fifth}}]} — SHAPE FROM VENDOR DOCS. scores is SETS WON (best of 5), not points; the per-set point totals are in periods. Reading scores as points is the usual mistake.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": ""}
Auth: needs your own key in API_SPORTS_KEY.
Inputs: date, team, league, season.
apitennis_eventsARead-onlyIdempotent
Event types the API covers (ATP singles, WTA doubles, ITF, …).
Returns: {success:1, result:[{event_type_key, event_type_type:'Atp Singles'}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Event types {"method": "get_events"}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: method.
apitennis_fixturesARead-onlyIdempotent
Matches in a date range, with scores and set-by-set detail once played.
Returns: {success:1, result:[{event_key, event_date, event_time, event_first_player, first_player_key, event_second_player, second_player_key, event_final_result:'2 - 0', event_status, tournament_name, tournament_round, scores:[{score_first, score_second, score_set}], pointbypoint:[…]}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's matches {"method": "get_fixtures", "date_start": "2025-01-20", "date_stop": "2025-01-20"}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: date_stop (required), date_start (required), method, player_key, +2 more.
apitennis_h2hARead-onlyIdempotent
Head-to-head history between two players, plus each one's recent form.
Returns: {success:1, result:{H2H:[{event_key, event_date, event_first_player, event_second_player, event_final_result, tournament_name}], firstPlayerResults:[…], secondPlayerResults:[…]}} — SHAPE FROM VENDOR DOCS. Note result here is an OBJECT, not a list like the other methods.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Two players' H2H {"method": "get_H2H", "first_player_key": 1905, "second_player_key": 1903}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: first_player_key (required), second_player_key (required), method.
apitennis_livescoreARead-onlyIdempotent
Matches in progress right now, with live scores.
Returns: {success:1, result:[{event_key, event_first_player, event_second_player, event_game_result, event_serve, event_status, scores:[…]}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Live matches {"method": "get_livescore"}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: method, event_type_key.
apitennis_playersARead-onlyIdempotent
One player's profile and recent results.
Returns: {success:1, result:[{player_key, player_name, player_country, player_bday, player_logo, stats:[{season, type, rank, titles, matches_won, matches_lost, hard_won, clay_won, grass_won}]}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One player {"method": "get_players", "player_key": 1905}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: player_key (required), method.
apitennis_standingsARead-onlyIdempotent
ATP or WTA rankings.
Returns: {success:1, result:[{place, player, player_key, league, movement, country, points}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: ATP rankings {"method": "get_standings", "event_type": "ATP"}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: method, event_type.
apitennis_tournamentsARead-onlyIdempotent
Tournaments, optionally for one event type.
Returns: {success:1, result:[{tournament_key, tournament_name, event_type_key, event_type_type}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All tournaments {"method": "get_tournaments"}
Auth: needs your own key in API_TENNIS_KEY.
Inputs: method, event_type_key.
balldontlie_epl_gamesARead-onlyIdempotent
Premier League fixtures and results.
Returns: {data:[{id, week, kickoff, home_team, away_team, home_score, away_score, status, ground}], meta:{next_cursor}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A season's fixtures {"season": 2023}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: week, cursor, season, per_page, +1 more.
balldontlie_epl_teamsARead-onlyIdempotent
Premier League clubs for a season.
Returns: {data:[{id, name, short_name, abbr, city, stadium}]} — SHAPE FROM VENDOR DOCS. The keyless official premierleague provider is deeper for the EPL.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: EPL clubs {"season": 2023}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: season.
balldontlie_mlb_gamesARead-onlyIdempotent
MLB games by date, season or team. (For MLB alone, the keyless official mlb provider is far deeper.)
Returns: {data:[{id, date, season, postseason, home_team_score, away_team_score, home_team, away_team, venue, status}], meta:{next_cursor}} — SHAPE FROM VENDOR DOCS. NOTE: away_team here, but visitor_team on the NBA and NFL paths. The shape is NOT uniform across sports.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One date's games {"dates": ["2024-07-04"]}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: dates, cursor, seasons, per_page, +1 more.
balldontlie_nba_gamesARead-onlyIdempotent
NBA games by date, season or team.
Returns: {data:[{id, date, season, status, period, time, postseason, home_team_score, visitor_team_score, home_team:{…}, visitor_team:{…}}], meta:{next_cursor}} — SHAPE FROM VENDOR DOCS. Note the away side is visitor_team, not away_team.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One date's games {"dates": ["2024-01-15"]}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: dates, cursor, seasons, per_page, +2 more.
balldontlie_nba_playersARead-onlyIdempotent
NBA players, searchable by name.
Returns: {data:[{id, first_name, last_name, position, height, weight, jersey_number, college, country, draft_year, draft_round, draft_number, team:{…}}], meta:{next_cursor, per_page}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Search a player {"search": "curry"}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: cursor, search, per_page, team_ids.
balldontlie_nba_season_averagesARead-onlyIdempotent
Season averages for specific NBA players.
Returns: {data:[{player_id, season, games_played, min, pts, reb, ast, stl, blk, turnover, fg_pct, fg3_pct, ft_pct}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A player's season {"season": 2023, "player_ids": ["115"]}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: season (required), player_ids (required).
balldontlie_nba_standingsARead-onlyIdempotent
NBA standings for a season.
Returns: {data:[{team:{…}, conference_record, conference_rank, division_record, division_rank, wins, losses, home_record, road_record, season}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A season's standings {"season": 2023}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: season (required).
balldontlie_nba_statsARead-onlyIdempotent
Per-player, per-game NBA box-score lines.
Returns: {data:[{id, min:'34:12', fgm, fga, fg_pct, fg3m, fg3a, ftm, fta, oreb, dreb, reb, ast, stl, blk, turnover, pf, pts, player:{…}, team:{…}, game:{…}}], meta:{next_cursor}} — SHAPE FROM VENDOR DOCS. min is a 'MM:SS' STRING, not a number.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A player's game lines {"player_ids": ["115"], "seasons": ["2023"]}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: dates, cursor, seasons, game_ids, +2 more.
balldontlie_nba_teamsARead-onlyIdempotent
All 30 NBA franchises with conference and division.
Returns: {data:[{id, conference, division, city, name, full_name, abbreviation}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every NBA team
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: no named parameters.
balldontlie_nfl_gamesARead-onlyIdempotent
NFL games by season, week or team.
Returns: {data:[{id, visitor_team_score, home_team_score, season, postseason, status, date, week, home_team, visitor_team}], meta:{next_cursor}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A season's games {"seasons": ["2023"]}
Auth: needs your own key in BALLDONTLIE_API_KEY.
Inputs: weeks, cursor, seasons, per_page, +2 more.
betfair_cashoutBRead-onlyIdempotent
Cash-out availability for one or more markets.
Returns: [{marketId, cashout, partial}] (top-level array)
Auth: none needed.
Inputs: marketIds (required), _ak, alt.
betfair_event_detailsBRead-onlyIdempotent
In-play event details (event name, competition, primary market, runners, start time) for one or more events.
Returns: [{eventId, eventTypeId, marketId, marketName, eventName, competitionName, numberOfRunners, countryCode, startTime}] (top-level array)
Auth: none needed.
Inputs: eventIds (required), _ak, alt, locale, +1 more.
betfair_event_timelineARead-onlyIdempotent
Live timeline + running score/state for one in-play event.
Returns: {eventId, eventTypeId, score:{home:{name, score, numberOfYellowCards, ...}, away:{...}}, timeElapsed, ...}
Auth: none needed.
Inputs: eventId (required), _ak, alt, locale, +2 more.
betfair_event_timelinesARead-onlyIdempotent
Live timelines + running scores for several in-play events at once (batch).
Returns: [{eventId, eventTypeId, score:{home:{name, score, halfTimeScore, fullTimeScore}, away:{...}}}] (top-level array)
Auth: none needed.
Inputs: eventIds (required), _ak, alt, locale.
betfair_market_pricesBRead-onlyIdempotent
Exchange back/lay prices + state for one or more markets (the core odds feed).
Returns: {currencyCode, eventTypes:[{eventTypeId, eventNodes:[{eventId, event:{eventName, countryCode, openDate}, marketNodes:[{marketId, state:{inplay, status}, description, runners:[{...prices: back/lay}]}]}]}]}
Example: Price two markets {"marketIds": "1.258654642,1.258653584"}
Auth: none needed.
Inputs: marketIds (required), _ak, alt, types, +4 more.
betfair_markets_by_eventARead-onlyIdempotent
Market STRUCTURE for an event (market ids, names, runners) — probed live 2026-07-06: this route STRIPS exchange prices (runners come back without the exchange block) and 400s on multi-id batches. For prices, feed the market ids into betfair_market_prices; for bulk market-id discovery, betfair_navigation with attachments=MENU,EVENT,MARKET returns 1000+ MARKET nodes per event type in one call.
Returns: {currencyCode, eventTypes:[{eventNodes:[{eventId, event:{eventName}, marketNodes:[{marketId, description:{marketType}, state, runners:[{...prices}]}]}]}]}
Auth: none needed.
Inputs: eventIds (required), _ak, alt, types, +4 more.
betfair_scoresARead-onlyIdempotent
Live scores for one or more in-play events (per-sport score detail).
Returns: [{eventId, eventTypeId, score:{home:{name, score, ...}, away:{...}}}] (top-level array)
Auth: none needed.
Inputs: eventIds (required), _ak, alt, locale.
betfair_scores_broadcastARead-onlyIdempotent
Live scores plus broadcast/streaming availability for one or more events.
Returns: [{eventId, startTime, state:{score:{...}}, broadcast:{...}}] (top-level array)
Auth: none needed.
Inputs: eventIds (required), _ak, alt, locale, +1 more.
betr_all_promotionsARead-onlyIdempotent
All visible promotions (name, description, dates).
Returns: {Promotions:[{Id, PromotionId, Name, Description, PromotionStartDate}]}
Auth: none needed.
Inputs: no named parameters.
betr_event_typesARead-onlyIdempotent
All event types (sports + racing) with event counts and SGM availability.
Returns: {Items:[{EventTypeId, EventTypeDesc, EventCount, HasSameGameMulti, MasterEventTypeId}]}
Auth: none needed.
Inputs: no named parameters.
betr_fav4ARead-onlyIdempotent
Featured 'Fav 4' upcoming races for a race-type filter.
Returns: {Items:[{EventId, MasterEventId, Venue, RaceNumber, BettingCloseTimeUtc, TimeToJump}]}
Auth: none needed.
Inputs: EventTypeFilter.
betr_featured_racingARead-onlyIdempotent
Editorially featured racing events (carousel order, promo titles).
Returns: {ContentfulFeaturedEvent:[{EventOrder, EventID, EventName, PromotionTitle}]}
Auth: none needed.
Inputs: no named parameters.
betr_grouped_racecardARead-onlyIdempotent
All meetings + their races for a day offset, grouped by code.
Returns: {Thoroughbred:[[{EventId, Venue, CountryCode, RaceNumber, AdvertisedStartTime, HasFixedMarkets}]], Greyhounds:[...], Trots:[...]}
Example: Today's meetings {"DaysToRace": 0}
Auth: none needed.
Inputs: DaysToRace.
betr_market_moversARead-onlyIdempotent
Racing market movers — runners whose fixed prices are shortening/drifting.
Returns: {Items:[{EventId, EventName, Venue, RaceNumber, SecondsToJump, AdvertisedStartTime}]}
Auth: none needed.
Inputs: no named parameters.
betr_master_categoryARead-onlyIdempotent
Master categories (competitions) for one event type, optionally with levelled markets.
Returns: {EventTypeDesc, EventTypeId, MasterCategories:[{MasterCategoryId, MasterCategory, Categories:[{CategoryId, CategoryName}]}]}
Example: Basketball competitions {"EventTypeId": 107}
Auth: none needed.
Inputs: EventTypeId (required), EventClassCode, WithLevelledMarkets.
betr_master_eventARead-onlyIdempotent
One sport match's markets by master event id — a market GROUP per call (Events[].Outcomes[] with prices; GroupLinks names the other groups: totals, lines, race-to, periods).
Returns: {MasterEvent:{MasterEventId, MasterEventName, CategoryId, MinAdvertisedStartTime, IsLive, IsOpenForBetting}, Events:[{EventId, EventName, Outcomes:[{OutcomeName, Price, MarketTypeCode, MarketDesc, Points}]}], GroupLinks:[{GroupTypeCode, GroupName}]}
Auth: none needed.
Inputs: MasterEventId (required), GroupTypeCode.
betr_next5_racesARead-onlyIdempotent
Next races about to jump, with time-to-jump, for a race-type + country filter.
Returns: {Items:[{Race:{EventId, Venue, RaceNo, AdvertisedStartTime, StateCode}, TimeToJump, SecondsToJump, EventType}]}
Auth: none needed.
Inputs: CountryFilter, EventTypeFilter.
betr_pop_sgm_bet_dataARead-onlyIdempotent
Popular Same Game Multi suggestions for one master event.
Returns: {PopSGMBetItems:[{legs:[{selectionName, price}], price}]}
Auth: none needed.
Inputs: MasterEventId (required), SortOrder, CategoryId.
betr_pop_sgm_categoryARead-onlyIdempotent
Categories that currently have Popular Same Game Multis.
Returns: {PopSGMCategoryItems:[{EventTypeId, MasterCategoryName, CategoryId, CategoryName}]}
Auth: none needed.
Inputs: no named parameters.
betr_popular_market_linksARead-onlyIdempotent
Popular market quick-links (specials, featured competitions) for navigation.
Returns: {Items:[{PopularMarketName, EventTypeId, EventType, MasterEventId, CategoryId}]}
Auth: none needed.
Inputs: no named parameters.
betr_promotionsARead-onlyIdempotent
Active promotions with metadata (title, end date, linked master events).
Returns: {MetaData:[{PromotionId, Title, PromotionEndDate, MasterEventId:[...]}]}
Auth: none needed.
Inputs: no named parameters.
betr_raceARead-onlyIdempotent
Full racecard for one race: runners, prices, allowed bet types, results once run.
Returns: {EventId, EventName, AllowedWinBetTypes:[{MarketTypeCode, DividendTypeCode}], ...runners + prices}
Auth: none needed.
Inputs: eventId (required).
betr_race_flucsARead-onlyIdempotent
Price fluctuation history per runner for one race (fixed-odds movements).
Returns: {Items:[{OutcomeId, Flucs:[{Offset, Price}]}]}
Auth: none needed.
Inputs: EventId (required).
betr_race_formARead-onlyIdempotent
Detailed form guide for one race (runner history, comments, ratings).
Returns: {RaceFormV2:{RaceNo, RaceName, NumberOfRunners, Distance, Course, RaceComment, Runners:[...]}}
Auth: none needed.
Also answers this: pointsbet_racing_form, tab_racing_race_form.
Inputs: EventId (required), RequestingRace.
betr_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it two or more selections from one BetR match, get the correlation-adjusted combined price. Prices combinations BetR has not pre-built (for the ones it has, see betr_pop_sgm_bet_data).
Returns: {Price: 2.2, ErrorNo: 0} — that is the WHOLE body on success; there is no echo of the legs. VERIFIED live 2026-08-27 against AFL Western Bulldogs v Collingwood (MasterEventId 2255977), unauthenticated.
THE PRICE IS NOT THE PRODUCT OF THE LEGS. Measured on that fixture, BetR's adjustment ran from -9.7% to +4.9% and went BOTH ways: Bulldogs (1.95) with Under 139.5 (6.25) priced 11.00 against a naive 12.19, while the same 1.95 with Under 201.5 (1.10) priced 2.25 against a naive 2.145. Never multiply the legs.
DO NOT SEND FixedWin. The site does, and the server treats the value you send as a FLOOR on the answer: send 99.0 on any leg and the response is {Price: 99.0, ErrorNo: 0} — a fabricated quote reported as a clean success. Omitting it returned the true price in every case tested, so the field is pure downside.
BETR REFUSES A REDUNDANT LEG INSTEAD OF DROPPING IT (ErrorNo 4527), which is the safe behaviour and the opposite of TAB's and PointsBet's — you cannot end up holding a shorter bet than you asked for. But 4527 IS A CATCH-ALL and its wording names only one of its three causes: a leg that another leg implies, the SAME leg twice, and legs from DIFFERENT matches all come back as 'redundant leg in bet'.
Other codes seen live: 4500 = fewer than two legs (unlike Sportsbet and PointsBet, BetR will not price a single one), 4526 = impossible combination (Over 139.5 with Under 139.5), 4503 = a leg could not be resolved, usually a missing EventId or OutcomeId. All arrive as HTTP 200; the engine raises them rather than passing Price: 0 off as a quote.
Example: Price Bulldogs to win with over 139.5 total points {"MasterEventID": 2255977, "Markets": [{"EventId": 91686300, "OutcomeId": 1, "MarketType": "WIN"}, {"EventId": 91712212, "OutcomeId": 13910, "MarketType": "WIN"}]}
Auth: none needed.
Inputs: Markets (required), MasterEventID.
betr_sports_categoryARead-onlyIdempotent
Events + markets for one sport category (competition).
Returns: {EventTypeDesc, EventTypeId, MasterCategories:[{Categories:[{CategoryId, CategoryName, Events:[...]}]}]}
Auth: none needed.
Inputs: CategoryId (required).
betr_statwars_eventsARead-onlyIdempotent
Statwars master events (head-to-head stats promo events).
Returns: {Items:[{EventTypeId, EventTypeDesc, MasterEventId, MasterEventName, MinAdvertisedStart}]}
Auth: none needed.
Inputs: no named parameters.
betr_todays_racesARead-onlyIdempotent
Today's races grouped by code (Thoroughbred / Greyhound / Harness), for the homepage.
Returns: {Throughbred:[{VenueId, Venue, Race1:{EventId, RaceNumber, AdvertisedStartTime, SecondsToJump}}], Greyhound:[...], Harness:[...]}
Auth: none needed.
Inputs: CountryFilter.
cfbd_advanced_box_scoreARead-onlyIdempotent
Advanced box score for one game: success rate, explosiveness, PPA and field position.
Returns: {gameId, teams:{ppa:[…], cumulativePpa:[…], successRates:[…], explosiveness:[…], rushing:[…], havoc:[…], scoringOpportunities:[…], fieldPosition:[…]}} — SHAPE FROM VENDOR DOCS. PPA is CFBD's expected-points-added metric.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One game's advanced box {"id": 401520165}
Auth: needs your own key in CFBD_API_KEY.
Inputs: id (required).
cfbd_betting_linesARead-onlyIdempotent
Historical betting lines per game from multiple books — spread, over/under and moneyline. The college-football backtesting dataset.
Returns: [{id, season, week, homeTeam, homeScore, awayTeam, awayScore, lines:[{provider:'consensus'|'Bovada'|…, spread, formattedSpread, spreadOpen, overUnder, overUnderOpen, homeMoneyline, awayMoneyline}]}] — SHAPE FROM VENDOR DOCS. lines is per BOOK; *Open vs the closing value is what a CLV comparison uses.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 week 1 lines {"year": 2024, "week": 1}
Auth: needs your own key in CFBD_API_KEY.
Inputs: team, week, year, seasonType.
cfbd_gamesARead-onlyIdempotent
Games for a season with scores, venue and attendance. year is required.
Returns: [{id, season, week, season_type, start_date, neutral_site, conference_game, venue, home_team, home_points, home_line_scores:[…], away_team, away_points, excitement_index, home_post_win_prob}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 week 1 {"year": 2024, "week": 1}
Auth: needs your own key in CFBD_API_KEY.
Inputs: year (required), team, week, conference, +1 more.
cfbd_portalARead-onlyIdempotent
Transfer-portal moves for a season — origin, destination and rating.
Returns: [{season, firstName, lastName, position, origin, destination, transferDate, rating, stars, eligibility}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 portal {"year": 2024}
Auth: needs your own key in CFBD_API_KEY.
Inputs: year (required).
cfbd_rankingsARead-onlyIdempotent
Weekly poll rankings (AP, Coaches, Playoff Committee).
Returns: [{season, seasonType, week, polls:[{poll:'AP Top 25', ranks:[{rank, school, conference, firstPlaceVotes, points}]}]}] — SHAPE FROM VENDOR DOCS. Note polls are NESTED inside each week entry.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 week 10 polls {"year": 2024, "week": 10}
Auth: needs your own key in CFBD_API_KEY.
Inputs: year (required), week, seasonType.
cfbd_ratings_eloARead-onlyIdempotent
Elo ratings by team and week.
Returns: [{year, team, conference, elo}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 Elo {"year": 2024}
Auth: needs your own key in CFBD_API_KEY.
Inputs: team, week, year, conference.
cfbd_ratings_spARead-onlyIdempotent
SP+ ratings — the headline predictive rating for college football, split by offence and defence.
Returns: [{year, team, conference, rating, ranking, offense:{ranking, rating, success, explosiveness}, defense:{…}, specialTeams:{rating}}] — SHAPE FROM VENDOR DOCS. Defensive ratings are better when LOWER.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 SP+ {"year": 2024}
Auth: needs your own key in CFBD_API_KEY.
Inputs: team, year.
cfbd_recruitingARead-onlyIdempotent
Recruiting classes: individual commits with stars, ratings and positions.
Returns: [{id, athleteId, recruitType, year, ranking, name, school, committedTo, position, height, weight, stars, rating, city, stateProvince, hometownInfo}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 recruits {"year": 2024}
Auth: needs your own key in CFBD_API_KEY.
Inputs: team, year, state, position.
cfbd_teamsARead-onlyIdempotent
FBS/FCS programmes with conference, venue and colours.
Returns: [{id, school, mascot, abbreviation, conference, division, color, alt_color, logos:[url], location:{venue_id, name, city, state, capacity, grass, dome}}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: SEC programmes {"conference": "SEC"}
Auth: needs your own key in CFBD_API_KEY.
Inputs: year, conference.
cfbd_team_season_statsARead-onlyIdempotent
Season totals per team across every tracked stat category.
Returns: [{season, team, conference, statName, statValue}] — SHAPE FROM VENDOR DOCS. NOTE this is LONG format: one row PER STAT per team, not one row per team.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: 2024 team stats {"year": 2024}
Auth: needs your own key in CFBD_API_KEY.
Inputs: year (required), team, conference.
chesscom_archivesARead-onlyIdempotent
The list of monthly game archives available for a player — call this before asking for a month's games.
Returns: {archives:[url]} — URLs ending /games/YYYY/MM; take the year and month from the last entry to fetch the most recent games
Example: Which months a player has games for {"username": "hikaru"}
Auth: none needed.
Inputs: username (required).
chesscom_clubARead-onlyIdempotent
A Chess.com club: description, membership count, admins and average rating.
Returns: {'@id', name, club_id, country, average_daily_rating, members_count, created, last_activity, admin:[url], description, url}
Example: The developer community club {"club_id": "chess-com-developer-community"}
Auth: none needed.
Inputs: club_id (required).
chesscom_leaderboardsARead-onlyIdempotent
Chess.com's leaderboards for every category — live blitz/bullet/rapid, daily, variants and tactics. LARGE (~290 KB).
Returns: {live_blitz:[{player_id, username, score, rank, title, country}], live_bullet:[…], live_rapid:[…], daily:[…], daily960:[…], tactics:[…], battle:[…]} — one array per category
Example: All leaderboards
Auth: none needed.
Inputs: no named parameters.
chesscom_monthly_gamesARead-onlyIdempotent
Every game a player finished in one month, with PGN, result, ratings and opening ECO.
Returns: {games:[{url, pgn, time_control, time_class, rules, end_time, rated, eco, white:{username, rating, result}, black:{…}}]} — end_time is UNIX SECONDS; a prolific player's month can be several MB
Example: One player-month {"username": "hikaru", "year": "2025", "month": "01"}
Auth: none needed.
Inputs: year (required), month (required), username (required).
chesscom_playerARead-onlyIdempotent
A Chess.com player's profile: name, title, country, league, followers and status.
Returns: {player_id, '@id', url, username, name, title, followers, country, location, joined, last_online, status, league, avatar} — joined/last_online are UNIX SECONDS; country is a URL, not a code
Example: One player's profile {"username": "hikaru"}
Auth: none needed.
Inputs: username (required).
chesscom_player_statsARead-onlyIdempotent
A player's ratings and records per game type — blitz, bullet, rapid, daily, plus tactics and puzzle rush.
Returns: {chess_blitz:{last:{rating, date, rd}, best:{rating, date, game}, record:{win, loss, draw}}, chess_bullet:{…}, chess_rapid:{…}, chess_daily:{…}, tactics:{highest, lowest}, puzzle_rush:{best}, fide} — a key is ABSENT if the player has never played that format
Example: Ratings across formats {"username": "hikaru"}
Auth: none needed.
Inputs: username (required).
chesscom_titled_playersARead-onlyIdempotent
Every player holding a given FIDE title — usernames only.
Returns: {players:[username]} — a flat list of USERNAME STRINGS, not objects; feed one to chesscom_player for detail
Example: All grandmasters {"title": "GM"}
Auth: none needed.
Inputs: title.
cricketaustralia_competitionsARead-onlyIdempotent
Competition catalogue — series / tournaments with id, name, dates and artwork.
Returns: {competitions:[{id, name, url, imageUrl, startDateTime, endDateTime, order}], responseError}
Auth: none needed.
Inputs: format, jsconfig.
cricketaustralia_contentARead-onlyIdempotent
Pulselive CMS content list by type — VIDEO (highlights/replays), TEXT (articles), AUDIO, or PLAYLIST (curated collections). Paginated.
Returns: {pageInfo:{page, pageSize, numPages, numEntries}, content:[{id, type, title, description, date, ...}]}
Auth: none needed.
Inputs: contentType (required), page, detail, pageSize, +1 more.
cricketaustralia_fixturesARead-onlyIdempotent
Match list (the /matches feed) — fixtures with teams, venue, competition, status, toss and result. Filter by competition, completed/live, etc.
Returns: {fixtures:[{id, name, startDateTime, gameType, isLive, isCompleted, resultText, competitionId, venueId, homeTeamId, awayTeamId, tossResult, tossDecision}], responseError}
Auth: none needed.
Inputs: year, limit, format, isLive, +4 more.
cricketaustralia_playersARead-onlyIdempotent
Player profiles for a batch of player ids — name, DOB, birthplace, batting/bowling hand + type, height, image. Pass a list of playerIds.
Returns: {players:[{id, displayName, firstName, lastName, dob, birthPlace, battingHand, bowlingHand, bowlingType, height, imageUrl}], responseError}
Auth: none needed.
Inputs: playerIds (required), format, jsconfig.
cricketaustralia_playlistARead-onlyIdempotent
A single Pulselive playlist by id — a curated collection of videos (e.g. a match's highlights playlist).
Returns: {id, type, title, description, date, content:[{id, type, title, ...}]}
Auth: none needed.
Inputs: playlistId (required), detail, pageSize.
cricketaustralia_runs_graphARead-onlyIdempotent
Run-progression (worm/manhattan) data per innings for a fixture — the series behind cricket.com.au's run graphs.
Returns: {innings:[{inningNumber, battingTeamId, bowlingTeamId, overs, overnightRuns, overnightWickets, byesRuns, legByesRuns, noBalls}]}
Auth: none needed.
Inputs: fixtureId (required), format, jsconfig.
cricketaustralia_scorecardARead-onlyIdempotent
Full match scorecard — per-innings batting, bowling and fall-of-wickets, plus the players[] lookup for the fixture.
Returns: {fixture:{id, name, innings:[{inningNumber, battingTeamId, bowlingTeamId, batsmen:[...], bowlers:[...], wickets:[...]}]}, fixtureTitle, players:[{id, displayName}], dataSupport, responseError}
Auth: none needed.
Inputs: fixtureId (required), format, jsconfig, competitionId.
cricketaustralia_standingsARead-onlyIdempotent
Competition ladder — per-team played/won/lost/drawn/tied/no-result, points, net run rate. Needs competitionId (empty for competitions without a points table).
Returns: {standings:[{competitionId, teamId, groupName, played, won, lost, drawn, matchTied, noResult, points, netRunRate, deductions}], responseError}
Auth: none needed.
Inputs: competitionId (required), format, jsconfig.
cricketaustralia_streamsARead-onlyIdempotent
Live video stream entries for a fixture (populated during live matches; empty array otherwise).
Returns: {streams:[{...stream urls/metadata}], responseError} (streams empty when the match isn't live)
Auth: none needed.
Inputs: fixtureId (required), jsconfig.
cricketaustralia_teamsARead-onlyIdempotent
Team catalogue — id, name, short name, colours, logo/badge URLs across all CA competitions.
Returns: {teams:[{id, name, shortName, teamColor, logoUrl, teambadgeImageUrl, isActive}], responseError}
Auth: none needed.
Inputs: format, jsconfig.
cricketaustralia_toursARead-onlyIdempotent
Tours / series with status flags — each tour groups its competitions and is flagged upcoming / in-progress / completed. The feed behind the site's series navigation.
Returns: {tours:[{competitionId, name, startDateTime, endDateTime, isUpComing, isInProgress, isCompleted, competitions:[...], bannerUrl, logoUrl}]}
Auth: none needed.
Inputs: format, jsconfig.
cricketaustralia_venueARead-onlyIdempotent
Venue detail for one venueId — name, city, country, state, coordinates. Resolve a fixture's venueId (one venue per call).
Returns: {venue:{id, name, city, state, countryName, latitude, longitude}, responseError}
Auth: none needed.
Inputs: venueId (required), format, jsconfig.
cricketdata_current_matchesARead-onlyIdempotent
Matches in progress or starting soon, with live scores.
Returns: {status:'success', data:[{id, name, matchType:'t20'|'odi'|'test', status, venue, date, dateTimeGMT, teams:[str], teamInfo:[{name, shortname, img}], score:[{r, w, o, inning}], series_id, matchStarted, matchEnded}], info:{hitsToday, hitsLimit}} — SHAPE FROM VENDOR DOCS. Score fields are terse: r runs, w wickets, o overs.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Live and upcoming matches
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: offset.
cricketdata_matchesARead-onlyIdempotent
All matches, paginated — recent and upcoming across every series.
Returns: {status, data:[{id, name, matchType, status, venue, date, teams, teamInfo, series_id, matchStarted, matchEnded}], info:{hitsToday, hitsLimit}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Recent matches
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: offset.
cricketdata_match_infoARead-onlyIdempotent
One match: toss, venue, teams and result.
Returns: {status, data:{id, name, matchType, status, venue, date, dateTimeGMT, teams, teamInfo, score:[{r, w, o, inning}], tossWinner, tossChoice, matchWinner, matchStarted, matchEnded}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One match {"id": ""}
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: id (required).
cricketdata_player_infoARead-onlyIdempotent
One player's profile and career batting/bowling statistics.
Returns: {status, data:{id, name, dateOfBirth, role, battingStyle, bowlingStyle, placeOfBirth, country, playerImg, stats:[{fn:'batting'|'bowling', matchtype:'test'|'odi'|'t20i', stat:'m'|'runs'|'avg', value}]}} — SHAPE FROM VENDOR DOCS. NOTE stats is LONG format: one row per (function, format, statistic), not a nested object.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One player's career {"id": ""}
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: id (required).
cricketdata_playersARead-onlyIdempotent
Search the player catalogue by name.
Returns: {status, data:[{id, name, country}], info:{hitsToday, hitsLimit}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Search players {"search": "Kohli"}
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: offset, search.
cricketdata_scorecardARead-onlyIdempotent
Full scorecard: batting and bowling figures per innings.
Returns: {status, data:{id, name, scorecard:[{inning, batting:[{batsman:{id, name}, r, b, '4s', '6s', sr, 'dismissal-text'}], bowling:[{bowler:{id, name}, o, m, r, w, eco}], extras, totals}]}} — SHAPE FROM VENDOR DOCS. Cricket abbreviations: r runs, b balls, sr strike rate, o overs, m maidens, w wickets, eco economy.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One match's scorecard {"id": ""}
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: id (required).
cricketdata_seriesARead-onlyIdempotent
Series (tours and tournaments) with their match counts and dates.
Returns: {status, data:[{id, name, startDate, endDate, odi, t20, test, squads, matches}], info:{hitsToday, hitsLimit}} — SHAPE FROM VENDOR DOCS. The format counts (odi/t20/test) are how many matches of each type the series holds.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All series
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: offset, search.
cricketdata_series_infoARead-onlyIdempotent
One series with its full match list.
Returns: {status, data:{info:{id, name, startdate, enddate, odi, t20, test, squads, matches}, matchList:[{id, name, matchType, status, venue, date, teams}]}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One series {"id": ""}
Auth: needs your own key in CRICKETDATA_API_KEY.
Inputs: id (required).
dabble_active_competitionsARead-onlyIdempotent
Every currently-bettable competition across all sports (~318) — the discovery entry point. Pick any one's id and pass it to dabble_competition_fixtures. Each carries name, sportName, country and a featured flag. Pass sportId to filter to one sport's active competitions.
Returns: {status, data:{activeCompetitions:[{id, name, sportName, country, featured, location, sportId}]}}
Auth: none needed.
Inputs: sportId.
dabble_competition_fixturesARead-onlyIdempotent
All fixtures for ONE competition, each embedding its markets + prices (decimal odds) + selections + teams. Get the competitionId from dabble_active_competitions / dabble_competitions (AFL Matches = ad4c78ec-e39d-45ee-8cec-ff5d485a3205, NRL = c709772d-d5d0-4252-af89-be8a163706dc). For the FULL book of one fixture use dabble_fixture_details.
Returns: {data:[{id, name, displayName, competitionId, competitionName, advertisedStart, status, inplayAvailable, teams:[{id, name, abbreviation}], markets:[{id, name, resultingType, product, isHandicap, isTotal, isSgmAllowed, status}], selections:[{id, name, marketId, isScratched}], prices:[{marketId, selectionId, price}]}]} (product is engine-derived from resultingType — see dabble_fixture_details.)
Example: AFL fixtures with markets + odds {"competitionId": "ad4c78ec-e39d-45ee-8cec-ff5d485a3205"}
Auth: none needed.
Inputs: competitionId (required), exclude, includeInPlay.
dabble_competitionsARead-onlyIdempotent
Look up competitions by EXACT name (name, case-sensitive; e.g. 'NRL', 'Premier League', 'AFL Matches' — note 'AFL' alone returns nothing) OR list EVERY competition for a sport (sportId, including ones not currently active — ~20 for AFL). Pass at least one filter: bare /competitions is the ~38 MB / 142k-row firehose (deliberately avoid). For browsing currently-bettable comps, prefer dabble_active_competitions.
Returns: {status, data:[{id, name, sportId, country}]} (filtered by name or sportId — empty if the exact name isn't found)
Auth: none needed.
Inputs: name, sportId.
dabble_fixture_detailsARead-onlyIdempotent
The FULL book for one fixture — every market (hundreds), all selections + prices, the marketGroups (SGM grouping) and the Pick'em playerProps product. LARGE (~1 MB+ for a major match); fetch one fixture at a time. fixtureId comes from dabble_competition_fixtures. Each market gets an engine-derived product: SGM legs by Dabble's capability flags (isSgmAllowed && !isSingleAllowed) so it's robust to the SGM vendor (SportCast today) changing; Pick'em by the pickem token (e.g. odds_on_pickem_goals) and racing by the Racing* resultingType — both first-party naming. RACING resultingTypes: RacingFixed*/RacingSP*=win/place, RacingDD*=exotics, RacingSrm*=Same-Race-Multi (no Pick'em in racing).
Returns: {sportFixtureDetail:{id, name, competitionName, sportName, status, teams, markets:[{id, name, resultingType, product, isSgmAllowed, isSingleAllowed}], selections:[{id, name, marketId}], prices:[{marketId, selectionId, price}], marketGroups, marketGroupMappings, playerProps:[{playerName, stats, value, lineType}]}} (LARGE — markets/selections/prices number in the hundreds-to-thousands. Each market carries an engine-derived product ∈ {single, sgm, pickem, srm, racing}: RacingSrm*→srm, Racing*→racing, resultingType-contains-pickem→pickem, else isSingleAllowed→single, else isSgmAllowed→sgm, else→single. Use product ∈ {single, sgm} for like-for-like price comparison; NEVER blend pickem multipliers into fixed-odds value/arb.)
Auth: none needed.
Inputs: fixtureId (required).
dabble_sportsARead-onlyIdempotent
The 24 sports Dabble offers (Rugby League, Australian Rules, Football, Basketball, Cricket, Tennis, Horse Racing, …), each with id + name. Join sportId from a competition back to its sport here.
Returns: {status, data:[{id, name, isRacing, isHidden}]}
Auth: none needed.
Inputs: no named parameters.
datagolf_approach_skillARead-onlyIdempotent
Detailed approach-play skill per player across yardage/lie buckets — SG per shot, proximity, GIR, good-shot and poor-shot-avoidance rates.
Returns: {last_updated, time_period, data:[{dg_id, player_name, ...per-bucket sg/proximity/gir fields}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: period, file_format.
datagolf_fantasy_projectionsARead-onlyIdempotent
DFS fantasy-points projections + salaries/ownership for a site + slate.
Returns: {event_name, last_updated, projections:[{dg_id, player_name, proj_points, salary, proj_ownership}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: site, tour, slate, file_format.
datagolf_field_updatesARead-onlyIdempotent
Current event field — players entered, tee times, withdrawals, current round.
Returns: {event_name, event_id, course_name, current_round, date_start, date_end, field:[{dg_id, player_name, ...tee times}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_hist_dfs_event_listARead-onlyIdempotent
List of historical events with DFS salary/ownership/points data for a site.
Returns: [{event_id, event_name, calendar_year, date, dk_salaries, dk_ownerships}] (top-level array)
Auth: needs your own key in DATAGOLF_KEY.
Inputs: site, file_format.
datagolf_hist_dfs_pointsARead-onlyIdempotent
Historical DFS points + salary + ownership per player for a past event.
Returns: {event_id, event_name, event_completed, season, dfs_points:[{dg_id, player_name, fin_text, finish_pts, total_pts, salary, ownership}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: year (required), event_id (required), site, tour, +1 more.
datagolf_hist_event_listARead-onlyIdempotent
List of historical events that have raw round-level data available (event_id + year to pass to the rounds feed).
Returns: [{event_id, event_name, tour, calendar_year, date, sg_categories}] (top-level array)
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, year, file_format.
datagolf_hist_matchupsARead-onlyIdempotent
Historical matchup / 3-ball odds for a past event from one sportsbook.
Returns: {book, event_id, event_name, event_completed, matchups:[{p1_player_name, p2_player_name, open_odds, close_odds, ...}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: year (required), event_id (required), book, tour, +2 more.
datagolf_hist_odds_event_listARead-onlyIdempotent
List of historical events that have archived bookmaker odds available.
Returns: [{event_id, event_name, calendar_year, archived_preds, ...}] (top-level array)
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_hist_outrightsARead-onlyIdempotent
Historical opening/closing outright odds for a past event from one sportsbook.
Returns: {book, event_id, event_name, event_completed, outrights:[{dg_id, player_name, open_odds, close_odds, ...}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: year (required), event_id (required), book, tour, +3 more.
datagolf_hist_resultsARead-onlyIdempotent
Historical event-level results for a past tournament — finish position, earnings, FedExCup points and DG Points per player.
Returns: {event_id, event_name, year, season, event_completed, event_stats:[{dg_id, player_name, fin_text, earnings, fec_points, dg_points}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: year (required), event_id (required), tour, file_format.
datagolf_hist_results_event_listARead-onlyIdempotent
List of tournaments with historical event-level results data (finishes/earnings/points) — the id lookup for datagolf_hist_results.
Returns: [{event_id, event_name, calendar_year, date}] (top-level array)
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_hist_roundsARead-onlyIdempotent
Historical round-by-round scoring + strokes-gained for every player in a past event.
Returns: {event_id, event_name, event_completed, scores:[{dg_id, player_name, fin_text, rounds:[{round_num, score, sg_total, sg_putt, ...}]}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: year (required), event_id (required), tour, file_format.
datagolf_in_playARead-onlyIdempotent
Live (in-play) model predictions during a tournament — current position/score + updated win probabilities.
Returns: {data:[{dg_id, player_name, current_pos, current_score, R1, R2, R3, R4, make_cut, win, ...}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format, odds_format.
datagolf_live_hole_statsARead-onlyIdempotent
Live per-hole scoring distributions for the in-progress event (avg score, birdie/bogey rates by hole, AM/PM wave).
Returns: {courses:[{course_code, course_key, rounds:[{round_num, holes:[{hole, par, avg_score, afternoon_wave:{...}, morning_wave:{...}}]}]}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_live_strokes_gainedARead-onlyIdempotent
Live strokes-gained breakdown for every player during PGA Tour events (raw, or relative to the model's pre-round expectations).
Returns: {event_name, current_round, last_update, strokes_gained_values, data:[{dg_id, player_name, pos, score, thru, today, R1:{...sg}, R2, R3, R4}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: sg, file_format.
datagolf_live_tournament_statsARead-onlyIdempotent
Live per-player tournament stats (strokes-gained by category, accuracy, etc.) for the requested round.
Returns: {event_name, course_name, last_updated, live_stats:[{dg_id, player_name, sg_total, sg_ott, sg_app, ...}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: round, stats, display, file_format.
datagolf_matchupsBRead-onlyIdempotent
Tournament / round / 3-ball matchup odds across sportsbooks, plus Data Golf's model line.
Returns: {event_name, market, last_updated, match_list:[{p1_player_name, p2_player_name, odds:{datagolf, bet365, pinnacle, ...}}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, market, file_format, odds_format.
datagolf_matchups_all_pairingsARead-onlyIdempotent
All possible tournament matchup pairings for the current event with Data Golf's model odds (every player-vs-player price).
Returns: {event_name, last_update, pairings:[{p1_player_name, p2_player_name, p3_player_name, ...model odds}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format, odds_format.
datagolf_outrightsARead-onlyIdempotent
Outright (win / top-N / make-cut) odds for the current event across ~13 sportsbooks, plus Data Golf's model line.
Returns: {event_name, last_updated, books_offering:[...], odds:[{dg_id, player_name, datagolf:{...}, bet365, pinnacle, draftkings, fanduel, ...}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, market, file_format, odds_format.
datagolf_player_decompositionsARead-onlyIdempotent
Per-player skill decomposition for the current event — how each skill (driving, approach, putting, course-fit) contributes to the prediction.
Returns: {event_name, course_name, players:[{dg_id, player_name, ...skill/course-fit components}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_player_listARead-onlyIdempotent
Full player list with Data Golf ids (dg_id), name, country, amateur flag.
Returns: [{dg_id, player_name, country, country_code, amateur}] (top-level array)
Auth: needs your own key in DATAGOLF_KEY.
Inputs: file_format.
datagolf_pre_tournamentCRead-onlyIdempotent
Pre-tournament model predictions — win / top-5/10/20 / make-cut probabilities per player.
Returns: {baseline:[{dg_id, player_name, win, top_5, top_10, top_20, make_cut}], baseline_history_fit:[...]}
Auth: needs your own key in DATAGOLF_KEY.
Also answers this: apisports_football_predictions, squiggle_tips, squiggle_ladder.
Inputs: tour, file_format, odds_format, add_position.
datagolf_pre_tournament_archiveCRead-onlyIdempotent
Archived pre-tournament predictions for a past event (what the model said beforehand).
Returns: {baseline:[{dg_id, player_name, fin_text, win, make_cut, first_round_leader, top_10}]}
Auth: needs your own key in DATAGOLF_KEY.
Also answers this: apisports_football_predictions, squiggle_tips, squiggle_ladder.
Inputs: tour, year, event_id, file_format, +1 more.
datagolf_rankingsARead-onlyIdempotent
Data Golf player rankings (top ~500) with skill estimate and OWGR rank.
Returns: {last_updated, rankings:[{datagolf_rank, owgr_rank, dg_id, player_name, dg_skill_estimate, country}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: file_format.
datagolf_scheduleARead-onlyIdempotent
Tour schedule — the season's events with dates, courses and locations.
Returns: {schedule:[{event_id, event_name, course, course_key, location, country, latitude, longitude, start_date}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: tour, file_format.
datagolf_skill_ratingsARead-onlyIdempotent
Player skill ratings — strokes-gained components (off-tee, approach, around-green, putting) + driving acc/dist.
Returns: {last_updated, players:[{dg_id, player_name, sg_total, sg_ott, sg_app, sg_arg, sg_putt, driving_acc, driving_dist}]}
Auth: needs your own key in DATAGOLF_KEY.
Inputs: display, file_format.
entain_cms_entriesARead-onlyIdempotent
Contentful CMS entries (promotions, major-event nav) via the www CDN proxy.
Returns: {sys, total, skip, limit, items:[{sys, fields}], includes:{}}
Example: Active promotions {"content_type": "promotions", "limit": 20}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: skip, limit, order, include, +1 more.
entain_event_market_rulesARead-onlyIdempotent
Settlement rules for every named market, indexed by rule id.
Returns: {market_rules:{<rule_id>:{id, name, description}}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
entain_event_market_type_group_mapsARead-onlyIdempotent
Join table between market types and market-type groups (dedup by pair).
Returns: {market_type_group_map:[{market_type_id, market_type_group_id, priority}]}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: category_id (required).
entain_event_market_type_groupsARead-onlyIdempotent
Market-tab group definitions for a sport category (lower priority renders first).
Returns: {market_type_group:[{id, category_id, name, priority, type}]}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: category_id (required).
entain_featured_sliderARead-onlyIdempotent
Featured slider events (homepage hero carousel).
Returns: {items:[{id, title, url, event_id, event:{competition_id, event_start}}]}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
entain_graphql_callARead-onlyIdempotent
Call any of Entain's 127 persisted GraphQL operations against
api.ladbrokes.com.au/gql/router by name + variables. Hashes are managed
server-side; a PERSISTED_QUERY_NOT_FOUND (gateway APQ-cache eviction) is
self-healed automatically by re-POSTing the stored query document. If it
still surfaces, run sportsdata-mcp refresh-hashes entain. GraphQL IDs are
type-prefixed (RacingRace:, SportingEvent:): variable type
ID! wants the prefixed form, UUID! wants the bare uuid. Read
entain://graphql/operations for the full op list + variable signatures.
Returns: (JSON object)
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: operation (required), variables.
entain_metadata_by_urlARead-onlyIdempotent
SEO metadata (page title) for a given URL path.
Returns: {metadata:{title, url}} (empty {} when no override)
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: url (required).
entain_quicklinks_listARead-onlyIdempotent
Navigation quick-links (racing/sports nav tiles).
Returns: {quick_links:[{id, root_category_id, category_id, url, title, icon, priority}]}
Example: Racing quick-links {"filter": {"type": "Racing"}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: filter (required).
entain_racing_future_marketsARead-onlyIdempotent
Legacy v1 racing RPC selector (future-markets races feed).
Returns: {status, data:{races:{<race_id>:{name, advertised_start:{seconds}}}}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: method, exclude.
entain_racing_meetingARead-onlyIdempotent
All race meetings + races for one date (normalised UUID-keyed tables).
Returns: {compounds, domestic_countries, meetings:{}, races:{}, venues:{}}
Example: Melbourne card for a given day {"date": "", "timezone": "Australia/Melbourne"}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), timezone (required).
entain_racing_next_racesARead-onlyIdempotent
Next races about to jump, grouped per racing category.
Returns: {category_race_map:{}, race_summaries:{<race_id>:{race_name, meeting_name, advertised_start, race_form}}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: count (required), categories (required).
entain_racing_racecardARead-onlyIdempotent
Full priced racecard for one race — entrants, fixed-odds fluctuations, form.
Returns: {status, data:{races:{}, markets:{}, prices:{}, entrants:{}, price_fluctuations:{<entrant_id>:[floats — LAST is the live fixed win price]}, meetings:{}}}
Example: One priced racecard {"id": "7f553143-1ed4-4ef8-a622-46c7563e6c83"}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: id (required), method.
entain_racing_searchARead-onlyIdempotent
Racing search facets (barrier/country/jockey/trainer buckets); optional full-text.
Returns: {facets:{barrier:{buckets}, country:{buckets}, jockey:{buckets}, trainer:{buckets}}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: q, category_ids.
entain_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it selections from one Entain (Ladbrokes/Neds) event, get the correlation-adjusted combined price. Prices combinations the book has not pre-built (for those, see entain_graphql_call SportingEventPopularSameGameMultis). Several events can be priced in one call.
Returns: {prices:{:{available: true, odds:{numerator: 27, denominator: 10}}}} — keyed by event id, one entry per event you asked about. VERIFIED live 2026-08-27 against AFL Melbourne v Carlton (event eccdc4f5-e01e-4aca-afab-570869b53702), unauthenticated.
ODDS ARE FRACTIONAL AND DECIMAL = numerator/denominator + 1. 27/10 is 3.70 — not 2.7, and not 27. Confirmed against the site's own displayed prices on the same event: Melbourne showed 2.15 and returns 23/20, Over showed 1.88 and returns 22/25. Every price in entain_sport_event_card is the same shape, so the conversion is the provider's convention rather than this endpoint's quirk. FORGETTING THE +1 UNDERSTATES EVERY PRICE.
THE PRICE IS NOT THE PRODUCT OF THE LEGS. Melbourne (2.15) with Over 173.5 (1.88) prices 3.70, against a naive 4.042.
IT SILENTLY COLLAPSES A REDUNDANT LEG AND STILL SAYS available: true. Melbourne to win plus Melbourne on the line returned 23/20 — 2.15, the SINGLE-LEG price — with no echo of the legs and nothing marking the drop. Repeating one selection twice does the same. There is no leg list in the response, so RESTATE THE SELECTIONS YOU SENT whenever you report a price, and treat a price equal to a shorter combination's as a collapse.
SOME IMPOSSIBLE COMBINATIONS ARE QUOTED RATHER THAN REFUSED, AT BIG PRICES. The conflict detector is good but not complete. Every exactly-two-entrant SGM-available market on the verified event was tested (41 of them): 35 correctly refused their mutually exclusive pair, and FIVE priced it — Match Betting, both teams to win, at 146.51, plus each of the four Quarter Match Betting markets at 70-82. The failing set is the WIN-MARKET FAMILY with two entrants and an implicit draw; the three-entrant version that lists Tie as an entrant (1st Half Betting) is refused correctly.
TWO CLIENT-SIDE DEFENCES, because nothing in the payload marks exclusivity. FIRST, honour same_game_multi_available from entain_sport_event_card — THE PRICER IGNORES ITS OWN FLAG (12 of 14 markets marked unavailable were priced anyway, including the two worst impossible quotes, Highest Scoring Half at 143.65 and 1st Half Match Betting at 110.18). SECOND, do not combine two legs from the SAME market_id unless you know that market permits it: every hole found is a same-market pair. Legitimate same-market pairs do exist — nested Alternate Handicaps/Totals lines, and multi-winner props like Anytime Goal Kicker — so a blanket rule costs a little coverage and removes the whole class.
DO NOT USE num_winners FOR THIS. It was tried and it does not mean exclusivity in either direction: Melbourne Alternate Handicaps is num_winners 1 with 96 nested lines that legitimately combine, while Race To 15 is num_winners 3 with two mutually exclusive entrants.
A bet that cannot win, quoted at 146.51, looks exactly like a longshot with enormous edge, which is what an automated screener selects for. Never trust available: true as proof a combination is coherent.
WHEN IT DOES DETECT A CLASH IT IS THE BEST DIAGNOSTIC OF ANY BOOK HERE: {available: false, conflicting_selections:[{market_id, entrant_id}, …]} names the exact pair. It correctly refused Over with Under, both line sides, two margin bands, and cross-market impossibilities like Melbourne to win with Carlton by 1-39.
available: false WITH NO odds KEY is also what an unknown event returns, quietly and alongside the events that did price. Unlike the other Australian books there is no fake zero to guard against — a refusal simply has no number — but a missing odds must never be read as 0.
Malformed requests are real HTTP 400s naming the problem: a selection missing market_id or entrant_id, and event id must match key when the map key and the inner event_id disagree.
Example: Price Melbourne to win with over 173.5 points {"same_game_multies": {"eccdc4f5-e01e-4aca-afab-570869b53702": {"event_id": "eccdc4f5-e01e-4aca-afab-570869b53702", "selections": [{"market_id": "c73591e5-b00e-4c92-abfb-b3737acbdd30", "entrant_id": "49475673-c7b8-4b49-8c87-e14637ebfa5c"}, {"market_id": "2bc6b298-4fce-4545-93cd-ed232a9c69a0", "entrant_id": "8ada7d51-2a67-4bcb-9593-f9fcbbbd5188"}]}}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: same_game_multies (required).
entain_sport_event_cardARead-onlyIdempotent
Complete event card — every market, selection and price for one sport event.
Returns: {entrants:{}, events:{}, markets:{}, prices:{}, regions:{}, market_type_groups:{}}
Example: One NBA event card {"id": "339e26d0-72a8-49bc-a85f-a2d02c0a1a70"}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: id (required).
entain_sport_event_requestARead-onlyIdempotent
Bulk events + markets + prices for one or more sport categories.
Returns: {events:{}, markets:{}, prices:{}, entrants:{}, next_events:[], regions:{}}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: category_ids (required).
entain_video_channelsARead-onlyIdempotent
Racing live-video channels (HLS .m3u8 URLs; verify token expires within minutes).
Returns: {channels:[{id, name, url}]}
Auth: works without a key; ENTAIN_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
entitysport_competitionsBRead-onlyIdempotent
Competitions and tours.
Returns: {status:'ok', response:{items:[{cid, title, abbr, category, game_format, status, season, datestart, dateend, total_matches, total_teams}], total_pages}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Live competitions {"status": "live"}
Auth: needs your own key in ENTITYSPORT_TOKEN.
Inputs: paged, status, per_page.
entitysport_match_commentaryARead-onlyIdempotent
Ball-by-ball commentary for an innings — the reason to choose this provider over cricketdata.
Returns: {status:'ok', response:{commentaries:[{event:'ball'|'overend'|'wicket', over, ball, batsman_id, bowler_id, score, run_str, commentary, noball, wide, byes, legbyes, six, four}]}} — SHAPE FROM VENDOR DOCS. Rows include NON-BALL events ('overend'), so filter on event before counting deliveries.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: An innings' commentary {"matchId": 12345, "inningsId": 1}
Auth: needs your own key in ENTITYSPORT_TOKEN.
Inputs: matchId (required), inningsId (required).
entitysport_matchesARead-onlyIdempotent
Cricket matches — live, upcoming and completed.
Returns: {status:'ok', response:{items:[{match_id, title, short_title, subtitle, format_str:'T20'|'ODI'|'Test', status, status_str, game_state_str, teama:{team_id, name, short_name, scores_full, scores, overs}, teamb:{…}, date_start, venue, toss:{text, winner, decision}}], total_items, total_pages}} — SHAPE FROM VENDOR DOCS. scores_full is the display string ('187/4 (20)') and scores the bare runs — do not parse the first when you want the second.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Live matches {"status": 3}
Auth: needs your own key in ENTITYSPORT_TOKEN.
Inputs: date, paged, status, per_page.
entitysport_match_infoARead-onlyIdempotent
One match with squads, toss and current state.
Returns: {status:'ok', response:{match_id, title, format_str, status_str, teama, teamb, venue, toss, umpires, referee, players:[…], equation, live}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One match {"matchId": 12345}
Auth: needs your own key in ENTITYSPORT_TOKEN.
Inputs: matchId (required).
entitysport_match_scorecardARead-onlyIdempotent
Full innings-by-innings scorecard.
Returns: {status:'ok', response:{innings:[{iid, number, name, batsmen:[{name, batsman_id, runs, balls_faced, fours, sixes, strike_rate, how_out}], bowlers:[{name, overs, maidens, runs, wickets, econ}], extras, equations:{runs, wickets, overs, runrate}, fows:[…], did_not_bat:[…]}]}} — SHAPE FROM VENDOR DOCS. fows is the fall-of-wickets list.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One match's scorecard {"matchId": 12345}
Auth: needs your own key in ENTITYSPORT_TOKEN.
Inputs: matchId (required).
espn_cdn_callARead-onlyIdempotent
Gateway to the ESPN CDN core live feed (cdn.espn.com). Fast, lightly-cached
scoreboard/game/boxscore/playbyplay JSON. The path slug is the LEAGUE, not the
sport (nfl, nba, mlb, college-football, mens-college-basketball) — for
soccer use the competition slug directly (eng.1, esp.1, uefa.champions).
The CDN covers ESPN's front-page leagues only (no nhl). gameId comes from the
scoreboard op. Every request carries ?xhr=1 (added by default). Browse
espn://cdn/operations.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
espn_core_callARead-onlyIdempotent
Gateway to the ESPN core data model (sports.core.api.espn.com). The deepest,
most canonical surface: athletes + statistics + career logs, per-event odds /
win-probabilities / plays / situation / broadcasts / predictor / power-index,
per-competitor line-scores + statistics, season teams/coaches/draft/futures,
venues, leaders, rankings, franchises and coaches. NOTE the path uses
leagues/{league} (plural). Supply operation + path_params (sport, league,
plus eventId/competitionId/athleteId/year as needed). Most responses use ESPN's
$ref-linked envelope ({count, items:[{$ref}]}); follow the refs for detail.
Browse every operation in the espn://core/operations resource.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
espnfantasy_boxscoreARead-onlyIdempotent
Week box scores — each matchup with both lineups, per-player actual and projected points. The start/sit post-mortem view.
Returns: {schedule:[{matchupPeriodId, home:{teamId, totalPoints, tiebreak, pointsByScoringPeriod, rosterForCurrentScoringPeriod:{entries:[{playerId, lineupSlotId, playerPoolEntry:{player:{fullName, stats:[{appliedTotal, appliedAverage, statSourceId, statSplitTypeId}]}}}]}}, away:{…}}]}
Example: Week-3 box scores {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), scoringPeriodId (required), game, +1 more.
espnfantasy_communicationARead-onlyIdempotent
League message board / activity feed (chat topics, trade chatter, activity posts). 404s when the league has no communication group.
Returns: {topics:[{id, type, date, author, messages:[{id, messageTypeId, to, for, content}]}]} — HTTP 404 'This Communication Group does not exist.' when the league never used the board
Example: Recent league activity {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_draftARead-onlyIdempotent
Draft results — every pick in order with round, team, player, keeper flag and auction bid.
Returns: {draftDetail:{drafted, inProgress, completeDate, picks:[{id, overallPickNumber, roundId, roundPickNumber, playerId, teamId, owningTeamIds, keeper, reservedForKeeper, bidAmount, autoDraftTypeId, lineupSlotId, memberId}]}}
Example: Full draft board {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_everythingARead-onlyIdempotent
UNDOCUMENTED mega-view (allon): settings + teams + rosters + schedule + draft + the whole player pool in ONE response. VERY LARGE (multi-MB) — prefer a targeted tool unless you genuinely need everything.
Returns: {settings, status, teams, members, schedule, draftDetail, players, playersHighlighted, creationInfo, lastUpdateInfo, lastAccessInfo} (~4 MB on a 10-team league)
Example: Everything about a league in one shot {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_gamesARead-onlyIdempotent
All five ESPN fantasy games with each one's CURRENT season id and scoring period — call this first to resolve seasonId/scoringPeriodId.
Returns: [{abbrev:'FFL', id, name, proSportAbbrev, currentSeasonId, currentSeason:{id, currentScoringPeriod:{id}, startDate, endDate}}] (top-level array of 5)
Example: Resolve the current NFL fantasy season + week
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: no named parameters.
espnfantasy_leagueARead-onlyIdempotent
Raw league read with ANY combination of views — the escape hatch when no dedicated tool below fits, or to fetch several views in one round trip.
Returns: {id, seasonId, scoringPeriodId, settings, status, teams:[…], members:[…]} plus whatever the requested views add (schedule, draftDetail, players, …)
Example: Teams + rosters + settings in one call {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "view": ["mTeam", "mRoster", "mSettings"]}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +2 more.
espnfantasy_league_defaultsARead-onlyIdempotent
ESPN's stock league templates (scoring/roster presets) by scoring-type id — the defaults a new league starts from.
Returns: {gameId, id, seasonId, scoringPeriodId, settings:{name:'FFL PPR Scoring', ...}, status:{...}}
Example: The PPR football preset {"game": "ffl", "seasonId": 2025, "scoringTypeId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: seasonId (required), game, scoringTypeId.
espnfantasy_league_historyARead-onlyIdempotent
Pre-2018 seasons and cross-season history via the leagueHistory path. Only works for leagues that HAVE history — check espnfantasy_status.status.previousSeasons first; an empty list there means this returns 404. Returns a single-element ARRAY, not an object.
Returns: [{id, seasonId, settings, teams, status, …}] — ARRAY wrapper; index [0] for a single seasonId. 404 when the league has no leagueHistory record (verified: public league 1234 reports status.previousSeasons == [] and 404s here) — fall back to the seasons path.
Example: A 2017 season for a long-running league {"game": "ffl", "leagueId": 1234, "seasonId": 2017}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), game, view, seasonId.
espnfantasy_league_settingsARead-onlyIdempotent
League rules: name, size, scoring items, roster slots, schedule/playoff format, waiver + keeper + trade settings.
Returns: {settings:{name, size, isPublic, draftSettings, rosterSettings:{lineupSlotCounts}, scoringSettings:{scoringItems:[{statId, points}]}, scheduleSettings, tradeSettings, acquisitionSettings}, status}
Example: Scoring + roster rules for a league {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_live_scoringARead-onlyIdempotent
Live in-progress scoring for the current period — points so far and how many roster spots have yet to play.
Returns: {schedule:[{matchupPeriodId, home:{teamId, totalPoints, totalPointsLive, gamesPlayed}, away:{…}}]} — the *Live fields only populate while pro games are in progress
Example: Live scores right now {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_matchupsARead-onlyIdempotent
Full season schedule of head-to-head fantasy matchups with each side's total and per-period points.
Returns: {schedule:[{id, matchupPeriodId, winner:'HOME'|'AWAY'|'UNDECIDED', home:{teamId, totalPoints, gamesPlayed, pointsByScoringPeriod:{'1':98.4}}, away:{…}}]}
Example: Every matchup in the season {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Also answers this: sleeper_matchups, sleeper_playoff_bracket.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_matchup_scoreARead-onlyIdempotent
Compact matchup scores for the season — totals only, no lineups. Much smaller than the box score.
Returns: {schedule:[{id, matchupPeriodId, winner, home:{teamId, totalPoints, gamesPlayed}, away:{…}}]}
Example: All matchup results {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Also answers this: sleeper_matchups, sleeper_playoff_bracket.
Inputs: leagueId (required), seasonId (required), game, view, +2 more.
espnfantasy_pending_transactionsARead-onlyIdempotent
Pending/unprocessed transactions — waiver claims and trade offers awaiting processing (needs the private cookie in most leagues).
Returns: {pendingTransactions:[…]} when any are pending; the key is ABSENT (not an empty list) when there are none.
Example: Outstanding waiver claims / trade offers {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_player_cardARead-onlyIdempotent
Deep card for specific players — full season + per-period stat splits and projections, as the site's player popup shows.
Returns: {players:[{id, player:{fullName, stats:[{id, seasonId, scoringPeriodId, statSourceId:0|1, statSplitTypeId, appliedTotal, appliedAverage, stats:{…}}]}}]} — statSourceId 0=actual, 1=projected
Example: Season + projection splits for one player {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "fantasy_filter": {"players": {"filterIds": {"value": [15825]}, "filterStatsForTopScoringPeriodIds": {"value": 16, "additionalValue": ["002018", "102018"]}}}}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_player_infoARead-onlyIdempotent
The league's player pool with ownership %, ratings, projections and injury status — pass a status filter for FREE AGENTS / WAIVERS (the waiver-wire tool).
Returns: {players:[{id, onTeamId, status:'FREEAGENT'|'ONTEAM'|'WAIVERS', keeperValue, draftAuctionValue, ratings, player:{fullName, defaultPositionId, eligibleSlots, injured, injuryStatus, proTeamId, ownership:{percentOwned, percentChange, percentStarted}, stats:[{appliedTotal, statSourceId, statSplitTypeId}]}}]}
Example: Top available free agents by ownership {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3, "fantasy_filter": {"players": {"filterStatus": {"value": ["FREEAGENT", "WAIVERS"]}, "limit": 25, "sortPercOwned": {"sortPriority": 1, "sortAsc": false}}}}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +2 more.
espnfantasy_player_newsARead-onlyIdempotent
Recent fantasy news items for one player (injury/usage blurbs that drive start-sit calls).
Returns: {news:{feed:[{id, headline, description, published, lastModified, playerId, links, images}], resultsCount, resultsLimit, timestamp}}
Example: News for one player {"game": "ffl", "playerId": 3139477}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: playerId (required), game.
espnfantasy_playersARead-onlyIdempotent
The player universe for a season (id, name, position, pro team, % owned). Defaults to 50 players — pass fantasy_filter to widen or filter.
Returns: [{id, fullName, firstName, lastName, defaultPositionId, eligibleSlots:[int], proTeamId, droppable, universeId, ownership:{percentOwned}}] (top-level array)
Example: Default slice (50 players) {"game": "ffl", "seasonId": 2025}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: seasonId (required), game, view, fantasy_filter.
espnfantasy_positional_ratingsARead-onlyIdempotent
Positional ratings — average fantasy points allowed by each pro defence to each position (the strength-of-matchup table).
Returns: {positionAgainstOpponent:{positionalRatings:{'1':{average, total, ratingsByOpponent:{'proTeamId':{average, rank}}}}}} (keys are position ids). IN-SEASON ONLY: verified 2026-07-02 that completed/old seasons return 200 with the whole positionAgainstOpponent block ABSENT — that is upstream behaviour, not an error.
Example: Which defences are soft against each position {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), scoringPeriodId (required), game, +1 more.
espnfantasy_pro_teamsARead-onlyIdempotent
Pro (real-world) teams for a fantasy season: ids, abbreviations, BYE weeks, and each team's games keyed by scoring period.
Returns: {settings:{proTeams:[{id, abbrev, location, name, byeWeek, universeId, proGamesByScoringPeriod:{'1':[{...game}]}}]}} — 33 entries for NFL (id 0 = free-agent/none)
Example: NFL teams + bye weeks + week-by-week pro schedule {"game": "ffl", "seasonId": 2025}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: seasonId (required), game, view.
espnfantasy_rostersARead-onlyIdempotent
Every fantasy team's roster — who each manager holds, their lineup slot, acquisition type and player stats. LARGE (hundreds of KB).
Returns: {teams:[{id, roster:{entries:[{playerId, lineupSlotId, acquisitionType, playerPoolEntry:{player:{fullName, defaultPositionId, eligibleSlots, injuryStatus, stats:[…]}}}]}}]}
Example: All rosters, week 3 {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_scoreboardARead-onlyIdempotent
Scoreboard for a scoring period — matchup totals plus the pro-game state behind each fantasy team.
Returns: {schedule:[{matchupPeriodId, home:{teamId, totalPoints, rosterForCurrentScoringPeriod, cumulativeScore:{wins,losses,ties}}, away:{…}}]}
Example: This week's scoreboard {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view, +1 more.
espnfantasy_seasonARead-onlyIdempotent
One game-season's status: current scoring period, start/end dates, whether it is active.
Returns: {abbrev:'FFL 2025', id:2025, gameId, name, active, display, startDate, endDate, currentScoringPeriod:{id}}
Example: 2025 fantasy football season status {"game": "ffl", "seasonId": 2025}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: seasonId (required), game.
espnfantasy_standingsARead-onlyIdempotent
League standings — records, points for/against, division and playoff seeding.
Returns: {teams:[{id, name, playoffSeed, rankCalculatedFinal, record:{overall:{wins,losses,ties,percentage,pointsFor,pointsAgainst}, division:{...}, home:{...}, away:{...}}}], schedule:[…]}
Example: Final standings {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_statusARead-onlyIdempotent
League lifecycle status — current matchup period, latest scoring period, whether the season is active, waiver process dates.
Returns: {status:{currentMatchupPeriod, latestScoringPeriod, finalScoringPeriod, isActive, previousSeasons:[int], teamsJoined, waiverProcessStatus:{…}}}
Example: Where the league is up to {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_teamsARead-onlyIdempotent
Fantasy teams with records, points for/against, playoff seed and projected rank.
Returns: {teams:[{id, abbrev, name, owners, primaryOwner, divisionId, playoffSeed, points, pointsAdjusted, currentProjectedRank, rankCalculatedFinal, record:{overall:{wins,losses,ties,pointsFor,pointsAgainst}}, transactionCounter, waiverRank}], members:[{id, displayName, firstName, lastName}]}
Example: All fantasy teams + records {"game": "ffl", "seasonId": 2018, "leagueId": 1234}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), game, view.
espnfantasy_transactionsARead-onlyIdempotent
Completed transactions (adds, drops, trades, waiver claims) for a scoring period.
Returns: {transactions:[{id, type, status, teamId, memberId, scoringPeriodId, proposedDate, bidAmount, items:[{type:'ADD'|'DROP', playerId, fromTeamId, toTeamId}]}]}
Example: Week-3 transactions {"game": "ffl", "seasonId": 2018, "leagueId": 1234, "scoringPeriodId": 3}
Auth: works without a key; ESPN_FANTASY_COOKIE unlocks more if set.
Inputs: leagueId (required), seasonId (required), scoringPeriodId (required), game, +2 more.
espn_game_summaryARead-onlyIdempotent
Full summary for one game: box score, scoring plays, drives/play-by-play,
leaders, win-probability and odds. event is an id from espn_scoreboard. No
example here on purpose — it needs a live event id, so the doctor probes
espn_scoreboard instead.
Returns: {boxscore:{teams, players}, plays:[...], scoringPlays:[...], leaders:[...], winprobability:[...]}
Auth: none needed.
Inputs: event (required), sport (required), league (required).
espn_newsARead-onlyIdempotent
League news feed: recent articles (headline, description, links, images, related athletes/teams) for one league.
Returns: {header, articles:[{headline, description, published, links, categories}]}
Example: Latest NFL news. {"sport": "football", "league": "nfl"}
Auth: none needed.
Inputs: sport (required), league (required), limit.
espn_scoreboardARead-onlyIdempotent
Scoreboard for one league: today's (or a given date's) games with status,
clock, live scores and event ids. The fastest way to get the event ids that
espn_game_summary / espn_core_call (event_*) need. sport+league are slugs, e.g.
football/nfl, basketball/nba, soccer/eng.1.
Returns: {leagues:[...], events:[{id, name, status, competitions:[{competitors:[{team, score}]}]}]}
Example: Today's NFL scoreboard. {"sport": "football", "league": "nfl"}
Auth: none needed.
Inputs: sport (required), league (required), week, dates, +1 more.
espn_site_callARead-onlyIdempotent
Gateway to the ESPN site API resource families (site.api.espn.com). Supply an
operation plus a path_params map containing at least sport + league
(slugs like football/nfl, basketball/nba) and any id the op needs (teamId,
athleteId), then optional query_params. Covers team detail/rosters/schedules/
injuries/depth-charts/transactions/history, athlete news, conference/division
groups and poll rankings. For athlete profiles/game-logs/splits use
espn_web_call (or espn_core_call for the canonical model). Browse every
operation in the espn://site/operations resource.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
espn_standingsARead-onlyIdempotent
League standings / ladder: per-team wins, losses, win %, conference/division groupings for the current (or a given) season.
Returns: {name, children:[{standings:{entries:[{team, stats:[{name, value}]}]}}]} (children = conferences/divisions)
Example: Current NBA standings. {"sport": "basketball", "league": "nba"}
Auth: none needed.
Inputs: sport (required), league (required), season, seasontype.
espn_teamsARead-onlyIdempotent
Team catalogue for one league: every team with id, name, abbreviation, colours and logos. Use the team ids with espn_site_call (team_roster, team_schedule, …).
Returns: {sports:[{leagues:[{teams:[{team:{id, displayName, abbreviation}}]}]}]}
Example: All 32 NFL teams. {"sport": "football", "league": "nfl"}
Auth: none needed.
Inputs: sport (required), league (required).
espn_web_callARead-onlyIdempotent
Gateway to the ESPN web API (site.web.api.espn.com): site-wide search across
teams/athletes/leagues, plus the common/v3 athlete views (overview, stats,
gamelog, splits) that power player profile pages, and statistics-by-athlete.
search needs only query_params {query, limit}; the athlete_* ops need
path_params {sport, league, athleteId}. Browse the espn://web/operations resource.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
euroleague_clubsARead-onlyIdempotent
The clubs in one season, with city, country and venue detail.
Returns: {total, data:[{code, name, abbreviatedName, editorialName, city, country:{code, name}, address, images, isVirtual}]} — code (e.g. 'MAD') is the club key used elsewhere
Example: 2024-25 EuroLeague clubs {"competition": "E", "season": "E2024"}
Auth: none needed.
Inputs: season (required), competition.
euroleague_gameARead-onlyIdempotent
One game's detail by its per-season game code.
Returns: {id, gameCode, identifier, date, played, gameStatus, local:{club, score}, road:{club, score}, group, phaseType, referee1..4, audience} — a single object, NOT wrapped in {data}
Example: Game 1 of the season {"competition": "E", "season": "E2024", "gameCode": 1}
Auth: none needed.
Inputs: season (required), gameCode (required), competition.
euroleague_gamesARead-onlyIdempotent
Games in a season with scores, venue and officials. Unpaged this is ~800 KB — pass a limit or filter by round.
Returns: {total, data:[{id (uuid), gameCode, identifier:'E2024_330', date, localDate, played, gameStatus, group, phaseType, local:{club, score}, road:{club, score}, isNeutralVenue, referee1..4, audience}]} — HOME/AWAY are local/road; use gameCode (an int) for the per-game tools, not the uuid
Example: First 50 games of the season {"competition": "E", "season": "E2024", "limit": 50}
Auth: none needed.
Inputs: season (required), limit, offset, competition, +1 more.
euroleague_game_statsARead-onlyIdempotent
Box score for one game: both teams' player lines plus team totals and coach.
Returns: {local:{team, coach, total:{…team totals…}, players:[{player:{person, dorsal, position, club}, stats:{timePlayed, valuation, points, fieldGoalsMade2/3, freeThrowsMade, offensiveRebounds, defensiveRebounds, assistances, steals, turnovers, plusMinus, foulsCommited}}]}, road:{…}} — a player line is NESTED as {player, stats}: identity under player, numbers under stats. valuation is EuroLeague's PIR efficiency metric. timePlayed is SECONDS as a float (1088.0 = 18:08), not a MM:SS string.
Example: Box score for game 1 {"competition": "E", "season": "E2024", "gameCode": 1}
Auth: none needed.
Inputs: season (required), gameCode (required), competition.
euroleague_peopleARead-onlyIdempotent
Players and coaches registered for a season. LARGE (~600 KB) — page it.
Returns: {total, data:[{code, name, alias, height, birthDate, country, position, club}]}
Example: First page of registered people {"competition": "E", "season": "E2024", "limit": 100}
Auth: none needed.
Inputs: season (required), limit, offset, competition.
euroleague_roundsARead-onlyIdempotent
The rounds (matchdays) in a season, with their date windows.
Returns: {total, data:[{round, name, seasonCode, phaseTypeCode, minGameStartDate, maxGameStartDate}]}
Example: EuroLeague rounds {"competition": "E", "season": "E2024"}
Auth: none needed.
Inputs: season (required), competition.
euroleague_seasonsARead-onlyIdempotent
Seasons for a competition — call this to get valid season codes like E2024.
Returns: {total, data:[{code:'E2024', name:'EuroLeague 2024-25', alias:'2024-25', year, startDate, endDate, competitionCode, winner}]}
Example: EuroLeague seasons {"competition": "E"}
Auth: none needed.
Inputs: competition.
fanduel_racing_callARead-onlyIdempotent
Call any FanDuel Racing (TVG) GraphQL operation by name + variables against api.racing.fanduel.com/cosmo/v1/graphql. The full query text lives server-side and the boilerplate variables (brand/product/device/profile) default automatically, so most calls need no variables. Read fanduel://racing/operations for the operation list + variable signatures.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), variables.
fanduel_racing_messagesARead-onlyIdempotent
Site message strings (disclaimers, informational copy) for a namespace.
Returns: {response:{:{: }}}
Auth: none needed.
Inputs: brand, device, product, namespace.
fanduel_racing_promotionsARead-onlyIdempotent
Structured racing promotions / placements (POST; empty body returns all).
Returns: {success, promoPlacements:[{...}]}
Auth: none needed.
Inputs: body.
fanduel_racing_quicklinksARead-onlyIdempotent
Homepage quick-link tiles for the racing site.
Returns: {quickLinks:[{label, url, ...}]}
Auth: none needed.
Inputs: no named parameters.
fanduel_sb_callARead-onlyIdempotent
Fetch a FanDuel Sportsbook (US, NJ) REST resource by operation name. Carries
the static public _ak web key + the sportsbook Origin/region headers, so the
caller supplies only the variable query params (eventId, customPageId,
dataEntries, eventIds, …). Read fanduel://sportsbook/operations for the list.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
fanduel_sb_live_scoreARead-onlyIdempotent
Live score + period state for one sportsbook event (NJ).
Returns: {openDate, homeTeam:{shortName, abbreviation, score}, awayTeam:{...}, comp, mediaTypes}
Auth: none needed.
Inputs: eventId (required).
fanduel_sgp_priceARead-onlyIdempotent
PRICE A SAME GAME PARLAY you choose — give it two or more selections from one FanDuel event and get the correlation-adjusted combined price. Read the entry with isSGM: true; the SINGLEs alongside it are the individual leg prices, not the parlay.
Returns: {respCode: 'SUCCESS', betCombinations:[{betType, isSGM, features, winAvgOdds:{trueOdds:{decimalOdds:{decimalOdds}}, americanDisplayOdds}, legCombinations:[…]}], betFailures:[…]} — VERIFIED live 2026-08-27 against NBA Boston Celtics @ Detroit Pistons (event 35928218).
READ THE isSGM: true ENTRY — IT IS THE ONLY ONE THAT IS A SAME GAME PARLAY. The response prices EVERY combination it can make from your legs, so a two-leg request comes back with two SINGLEs and one DOUBLE. The SINGLEs are the individual leg prices, not the parlay; taking the first betCombination gives you a single bet.
THE PRICE IS NOT THE PRODUCT OF THE LEGS. Verified: 2.02 and 1.87 as singles, and the SGP DOUBLE prices 3.4128 against a naive 3.7765 — a 9.6% correlation charge.
USE winAvgOdds.trueOdds.decimalOdds.decimalOdds, NOT averageOdds. The latter is a DISPLAY rounding: the same bet reads 3.41 there and 3.41275716 in trueOdds. Rounded odds compared against another book's exact ones manufacture edge that is not there.
betFailures: INVALID_COMBINATION IS USUALLY NOT ABOUT YOUR PARLAY. It says the legs cannot form an ORDINARY multi because they are from the same game — which is the whole point of an SGP. It appears alongside a perfectly good isSGM entry, so never treat its presence as failure; check for the isSGM entry instead.
NO isSGM ENTRY MEANS FANDUEL WILL NOT COMBINE THOSE LEGS. Seen live on legs whose markets were sgmMarket: true in fanduel_sb_call(event_page), so that flag is necessary and not sufficient. A leg whose runner is suspended reports RUNNER_SUSPENDED instead.
THE UPSTREAM RETURNS A betReference PLACEMENT TOKEN ON EVERY COMBINATION. It is PROJECTED AWAY here and never reaches you — this tool prices and cannot place. The stake ceilings, bonus-wallet and promotion fields are dropped with it.
Example: Price a two-leg same game parlay {"betLegs": [{"legType": "SIMPLE_SELECTION", "betRunners": [{"runner": {"marketId": "734.180521459", "selectionId": 60427}}]}, {"legType": "SIMPLE_SELECTION", "betRunners": [{"runner": {"marketId": "734.180522215", "selectionId": 7017823}}]}]}
Auth: none needed.
Inputs: betLegs (required), web_key.
footballdataorg_areasBRead-onlyIdempotent
Countries and regions, used to filter competitions. VERIFIED live — works without a key.
Returns: {count, filters, areas:[{id, name, countryCode, flag, parentAreaId, parentArea}]} — VERIFIED (272 areas)
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All areas
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: no named parameters.
footballdataorg_competitionARead-onlyIdempotent
One competition with its current season and available seasons. NEEDS A KEY (403 without).
Returns: {id, name, code, type, emblem, area, currentSeason:{id, startDate, endDate, currentMatchday, winner}, seasons:[…]} — SHAPE FROM VENDOR DOCS, not probed.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Premier League {"competition": "PL"}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: competition (required).
footballdataorg_competition_matchesARead-onlyIdempotent
All matches in one competition. NEEDS A KEY (403 without).
Returns: {filters, resultSet, competition, matches:[{id, utcDate, status, matchday, homeTeam, awayTeam, score:{winner, fullTime:{home, away}, halfTime}}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A Premier League matchday {"competition": "PL", "matchday": 1}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: competition (required), dateTo, season, status, +2 more.
footballdataorg_competitionsARead-onlyIdempotent
Every competition the API covers, with its code and current season. VERIFIED live — works without a key.
Returns: {count, filters, competitions:[{id, name, code:'PL', type:'LEAGUE'|'CUP', emblem, plan:'TIER_ONE'…, area:{id, name, code, flag}, currentSeason:{id, startDate, endDate, currentMatchday}, numberOfAvailableSeasons, lastUpdated}]} — VERIFIED (189 competitions). plan tells you which tier a competition needs; the free key covers TIER_ONE only.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All competitions
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: areas.
footballdataorg_matchARead-onlyIdempotent
One match with lineups, goals, bookings and head-to-head. NEEDS A KEY (403 without).
Returns: {id, utcDate, status, competition, homeTeam:{id, name, lineup:[…], bench:[…]}, awayTeam:{…}, score, goals:[{minute, scorer, assist}], bookings:[…], substitutions:[…], referees:[…], head2head:{…}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One match {"matchId": 419516}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: matchId (required).
footballdataorg_matchesARead-onlyIdempotent
Matches across every competition your key can see, for a date range. VERIFIED live — the envelope works without a key (though a keyless call sees no competitions).
Returns: {filters, resultSet:{count, first, last, played}, matches:[{id, utcDate, status, matchday, stage, competition:{id, name, code}, homeTeam:{id, name, shortName, tla, crest}, awayTeam:{…}, score:{winner, duration, fullTime:{home, away}, halfTime:{…}}}]} — envelope VERIFIED; the match object shape is from the vendor's docs. Note the score lives in score.fullTime, not on the match.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Matches in a date window {"dateFrom": "", "dateTo": "<today+2>"}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: dateTo, status, dateFrom, competitions.
footballdataorg_scorersARead-onlyIdempotent
Top scorers in a competition. NEEDS A KEY (403 without).
Returns: {count, filters, competition, season, scorers:[{player:{id, name, nationality, position}, team:{id, name}, goals, assists, penalties, playedMatches}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Premier League top scorers {"competition": "PL", "limit": 10}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: competition (required), limit, season.
footballdataorg_standingsARead-onlyIdempotent
League table for a competition. NEEDS A KEY (403 without).
Returns: {filters, competition, season, standings:[{stage, type:'TOTAL'|'HOME'|'AWAY', group, table:[{position, team:{id, name, crest}, playedGames, won, draw, lost, points, goalsFor, goalsAgainst, goalDifference, form}]}]} — SHAPE FROM VENDOR DOCS. Note standings is a LIST of tables (TOTAL/HOME/AWAY); pick type == 'TOTAL' for the normal ladder.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Premier League table {"competition": "PL"}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: competition (required), season, matchday.
footballdataorg_teamARead-onlyIdempotent
One club with its squad and running competitions. NEEDS A KEY (403 without).
Returns: {id, name, shortName, tla, crest, address, website, founded, clubColors, venue, runningCompetitions:[…], coach:{id, name, nationality, contract}, squad:[{id, name, position, dateOfBirth, nationality}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One club {"teamId": 57}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: teamId (required).
footballdataorg_teamsARead-onlyIdempotent
The clubs in a competition. NEEDS A KEY (403 without).
Returns: {count, filters, competition, season, teams:[{id, name, shortName, tla, crest, address, website, founded, clubColors, venue, coach, squad:[…]}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Premier League clubs {"competition": "PL"}
Auth: needs your own key in FOOTBALL_DATA_ORG_KEY.
Inputs: competition (required), season.
footballdatauk_seasonARead-onlyIdempotent
One league season: every match with full/half-time score, shots, cards, and CLOSING ODDS from ~10 bookmakers. The backtesting dataset.
Returns: [{Div, Date:'16/08/2024', Time, HomeTeam, AwayTeam, FTHG, FTAG, FTR:'H'|'D'|'A', HTHG, HTAG, HTR, Referee, HS, AS, HST, AST, HF, AF, HC, AC, HY, AY, HR, AR, B365H, B365D, B365A, PSH, PSD, PSA, WHH, WHD, WHA, MaxH, AvgH, B365CH…}] (one row per match; ~380 rows for a 20-team season). ALL VALUES ARE STRINGS — cast before arithmetic. Dates are DD/MM/YYYY. A C in an odds column means CLOSING (B365CH = Bet365 closing home).
Example: Premier League 2024/25 with closing odds {"season": "2425", "division": "E0"}
Auth: none needed.
Inputs: season (required), division.
formulae_championshipsARead-onlyIdempotent
Every Formula E season ('championship') with its uuid — call this first, everything else needs the id.
Returns: {championships:[{id (uuid), name:'SEASON 2024-2025', status:'Past'|'Live'|'Future', lastFinishedRound, series:{id, name}}]}
Example: All seasons
Auth: none needed.
Inputs: no named parameters.
formulae_driver_standingsARead-onlyIdempotent
Drivers' championship standings for one season.
Returns: [{driverPosition, driverFirstName, driverLastName, driverTLA:'ROW', driverPoints, driverTeamName, driverTeamId, driverId, driverCountry}] — a TOP-LEVEL ARRAY, not wrapped
Example: Drivers' championship {"championshipId": "4e287a6d-e2da-471a-9c8a-01141d6a1819"}
Auth: none needed.
Inputs: championshipId (required).
formulae_raceARead-onlyIdempotent
One race's detail: circuit, city, date and whether results exist.
Returns: {id, name, sequence, date, city, country, circuit, championship, hasRaceResults, hasSessionResults, metadata} — a single object; there is no results payload on this host (see the docs)
Example: One E-Prix {"raceId": "c1dd1f8a-5112-4864-8d2d-cfcc8951d197"}
Auth: none needed.
Inputs: raceId (required).
formulae_racesARead-onlyIdempotent
The race calendar — all seasons, or one championship's rounds.
Returns: {pageInfo:{…}, races:[{id (uuid), name:'Beijing E-Prix', sequence, date, city, country, circuit, championship, hasRaceResults, hasSessionResults}]} — WRAPPED, unlike standings
Example: One season's calendar {"championshipId": "4e287a6d-e2da-471a-9c8a-01141d6a1819"}
Auth: none needed.
Inputs: championshipId.
formulae_team_standingsARead-onlyIdempotent
Teams' championship standings, including each team's points race by race.
Returns: [{teamPosition, teamName, teamId, teamPoints, teamRaceStandings:[{raceSequence, raceCountry, racePoints}]}] — top-level array. teamRaceStandings is the per-race points breakdown, and the closest thing to race results this host exposes.
Example: Teams' championship {"championshipId": "4e287a6d-e2da-471a-9c8a-01141d6a1819"}
Auth: none needed.
Inputs: championshipId (required).
fpl_classic_leagueARead-onlyIdempotent
Classic (total-points) league standings, paginated.
Returns: {league:{id, name, created, closed, admin_entry, start_event, league_type, scoring}, new_entries:{has_next, page, results}, standings:{has_next, page, results:[{id, entry, entry_name, player_name, rank, last_rank, rank_sort, total, event_total}]}} — entry is the manager id for fpl_manager; rank vs last_rank gives movement. Big leagues page at 50.
Example: A league table {"leagueId": 314}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: leagueId (required), page_standings, page_new_entries.
fpl_dream_teamARead-onlyIdempotent
The highest-scoring XI of a completed gameweek.
Returns: {top_player:{id, points}, team:[{element, position, points}]} — 404s until the gameweek is finished.
Example: A gameweek's best XI {"gameweek": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: gameweek (required).
fpl_event_statusARead-onlyIdempotent
Whether bonus points and league tables have been finalised for the current gameweek.
Returns: {status:[{bonus_added, date, event, points:'r'|'p'|'l'}], leagues:'Updated'|''} — this is how you know scores are FINAL. bonus_added: false means bonus points are still provisional, so a score read now may change.
Example: Is this gameweek settled?
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
fpl_fixturesARead-onlyIdempotent
Fixtures with FPL difficulty ratings, and goal/assist/bonus breakdowns once played.
Returns: [{id, code, event, team_h, team_a, team_h_score, team_a_score, kickoff_time, started, finished, finished_provisional, minutes, team_h_difficulty:1-5, team_a_difficulty:1-5, stats:[{identifier:'goals_scored'|'assists'|'bonus'|'bps'|'saves'|…, h:[{element, value}], a:[{element, value}]}]}] — stats is EMPTY until the match is played, then carries per-player contributions keyed by player id. The two difficulty ratings are from each side's perspective. finished_provisional goes true before finished: bonus points are not final until finished.
Example: One gameweek's fixtures {"event": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: event, future.
fpl_game_rulesARead-onlyIdempotent
Positions, chips, phases and scoring settings — the lookup tables the other tools' ids refer to.
Returns: {element_types:[{id:1-4, singular_name:'Goalkeeper', plural_name, squad_select, squad_min_play, squad_max_play, element_count}], chips:[{id, name:'wildcard'|'freehit'|'bboost'|'3xc', number, start_event, stop_event}], phases:[{id, name:'Overall'|'August', start_event, stop_event}], game_settings:{squad_squadplay, squad_total_spend, transfers_cost, transfers_limit, …}, element_stats:[{label:'Goals scored', name:'goals_scored'}], total_players:4085510} — element_types resolves the element_type id on every player (1 GK, 2 DEF, 3 MID, 4 FWD). total_players is how many squads exist worldwide, which is what an overall rank is out of.
Example: The lookup tables
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
fpl_gameweeksARead-onlyIdempotent
All 38 gameweeks: deadlines, average scores, highest score, chip usage, and which one is current.
Returns: {events:[{id:1-38, name:'Gameweek 1', deadline_time:'2026-08-15T17:30:00Z', deadline_time_epoch, finished, data_checked, is_previous, is_current, is_next, average_entry_score, highest_score, highest_scoring_entry, most_selected, most_transferred_in, most_captained, most_vice_captained, top_element, transfers_made, chip_plays:[{chip_name, num_played}]}]} — deadline_time is THE thing an agent needs: transfers and lineup changes lock at it. is_current/is_next are how you find where the season is without doing date arithmetic.
Example: The full gameweek calendar
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
fpl_h2h_leagueARead-onlyIdempotent
Head-to-head league standings with win/draw/loss records.
Returns: {league:{id, name, league_type, scoring:'h'}, standings:{has_next, page, results:[{id, entry, entry_name, player_name, rank, last_rank, total, matches_played, matches_won, matches_drawn, matches_lost, points_for}]}} — total is H2H league points (3 a win), points_for the FPL points scored. Ranking is on total, so a high scorer can sit mid-table.
Example: An H2H table {"leagueId": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: leagueId (required), page_standings.
fpl_live_gameweekARead-onlyIdempotent
Live per-player scoring for a gameweek — points as they are being earned.
Returns: {elements:[{id, stats:{minutes, goals_scored, assists, clean_sheets, goals_conceded, saves, bonus, bps, total_points, expected_goals, …}, explain:[{fixture, stats:[{identifier, points, value}]}]}]} — explain breaks a player's points down by WHY they were awarded, which is the only way to reconcile a score. Returns {elements: []} for a gameweek that has not started — empty is normal pre-season, not a failure.
Example: Live scoring for a gameweek {"gameweek": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: gameweek (required).
fpl_managerARead-onlyIdempotent
A manager's squad summary: overall rank, points, and every league they are in.
Returns: {id, name:'Squad Name', player_first_name, player_last_name, player_region_name, summary_overall_points, summary_overall_rank, summary_event_points, summary_event_rank, current_event, started_event, last_deadline_bank, last_deadline_value, last_deadline_total_transfers, leagues:{classic:[{id, name, entry_rank, entry_last_rank}], h2h:[…], cup:{…}}} — last_deadline_value and last_deadline_bank are in TENTHS of a million, like player prices.
Example: A manager's summary {"managerId": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: managerId (required).
fpl_manager_historyARead-onlyIdempotent
A manager's gameweek-by-gameweek history, past seasons, and chips already used.
Returns: {current:[{event, points, total_points, rank, overall_rank, bank, value, event_transfers, event_transfers_cost, points_on_bench}], past:[{season_name:'2024/25', total_points, rank}], chips:[{name:'wildcard', time, event}]} — chips is what has ALREADY been played, which is how you know what is still available. current is empty before gameweek 1.
Example: A manager's season {"managerId": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: managerId (required).
fpl_manager_picksARead-onlyIdempotent
The exact XI, bench order, captain and chip a manager used in a gameweek.
Returns: {active_chip, automatic_subs:[{element_in, element_out}], entry_history:{event, points, total_points, rank, bank, value, event_transfers, event_transfers_cost, points_on_bench}, picks:[{element, position:1-15, multiplier:0|1|2|3, is_captain, is_vice_captain}]} — position 1-11 is the XI and 12-15 the bench IN ORDER. multiplier 2 is the captain, 3 a triple-captain chip, and 0 means they did not play (benched).
Example: A manager's gameweek team {"managerId": 1, "gameweek": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: gameweek (required), managerId (required).
fpl_my_teamARead-onlyIdempotent
YOUR current squad including picks not yet visible to others, plus bank, free transfers and chip availability. Needs your FPL session cookie.
Returns: {picks:[{element, position:1-15, multiplier:0|1|2|3, is_captain, is_vice_captain, element_type:1-4, selling_price, purchase_price}], picks_last_updated, chips:[{id, status_for_entry:'available'|'played'|'unavailable', played_by_entry:[], name:'bboost'|'3xc'|'wildcard'|'freehit', number, start_event, stop_event, chip_type:'team'|'transfer', is_pending}], transfers:{cost, status:'unlimited'|'limited', limit, made, bank, value}} — VERIFIED against a live squad. The ONE place selling_price and purchase_price appear: FPL sells a risen player back at half the gain, so selling_price is often below now_cost and that difference decides whether a transfer is affordable.
TWO FIELDS THAT CHANGE THE ANSWER: transfers.status is 'unlimited' BEFORE the first deadline — unlimited free changes, so cost and limit do not apply and limit is null. And chips[].chip_type splits how a chip is played: 'team' chips (bboost, 3xc) ride POST /api/my-team/, 'transfer' chips (wildcard, freehit) ride POST /api/transfers/.
Returns 403 {'detail':'Authentication credentials were not provided.'} without FPL_SESSION_COOKIE.
Example: Your own squad {"managerId": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: managerId (required).
fpl_player_detailARead-onlyIdempotent
One player in full: every gameweek this season, past seasons, and upcoming fixtures with difficulty.
Returns: {fixtures:[{id, event, team_h, team_a, is_home, difficulty:1-5, kickoff_time}], history:[{element, fixture, round, total_points, minutes, goals_scored, assists, clean_sheets, bonus, bps, expected_goals, value, transfers_balance, selected, was_home, opponent_team}], history_past:[{season_name:'2024/25', total_points, minutes, goals_scored, end_cost, start_cost}]} — difficulty is FPL's own 1 (easiest) to 5 (hardest) rating, and it drives most fixture-run analysis. value in history is the price AT THAT GAMEWEEK, so you can see price movement.
Example: One player's full record {"playerId": 1}
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: playerId (required).
fpl_playersARead-onlyIdempotent
Every FPL player with price, form, ownership, expected goals and availability. LARGE — ~65k tokens for all 581 players; use fpl_player_detail for one player's depth.
Returns: {elements:[{id, web_name:'Salah', team:11, element_type:3, now_cost:145, total_points, points_per_game:'6.2', form:'5.4', selected_by_percent:'42.1', status:'a'|'i'|'d'|'s'|'u', news:'Knock - 75% chance of playing', chance_of_playing_next_round, minutes, goals_scored, assists, clean_sheets, bonus, expected_goals:'0.54', expected_assists, defensive_contribution, ict_index, ep_next:'6.1'}]} — now_cost is TENTHS of a million (145 = £14.5m). status: a available, i injured, d doubtful, s suspended, u unavailable. Trimmed from 105 fields per player to 22; the upstream blob is ~362k tokens, which no context window holds.
Example: Every player, key fields
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
fpl_set_piece_notesARead-onlyIdempotent
Official set-piece taker notes per club — who takes penalties, corners and free kicks.
Returns: {last_updated, teams:[{id, notes:[{external_link, info_message:'Penalties: Haaland, then Alvarez', source_link}]}]} — genuinely useful for FPL and priced-market work alike: penalty duty is worth several points a season and moves with injuries.
Example: Who takes the penalties
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
fpl_teamsARead-onlyIdempotent
The 20 Premier League clubs with FPL's attack/defence strength ratings.
Returns: {teams:[{id:1-20, name:'Arsenal', short_name:'ARS', code, strength:1-5, strength_overall_home, strength_overall_away, strength_attack_home, strength_attack_away, strength_defence_home, strength_defence_away, played, win, draw, loss, points, position, form}]} — id is FPL's own alphabetical 1-20, NOT the Premier League's official team id; join to the premierleague provider by name. The strength_* numbers are FPL's internal ratings (~1000-1400) and are what fixture-difficulty is derived from.
Example: All 20 clubs
Auth: works without a key; FPL_SESSION_COOKIE unlocks more if set.
Inputs: no named parameters.
golfcourseapi_courseARead-onlyIdempotent
One course in full: every tee box with per-hole par, yardage and stroke index.
Returns: {course:{id, club_name, course_name, location:{…}, tees:{male:[{tee_name, course_rating, slope_rating, par_total, total_yards, number_of_holes, holes:[{par, yardage, handicap}]}], female:[…]}}} — SHAPE FROM VENDOR DOCS. NOTE tees is split by MALE/FEMALE tee sets, each a LIST of tee boxes, each with its own 18-hole array — three levels before a hole. handicap here is the hole's stroke index (1 = hardest), not a player handicap.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One course in full {"id": 1}
Auth: needs your own key in GOLFCOURSE_API_KEY.
Inputs: id (required).
golfcourseapi_searchARead-onlyIdempotent
Search the course catalogue by name or club.
Returns: {courses:[{id, club_name, course_name, location:{address, city, state, country, latitude, longitude}}]} — SHAPE FROM VENDOR DOCS. Search returns the summary only; per-hole data needs golfcourseapi_course.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Find a course {"search_query": "Pebble Beach"}
Auth: needs your own key in GOLFCOURSE_API_KEY.
Inputs: search_query (required).
highlightly_baseball_highlightsARead-onlyIdempotent
Baseball highlight clips.
Returns: {data:[{id, title, url, embedUrl, imgUrl, match:{…}}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's baseball highlights {"date": "2024-07-04"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, matchId, leagueId.
highlightly_basketball_highlightsARead-onlyIdempotent
Basketball highlight clips (NBA, EuroLeague and others).
Returns: {data:[{id, title, url, embedUrl, imgUrl, match:{…}}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's basketball highlights {"date": "2024-01-15"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, matchId, leagueId.
highlightly_hockey_highlightsARead-onlyIdempotent
Ice-hockey highlight clips.
Returns: {data:[{id, title, url, embedUrl, imgUrl, match:{…}}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's hockey highlights {"date": "2024-01-15"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, matchId, leagueId.
highlightly_nfl_highlightsARead-onlyIdempotent
American-football highlight clips.
Returns: {data:[{id, title, url, embedUrl, imgUrl, match:{…}}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's NFL highlights {"date": "2024-01-15"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, matchId, leagueId.
highlightly_soccer_highlightsARead-onlyIdempotent
Football highlight clips, by match, league or date. The main tool here.
Returns: {data:[{id, title, type, url, imgUrl, embedUrl, channel, source, match:{id, date, league, homeTeam, awayTeam}}], pagination:{totalCount, limit, offset}} — SHAPE FROM VENDOR DOCS. url is a page link and embedUrl an iframe source; they are not interchangeable.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's football highlights {"date": "2024-08-17"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, offset, matchId, +1 more.
highlightly_soccer_leaguesCRead-onlyIdempotent
Football competitions covered, with the leagueId filters.
Returns: {data:[{id, name, logo, country:{code, name, logo}, seasons:[…]}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Competitions covered
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: limit, leagueName, countryCode.
highlightly_soccer_matchesARead-onlyIdempotent
Football matches, to find the matchId a highlight lookup needs.
Returns: {data:[{id, date, country, league:{id, name, logo}, homeTeam:{id, name, logo}, awayTeam:{…}, state:{description, score:{current, penalties}}}], pagination} — SHAPE FROM VENDOR DOCS. The score is nested under state, not on the match.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's matches {"date": "2024-08-17"}
Auth: needs your own key in HIGHLIGHTLY_API_KEY.
Inputs: date, limit, season, leagueId.
isportsapi_basketball_scheduleARead-onlyIdempotent
Basketball fixtures and results by date.
Returns: {code:0, data:[{matchId, leagueId, homeName, awayName, matchTime, status, homeScore, awayScore, quarterScores}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's games {"date": "2024-01-15"}
Auth: needs your own key in ISPORTS_API_KEY.
Inputs: date, leagueId.
isportsapi_football_competitionsARead-onlyIdempotent
Football competitions with their ids.
Returns: {code:0, data:[{competitionId, name, shortName, logo, type, color}]} — SHAPE FROM VENDOR DOCS. code: 0 means success; anything else is an error delivered with HTTP 200.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every competition
Auth: needs your own key in ISPORTS_API_KEY.
Inputs: no named parameters.
isportsapi_football_liveARead-onlyIdempotent
Football matches in play now.
Returns: {code:0, data:[{matchId, status, homeScore, awayScore, homeHalfScore, awayHalfScore, homeRed, awayRed, homeYellow, awayYellow, homeCorner, awayCorner, updateTime}]} — SHAPE FROM VENDOR DOCS. Corners and cards live here rather than in a separate statistics call.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: In play now
Auth: needs your own key in ISPORTS_API_KEY.
Inputs: no named parameters.
isportsapi_football_odds_asianARead-onlyIdempotent
Asian-handicap odds across companies — the reason to use this provider.
Returns: {code:0, data:{handicap:[[matchId, companyId, initialHandicap, initialHome, initialAway, liveHandicap, liveHome, liveAway, …]], europeOdds:[[…]], overUnder:[[…]]}} — SHAPE FROM VENDOR DOCS. NOTE the payload is ARRAYS OF POSITIONAL ARRAYS, not objects: fields are identified by INDEX. Read the vendor's column order before parsing, and do not assume it matches other providers here.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Asian handicap odds
Auth: needs your own key in ISPORTS_API_KEY.
Inputs: matchId, companyId.
isportsapi_football_scheduleARead-onlyIdempotent
Football fixtures and results by date.
Returns: {code:0, data:[{matchId, competitionId, homeId, homeName, awayId, awayName, matchTime, status, homeScore, awayScore, halfHomeScore, halfAwayScore}]} — SHAPE FROM VENDOR DOCS. matchTime is a UNIX TIMESTAMP, not an ISO string.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A day's fixtures {"date": "2024-08-17"}
Auth: needs your own key in ISPORTS_API_KEY.
Inputs: date, leagueId.
jolpicaf1_circuitsBRead-onlyIdempotent
Circuits, with location and coordinates.
Returns: {MRData:{CircuitTable:{Circuits:[{circuitId, circuitName, Location:{lat, long, locality, country}, url}]}}}
Example: 2024 circuits {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format.
jolpicaf1_constructorsBRead-onlyIdempotent
Constructors (teams) — all-time, or those entered in one season.
Returns: {MRData:{ConstructorTable:{season, Constructors:[{constructorId, name, nationality, url}]}}}
Example: 2024 constructors {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format.
jolpicaf1_constructor_standingsARead-onlyIdempotent
Constructors' championship standings.
Returns: {MRData:{StandingsTable:{StandingsLists:[{season, round, ConstructorStandings:[{position, points, wins, Constructor:{constructorId, name, nationality}}]}]}}}
Example: 2024 constructors' championship {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format.
jolpicaf1_driversARead-onlyIdempotent
Drivers — all-time, or the field for one season.
Returns: {MRData:{DriverTable:{season, Drivers:[{driverId, permanentNumber, code, givenName, familyName, dateOfBirth, nationality, url}]}}} — driverId (e.g. 'max_verstappen') is the key every other tool filters on
Example: 2024 field {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format, offset.
jolpicaf1_driver_standingsARead-onlyIdempotent
Drivers' championship standings — after a season, or after a specific round.
Returns: {MRData:{StandingsTable:{season, round, StandingsLists:[{season, round, DriverStandings:[{position, points, wins, Driver:{driverId, code, familyName}, Constructors:[{constructorId, name}]}]}]}}} — note the extra StandingsLists layer
Example: 2024 drivers' championship {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format.
jolpicaf1_lapsARead-onlyIdempotent
Lap-by-lap times for every driver in a race. LARGE — page it or narrow to one lap.
Returns: {MRData:{total, RaceTable:{Races:[{Laps:[{number, Timings:[{driverId, position, time}]}]}]}}} — one entry per lap, each holding every driver's timing
Example: First laps of 2024 round 1 {"season": "2024", "round": "1", "format": "json", "limit": 100}
Auth: none needed.
Inputs: round (required), season (required), limit, format, +1 more.
jolpicaf1_pitstopsARead-onlyIdempotent
Pit stops for a race: lap, time of day and stationary duration.
Returns: {MRData:{RaceTable:{Races:[{PitStops:[{driverId, lap, stop, time, duration}]}]}}} — duration is stationary time ('23.2'), time is clock time of day
Example: 2024 round 1 pit stops {"season": "2024", "round": "1", "format": "json"}
Auth: none needed.
Inputs: round (required), season (required), limit, format.
jolpicaf1_qualifyingARead-onlyIdempotent
Qualifying results with Q1/Q2/Q3 times per driver.
Returns: {MRData:{RaceTable:{Races:[{QualifyingResults:[{position, Driver, Constructor, Q1, Q2, Q3}]}]}}} — Q2/Q3 absent for drivers eliminated earlier
Example: 2024 round 1 qualifying {"season": "2024", "round": "1", "format": "json"}
Auth: none needed.
Inputs: round (required), season (required), limit, format.
jolpicaf1_racesARead-onlyIdempotent
A season's race calendar with dates, circuits and (from 2021) each session's date/time.
Returns: {MRData:{RaceTable:{season, Races:[{season, round, raceName, date, time, url, Circuit:{circuitId, circuitName, Location}, FirstPractice, Qualifying, Sprint}]}}} — round is what the result tools take
Example: 2024 calendar {"season": "2024", "format": "json"}
Auth: none needed.
Inputs: season (required), limit, format.
jolpicaf1_resultsARead-onlyIdempotent
Race results: finishing order, grid, laps, time/status, points and fastest lap.
Returns: {MRData:{RaceTable:{Races:[{season, round, raceName, Results:[{position, positionText, points, grid, laps, status, Driver:{driverId, code}, Constructor:{constructorId}, Time:{millis, time}, FastestLap:{rank, lap, Time, AverageSpeed}}]}]}}} — all values are STRINGS
Example: 2024 round 1 {"season": "2024", "round": "1", "format": "json"}
Auth: none needed.
Inputs: round (required), season (required), limit, format.
jolpicaf1_seasonsARead-onlyIdempotent
Every F1 season on record (1950 onward).
Returns: {MRData:{total, limit, offset, SeasonTable:{Seasons:[{season, url}]}}}
Example: First page of seasons {"format": "json", "limit": 30}
Auth: none needed.
Inputs: limit, format, offset.
jolpicaf1_sprintARead-onlyIdempotent
Sprint race results (weekends that have one — 2021 onward).
Returns: {MRData:{RaceTable:{Races:[{SprintResults:[{position, points, grid, laps, status, Driver, Constructor, Time}]}]}}} — Races is EMPTY for a weekend with no sprint, which is not an error
Example: A 2024 sprint weekend {"season": "2024", "round": "5", "format": "json"}
Auth: none needed.
Inputs: round (required), season (required), format.
kalshi_candlesticksARead-onlyIdempotent
OHLC price candlesticks for one market over a time window (1m/1h/1d periods).
Returns: {ticker, candlesticks:[{end_period_ts, yes_bid, yes_ask, price, volume, open_interest}]}
Auth: none needed.
Also answers this: polymarket_price_history.
Inputs: end_ts (required), ticker (required), start_ts (required), seriesTicker (required), +1 more.
kalshi_candlesticks_batchARead-onlyIdempotent
OHLC candlesticks for MANY markets in one call — pass the tickers as a list.
Returns: {markets:[{market_ticker, candlesticks:[{end_period_ts, price, volume, open_interest}]}]}
Auth: none needed.
Also answers this: polymarket_price_history.
Inputs: end_ts (required), start_ts (required), market_tickers (required), period_interval.
kalshi_eventARead-onlyIdempotent
One event by ticker, optionally with its markets embedded.
Returns: {event:{event_ticker, series_ticker, title, category, mutually_exclusive, markets:[…]}, markets}
Auth: none needed.
Inputs: eventTicker (required), with_nested_markets.
kalshi_eventsARead-onlyIdempotent
Event catalogue (an event groups related markets) — filter by series or status. Paginated by cursor.
Returns: {cursor, events:[{event_ticker, series_ticker, title, sub_title, category, mutually_exclusive, strike_period}], milestones}
Example: First page of open events {"limit": 5, "status": "open"}
Auth: none needed.
Inputs: limit, cursor, status, series_ticker, +1 more.
kalshi_exchange_announcementsARead-onlyIdempotent
Active exchange-wide announcements.
Returns: {announcements:[{type, message, delivery_time, status}]}
Auth: none needed.
Inputs: no named parameters.
kalshi_exchange_scheduleARead-onlyIdempotent
Standard trading hours + maintenance windows.
Returns: {schedule:{standard_hours, maintenance_windows}}
Auth: none needed.
Inputs: no named parameters.
kalshi_exchange_statusARead-onlyIdempotent
Is the exchange up and trading right now.
Returns: {exchange_active, trading_active}
Auth: none needed.
Inputs: no named parameters.
kalshi_marketARead-onlyIdempotent
One market's full detail by ticker — quotes, volume, rules, strike, timing.
Returns: {market:{ticker, event_ticker, title, yes_sub_title, no_sub_title, status, result, yes_bid_dollars, yes_ask_dollars, last_price_dollars, volume_fp, open_interest_fp, rules_primary, rules_secondary, strike_type, custom_strike, open_time, close_time, expiration_time}}
Auth: none needed.
Also answers this: polymarket_market.
Inputs: ticker (required).
kalshi_marketsARead-onlyIdempotent
Prediction-market catalogue with current quotes — filter by event/series ticker or status. Paginated by cursor.
Returns: {cursor, markets:[{ticker, event_ticker, market_type, title, status, yes_bid_dollars, yes_ask_dollars, no_bid_dollars, no_ask_dollars, last_price_dollars, volume_fp, volume_24h_fp, open_interest_fp, liquidity_dollars, open_time, close_time, expiration_time, rules_primary}]}
Example: First page of open markets {"limit": 5, "status": "open"}
Auth: none needed.
Also answers this: polymarket_markets, polymarket_clob_markets.
Inputs: limit, cursor, status, tickers, +2 more.
kalshi_milestonesARead-onlyIdempotent
Milestones — dated catalysts (data releases, games, decisions) linked to the event tickers they resolve.
Returns: {cursor, milestones:[{id, category, details, end_date, primary_event_tickers, related_event_tickers}]}
Auth: none needed.
Inputs: limit, cursor, category, minimum_start_date.
kalshi_mve_collectionARead-onlyIdempotent
One multivariate event collection by ticker.
Returns: {multivariate_contract:{collection_ticker, series_ticker, title, description, associated_events, associated_event_tickers}}
Auth: none needed.
Inputs: collectionTicker (required).
kalshi_mve_collectionsARead-onlyIdempotent
Multivariate event collections — the parlay-style combo products that many KXMVE* markets belong to (a market's mve_collection_ticker points here).
Returns: {cursor, multivariate_contracts:[{collection_ticker, series_ticker, title, description, is_ordered, is_all_yes, size_min, size_max, associated_event_tickers, open_date, close_date}]}
Auth: none needed.
Inputs: limit, cursor, status, series_ticker.
kalshi_orderbookARead-onlyIdempotent
Order book for one market — resting yes/no bids by price level (dollar-denominated).
Returns: {orderbook_fp:{yes_dollars:[[price, size], …], no_dollars:[[price, size], …]}} (empty arrays when nothing is resting)
Auth: none needed.
Inputs: ticker (required), depth.
kalshi_seriesARead-onlyIdempotent
One series by ticker — title, category, settlement sources, fee structure.
Returns: {series:{ticker, title, category, frequency, tags, settlement_sources, contract_url, fee_type}}
Auth: none needed.
Inputs: seriesTicker (required).
kalshi_series_listARead-onlyIdempotent
All series in a category (Sports, Politics, Economics, Financials, Climate and Weather, Entertainment, …) — the top of the id chain.
Returns: {series:[{ticker, title, category, frequency, tags, settlement_sources, contract_url}]}
Example: Every sports series {"category": "Sports"}
Auth: none needed.
Inputs: category (required), include_product_metadata.
kalshi_structured_targetARead-onlyIdempotent
One structured target (entity) by id.
Returns: {structured_target:{id, name, type, details, source_ids}}
Auth: none needed.
Inputs: id (required).
kalshi_structured_targetsARead-onlyIdempotent
Structured targets — Kalshi's entity registry (players, companies, people) that markets resolve against. Paginated by cursor; page size via page_size.
Returns: {cursor, structured_targets:[{id, name, type, details, source_ids, last_updated_ts}]}
Auth: none needed.
Inputs: type, cursor, page_size.
kalshi_tradesARead-onlyIdempotent
Recent public trades, optionally for one market ticker. Paginated by cursor.
Returns: {cursor, trades:[{trade_id, ticker, count, yes_price, no_price, taker_side, created_time}]}
Auth: none needed.
Also answers this: polymarket_trades, polymarket_holders.
Inputs: limit, cursor, max_ts, min_ts, +1 more.
laliga_competitionARead-onlyIdempotent
One competition by SLUG (e.g. primera-division). Numeric id 404s — use the slug.
Returns: {competition:{id, slug, name, opta_id}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_competitionsARead-onlyIdempotent
All LaLiga competitions (men's/women's, primera/segunda, across history), each with slug, opta_id, name.
Returns: {competitions:[{id, slug, name, opta_id, lde_id, main}]}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: no named parameters.
laliga_matchARead-onlyIdempotent
One match by SLUG (from laliga_matches; the long temporada-… slug, not the numeric id which 404s). For a played match adds scores + formations.
Returns: {match:{id, slug, name, home_team, away_team, home_score, away_score, home_formation, away_formation, competition, gameweek, date, status, attempt, ball}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_matchesARead-onlyIdempotent
Matches feed. IMPORTANT: pass competition= to get a competition's matches — subscription= alone returns a mixed bag (incl. World Cup placeholders). competition=primera-division gives the 380 LALIGA EA SPORTS matches; add gameweek= for one matchweek (10).
Returns: {total, matches:[{id, slug, name, opta_id, home_team, away_team, competition, season, gameweek, date, time, venue, status}]} (status FullTime/PreMatch/…)
Example: 2025/26 LALIGA matchweek 1 (10 matches) {"subscription": "laliga-easports-2025", "competition": "primera-division", "gameweek": 1, "limit": 10}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: limit, offset, gameweek, competition, +1 more.
laliga_playerARead-onlyIdempotent
One player profile by SLUG — name, firstname/lastname, date_of_birth, country, current team + squad, roles.
Returns: {player:{id, slug, name, firstname, lastname, date_of_birth, country, international, team, squad, roles}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_players_statsARead-onlyIdempotent
EVERY player in a season (≈749) with full Opta stats[] (name/stat pairs) + position + team + opta_id. Page with limit (max 100) + offset.
Returns: {total, player_stats:[{id, name, slug, opta_id, shirt_number, position, country, team, stats:[{name, stat}]}]}
Example: First page of 2025/26 player stats {"slug": "laliga-easports-2025", "limit": 20}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required), limit, offset.
laliga_player_statsARead-onlyIdempotent
One player's Opta stats[] by SLUG.
Returns: {player_stats:{id, name, slug, opta_id, team, stats:[{name, stat}]}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_roundsARead-onlyIdempotent
Rounds / matchweeks structure for a season (gameweeks, groups).
Returns: {total, rounds:[{id, slug, name, position, num_gameweeks, gameweeks, has_groups, groups}]}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_squadARead-onlyIdempotent
A club's CURRENT squad — each entry has person (name, date_of_birth, country, height), photos, position id, shirt_number, opta_id, loan status. (The subscription arg is required by the API but the roster returned is the current one, not season-historical.)
Returns: {total, squads:[{id, opta_id, person:{name, date_of_birth, country, height}, photos, position, shirt_number, role, current, loan}]}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required), subscription (required).
laliga_standingARead-onlyIdempotent
Full league table for a season — 20 entries with played/won/drawn/lost/goals_for/goals_against/goal_difference/points/position + full team object (shield, colours).
Returns: {total, standings:[{position, previous_position, played, won, drawn, lost, goals_for, goals_against, goal_difference, points, team:{id, slug, name, shortname, opta_id, shield}}]}
Example: 2025/26 LALIGA EA SPORTS table {"slug": "laliga-easports-2025"}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_subscriptionARead-onlyIdempotent
One season instance by slug — competition, year, season name, current gameweek, rounds, and teams (the authoritative 20 teams in that season — use this, not laliga_teams, for a season roster).
Returns: {subscription:{id, slug, name, competition, season, season_name, year, current_gameweek, teams:[20 season teams], rounds}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_subscriptionsARead-onlyIdempotent
Season instances (a 'subscription' = one competition's season), paginated 20/page. Each has slug, competition, year, current_gameweek, date range.
Returns: {total, subscriptions:[{id, name, slug, competition, year, current_gameweek, date_ini, date_end, rounds}]}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: offset.
laliga_teamARead-onlyIdempotent
One team by SLUG — club info, colours, foundation, socials, competitions, venue.
Returns: {team:{id, slug, name, shortname, opta_id, club, color, foundation, competitions, last_main_competition}}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: slug (required).
laliga_teamsARead-onlyIdempotent
Global team directory across all competitions (~1541), paginated — use it to resolve a team's slug/id/opta_id. NOTE: NOT season-scoped; for the 20 teams in a season read laliga_standing or laliga_subscription (its embedded teams).
Returns: {total, teams:[{id, slug, name, nickname, shortname, boundname, shield, competitions}]} (opta_id present on most; join via it where available)
Example: First page of the team directory {"limit": 20}
Auth: works without a key; LALIGA_SUBSCRIPTION_KEY unlocks more if set.
Inputs: limit, offset.
lichess_daily_puzzleARead-onlyIdempotent
The daily puzzle: the position, the solution line, and the game it came from.
Returns: {game:{id, perf:{key, name}, rated, players:[{name, color, rating}], pgn, clock}, puzzle:{id, rating, plays, solution:[uci moves], themes:[str], initialPly}}
Example: Today's puzzle
Auth: none needed.
Inputs: no named parameters.
lichess_leaderboardARead-onlyIdempotent
Top-rated players for one time control or variant.
Returns: {users:[{id, username, title, perfs:{:{rating, progress}}, online}]}
Example: Top 10 blitz players {"count": 10, "perf": "blitz"}
Auth: none needed.
Inputs: perf, count.
lichess_leaderboards_allARead-onlyIdempotent
Top 10 for EVERY time control and variant in a single call.
Returns: {bullet:[{id, username, title, perfs}], blitz:[…], rapid:[…], classical:[…], chess960:[…], atomic:[…], …} — one array per perf
Example: Every leaderboard at once
Auth: none needed.
Inputs: no named parameters.
lichess_tournamentsARead-onlyIdempotent
Arena tournaments — currently running, finished and upcoming.
Returns: {created:[{id, fullName, startsAt, variant, clock, nbPlayers}], started:[…], finished:[…]} — three lists by state, NOT one
Example: Arena tournaments by state
Auth: none needed.
Inputs: no named parameters.
lichess_userARead-onlyIdempotent
A Lichess player: ratings per time control and variant, games played, play time and profile.
Returns: {id, username, title, perfs:{bullet:{rating, games, rd, prog}, blitz:{…}, rapid:{…}, classical:{…}, correspondence:{…}, puzzle:{…}}, createdAt, seenAt, playTime:{total, tv}, count:{all, rated, win, loss, draw}, profile:{…}, patron, streamer} — no single 'rating': read perfs..rating
Example: One player's profile and ratings {"username": "thibault"}
Auth: none needed.
Inputs: username (required).
lichess_users_statusARead-onlyIdempotent
Online/playing status for up to 50 users in one call — who is available right now.
Returns: [{id, name, title, online, playing, streaming, patron}] (top-level array)
Example: Status of two players {"ids": ["thibault", "neio"]}
Auth: none needed.
Inputs: ids (required).
list_available_groupsARead-onlyIdempotent
List every tool group across all providers, which are currently enabled, and each provider's auth requirements (env-var names + required/optional).
On a fresh install (no groups enabled) this is the only functional tool, so the model can guide the user to enable what they want in sportsdata-mcp.yaml.
Inputs: no named parameters. Returns: object
list_resourcesARead-onlyIdempotent
List all registered MCP resources (capability map, dispatcher catalogues, reference data).
Inputs: no named parameters. Returns: object
list_tools_by_capabilityARead-onlyIdempotent
Discover tools by capability — the unit of cross-provider comparison.
Given a slug like 'sport.event_markets', returns every enabled tool exposing it across providers. Pass no argument for the full capability → tools map.
Inputs: capability. Returns: object
mfl_free_agentsARead-onlyIdempotent
Players not on any roster in this league — the pool an add or a waiver claim draws from.
Returns: {freeAgents:{leagueUnit:{unit, player:[{id, contractYear, salary}]}}} — ids only; join to mfl_players for names and to mfl_player_scores for form.
Example: Free-agent running backs {"year": 2026, "L": "10005", "POSITION": "RB"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), JSON, TYPE, +2 more.
mfl_injuriesBRead-onlyIdempotent
The NFL injury report by player id — status and body part, updated daily in season.
Returns: {injuries:{week, timestamp, injury:[{id, status:'Questionable'|'Out'|'IR'|'Inactive'|…, details:'Hamstring', exp_return}]}} — VERIFIED live 2026. id joins to mfl_players.
Example: This week's injury report {"year": 2026}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: year (required), W, JSON, TYPE.
mfl_leagueARead-onlyIdempotent
League setup: name, roster size, starting-lineup requirements, franchises, divisions, IR and taxi-squad sizes. Read this FIRST — it defines what a legal lineup is.
Returns: {league:{id, name, rosterSize, injuredReserve, taxiSquad, startWeek, endWeek, franchises:{franchise:[{id:'0001', name, owner_name}]}, starters:{count, position:[{name:'QB', limit:'1'}]}, …}}
THE THING YOU NEED: starters defines the legal formation and franchises[].id is the four-digit franchise id every write uses. Roster limits differ per league — never assume a standard shape.
Example: League setup {"year": 2026, "L": "10005"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), JSON, TYPE, +1 more.
mfl_league_standingsARead-onlyIdempotent
Current standings — record, points for and against, and the league's own standings columns.
Returns: {leagueStandings:{franchise:[{id, h2hw, h2hl, h2ht, pf, pa, vp, …}]}} — the columns vary by league configuration; COLUMN_NAMES=1 tells you what each key means.
Example: Standings with column names {"year": 2026, "L": "10005", "COLUMN_NAMES": 1}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), JSON, TYPE, +2 more.
mfl_live_scoringARead-onlyIdempotent
Live matchup state — each franchise's score, game seconds remaining, and who has yet to play.
Returns: {liveScoring:{franchise:[{id, score, gameSecondsRemaining, playersYetToPlay, playersCurrentlyPlaying}]}} — playersYetToPlay is the honest read on whether a matchup is still live.
Example: Live scores this week {"year": 2026, "L": "10005"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), W, JSON, +3 more.
mfl_my_leaguesARead-onlyIdempotent
Every league YOU are in, with your franchise id in each. Needs your cookie. The way to find the ids every other tool wants.
Returns: {leagues:{league:[{league_id, franchise_id, name, url}]}} — franchise_id is YOUR four-digit id in that league, which every write needs. Returns nothing useful without MFL_COOKIE.
Example: My leagues this season {"year": 2026}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: year (required), JSON, TYPE, FRANCHISE_NAMES.
mfl_nfl_scheduleARead-onlyIdempotent
The NFL schedule for one week — kickoff times and both teams. Which is what tells you when a player locks.
Returns: {nflSchedule:{week, matchup:[{kickoff (unix seconds), team:[{id, isHome, score, spread}]}]}} — kickoff is the lock time for that game's players. Does NOT update live during games.
Example: Week 1 fixtures {"year": 2026, "W": 1}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: year (required), W, JSON, TYPE.
mfl_pending_tradesBRead-onlyIdempotent
Trades offered to you, and trades you have offered. Needs your cookie.
Returns: {pendingTrades:{pendingTrade:[{trade_id, offeringteam, willGiveUp, willReceive, expires}]}} — trade_id is what a response quotes. Draft picks appear as DP_/FP_ tokens and blind-bid dollars as BB_.
Example: What is on the table {"year": 2026, "L": "10005"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), JSON, TYPE, +2 more.
mfl_playersARead-onlyIdempotent
Every player MFL knows: id, name, position, NFL team. The id translation table every other MFL tool depends on. LARGE.
Returns: {players:{timestamp, player:[{id, name:'Last, First', position, team}]}} — id is MFL's own player id and is what every roster, lineup and waiver call speaks. name is 'Surname, Firstname'. VERIFIED live 2026.
The full table is thousands of players; prefer PLAYERS= or SINCE= once you have ids.
Example: Look up three players by id {"year": 2026, "PLAYERS": "13593,14208,15029"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: year (required), JSON, TYPE, SINCE, +2 more.
mfl_player_scoresARead-onlyIdempotent
Fantasy points under THIS league's scoring rules — for a week, year-to-date, or a weekly average. Rostered players and free agents alike.
Returns: {playerScores:{playerScore:[{id, score, isAvailable}]}} — score is in THIS league's scoring, so it is comparable across your own players and the free-agent pool, and not comparable to any other league.
Example: Season-to-date scores for a shortlist {"year": 2026, "L": "10005", "W": "YTD", "PLAYERS": "13593,14208"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), W, JSON, +6 more.
mfl_projected_scoresARead-onlyIdempotent
Projected fantasy points for named players under this league's rules — the forward-looking number a lineup decision needs.
Returns: {projectedScores:{playerScore:[{id, score}]}} — projections come from a third party (fantasysharks) run through the league's scoring. They are an input, not a forecast to quote as fact.
Example: Project two players for the upcoming week {"year": 2026, "L": "10005", "PLAYERS": "13593,14208"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), PLAYERS (required), W, +4 more.
mfl_rostersARead-onlyIdempotent
Every franchise's roster, with each player's status (active / IR / taxi) and salary or contract if the league uses them.
Returns: {rosters:{franchise:[{id:'0001', player:[{id, status:'ROSTER'|'INJURED_RESERVE'|'TAXI_SQUAD', salary, contractYear}]}]}} — status is what an IR or taxi move changes. Join id to mfl_players for names.
Example: One franchise's roster {"year": 2026, "L": "10005", "FRANCHISE": "0001"}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), W, JSON, +3 more.
mfl_scheduleARead-onlyIdempotent
The fantasy schedule — who you play, and the score for weeks already played.
Returns: {schedule:{weeklySchedule:[{week, matchup:[{franchise:[{id, score, result, isHome}]}]}]}}
Example: This week's matchups {"year": 2026, "L": "10005", "W": 1}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), F, W, +3 more.
mfl_transactionsARead-onlyIdempotent
Completed league transactions — adds, drops, trades, waivers. Filter it: unfiltered is very large.
Returns: {transactions:{transaction:[{type, timestamp, franchise, transaction}]}} — the transaction field is a packed, comma/pipe-delimited string whose meaning depends on type.
Example: This franchise's last week of moves {"year": 2026, "L": "10005", "FRANCHISE": "0001", "DAYS": 7}
Auth: works without a key; MFL_COOKIE unlocks more if set.
Inputs: L (required), year (required), W, DAYS, +6 more.
mlb_allstar_ballotARead-onlyIdempotent
All-Star Game ballot candidates for a league + season.
Returns: {league, candidates:[{position, players:[{person, team}]}]}
Auth: none needed.
Inputs: season (required), leagueId (required).
mlb_allstar_final_voteARead-onlyIdempotent
All-Star 'Final Vote' candidates for a league + season.
Returns: {league, candidates:[{person, team, position}]}
Auth: none needed.
Inputs: season (required), leagueId (required).
mlb_allstar_writeinsARead-onlyIdempotent
All-Star write-in candidates for a league + season.
Returns: {league, writeIns:[{person, team, position}]}
Auth: none needed.
Inputs: season (required), leagueId (required).
mlb_attendanceARead-onlyIdempotent
Attendance figures for a team or league/season — per-game and aggregate home/away/total gate.
Returns: {records:[{openings, attendanceTotal, attendanceAverage, team, season}], aggregateTotals}
Auth: none needed.
Inputs: date, season, teamId, leagueId.
mlb_awardsARead-onlyIdempotent
Recipients of an award — e.g. MLBHOF (Hall of Fame), ALMVP/NLMVP, ALCY/NLCY (Cy Young), ALROY/NLROY (Rookie of the Year). Discover awardIds with mlb_awards_list.
Returns: {awards:[{id, name, season, player, team, votes}]}
Auth: none needed.
Also answers this: pl_awards.
Inputs: awardId (required), season, sportId.
mlb_awards_listARead-onlyIdempotent
Award definitions catalogue — every awardId with name, description and sport (the id lookup for mlb_awards).
Returns: {awards:[{id, name, description, sortOrder, sport, active}]}
Auth: none needed.
Inputs: sportId, leagueId.
mlb_boxscoreARead-onlyIdempotent
Full game boxscore — both teams' batting + pitching lines per player, team totals, officials and top performers.
Returns: {teams:{away:{team, teamStats, players:{ID#:{stats:{batting,pitching}, position}}}, home:{...}}, officials, topPerformers}
Auth: none needed.
Inputs: gamePk (required), timecode.
mlb_conferencesBRead-onlyIdempotent
Conference catalogue (used by some leagues / amateur levels).
Returns: {conferences:[{id, name, abbreviation, league, hasWildcard}]}
Auth: none needed.
Inputs: season, conferenceId.
mlb_datacastersBRead-onlyIdempotent
Datacaster (official scorer-adjacent stringer) assignments.
Returns: {roster:[{person, job}]}
Auth: none needed.
Also answers this: pl_match_officials.
Inputs: date, sportId.
mlb_divisionsARead-onlyIdempotent
Division catalogue (AL/NL East, Central, West) with their league + sport links.
Returns: {divisions:[{id, name, nameShort, abbreviation, league, sport}]}
Auth: none needed.
Inputs: sportId, leagueId, divisionId.
mlb_draftARead-onlyIdempotent
MLB Rule 4 draft results for a year — picks with player, school/team, position and signing info. Filter by round.
Returns: {drafts:{draftYear, rounds:[{round, picks:[{pickNumber, person, team, school, position}]}]}}
Auth: none needed.
Inputs: year (required), limit, round, teamId.
mlb_draft_prospectsBRead-onlyIdempotent
Draft prospects for a year (the pre-draft prospect board).
Returns: {prospects:[{id, rank, person, school, position}]}
Auth: none needed.
Inputs: year (required), limit, round.
mlb_free_agentsARead-onlyIdempotent
Free agents for a season — players and their from/to-team signing info.
Returns: {freeAgents:[{player, originalTeam, newTeam, dateSigned, dateDeclared, position]}]}
Auth: none needed.
Inputs: season (required), order, leagueId.
mlb_game_changesARead-onlyIdempotent
Games changed since a timestamp — a polling helper to detect updated games.
Returns: {totalItems, dates:[{games:[{gamePk, gameDate}]}]}
Auth: none needed.
Inputs: updatedSince (required), fields, sportId.
mlb_game_contentARead-onlyIdempotent
Editorial / media content for a game — highlights, recap, media, and (when present) the box-score-and-storylines bundle.
Returns: {editorial, media, highlights, summary, gameNotes}
Auth: none needed.
Inputs: gamePk (required).
mlb_game_context_metricsARead-onlyIdempotent
Context metrics for a game — leverage, win-probability and run-expectancy context for the current/most-recent state.
Returns: {game, leverageIndex, homeWinProbability, awayWinProbability}
Auth: none needed.
Inputs: gamePk (required), timecode.
mlb_game_paceARead-onlyIdempotent
Game-pace / tempo metrics for a season (pitches per game, time of game, etc.), optionally by team.
Returns: {sports:[{...pace}], teams:[{team, ...pace}], leagues:[...]}
Auth: none needed.
Inputs: season (required), sportId, teamIds.
mlb_game_uniformsARead-onlyIdempotent
Uniforms worn in one or more games.
Returns: {uniforms:[{gamePk, home:{...}, away:{...}}]}
Auth: none needed.
Inputs: gamePks (required).
mlb_game_win_probabilityARead-onlyIdempotent
Win-probability time series for a game — WP after each play, with leverage index.
Returns: [{atBatIndex, homeTeamWinProbability, awayTeamWinProbability, leverageIndex, homeTeamWinProbabilityAdded}] (top-level array)
Auth: none needed.
Also answers this: espn_core_call.
Inputs: gamePk (required), timecode.
mlb_high_lowARead-onlyIdempotent
High / low stat records for an org level — top and bottom performances for a sortStat in a season.
Returns: {highLow:[{statType, splits:[{stat, player|team}]}]}
Auth: none needed.
Inputs: season (required), orgType (required), sortStat (required), limit, +1 more.
mlb_home_run_derbyARead-onlyIdempotent
Home Run Derby bracket + results for a derby gamePk.
Returns: {info, status, rounds:[{matchups:[{topSeed, bottomSeed, ...}]}]}
Auth: none needed.
Inputs: gamePk (required).
mlb_jobsARead-onlyIdempotent
People holding a job type for a season — jobType e.g. UMPR (umpires), SCORER, DATACASTER, BROADCASTER, COACH.
Returns: {roster:[{person, jobType, job}]}
Auth: none needed.
Also answers this: pl_match_officials.
Inputs: jobType (required), season, sportId.
mlb_leadersBRead-onlyIdempotent
League leaders for one or more categories (homeRuns, battingAverage, era, strikeouts, wins, saves, ...).
Returns: {leagueLeaders:[{leaderCategory, statGroup, season, leaders:[{rank, value, person, team}]}]}
Auth: none needed.
Inputs: leaderCategories (required), limit, season, sportId, +2 more.
mlb_leaguesARead-onlyIdempotent
League catalogue — e.g. American League (103) and National League (104). Pass sportId=1 for MLB.
Returns: {leagues:[{id, name, abbreviation, sport, seasonState, hasWildCard}]}
Auth: none needed.
Inputs: seasons, sportId, leagueIds.
mlb_linescoreARead-onlyIdempotent
Game linescore — runs per inning, R/H/E totals, current inning + state, and on-base/defense for live games.
Returns: {currentInning, inningState, isTopInning, innings:[{num, home:{runs,hits,errors}, away:{...}}], teams:{home:{runs,hits,errors}, away:{...}}}
Auth: none needed.
Inputs: gamePk (required), timecode.
mlb_live_feedARead-onlyIdempotent
The complete live game feed (v1.1) — gameData (teams, players, venue, weather, probables) + liveData (boxscore, linescore, full plays). The firehose; large.
Returns: {gamePk, gameData:{teams, players, venue, weather, probablePitchers}, liveData:{plays, linescore, boxscore, decisions}}
Auth: none needed.
Inputs: gamePk (required), hydrate, timecode.
mlb_metaARead-onlyIdempotent
Meta lookup — fetch the valid values for a parameter used elsewhere (stat types, positions, game types, pitch codes, etc.). One tool over the API's /{type} endpoint.
Returns: [{...lookup rows}] (shape depends on type; e.g. positions → [{code, name, type, abbrev}])
Auth: none needed.
Inputs: type (required).
mlb_official_scorersBRead-onlyIdempotent
Official scorer assignments.
Returns: {roster:[{person, job}]}
Auth: none needed.
Also answers this: pl_match_officials.
Inputs: date, sportId.
mlb_peopleARead-onlyIdempotent
Batch player profiles for a list of personIds (the multi-id form of mlb_player).
Returns: {people:[{id, fullName, primaryNumber, birthDate, primaryPosition, batSide, pitchHand, currentTeam}]}
Auth: none needed.
Inputs: personIds (required), hydrate.
mlb_people_changesARead-onlyIdempotent
Player records changed since a timestamp — a polling/sync helper (the people-side sibling of mlb_game_changes).
Returns: {people:[{id, fullName, currentAge, birthDate, active, primaryPosition, batSide, pitchHand}]} (can be large for a wide window)
Auth: none needed.
Inputs: updatedSince (required), fields.
mlb_playbyplayARead-onlyIdempotent
Pitch-by-pitch / play-by-play log — every plate appearance with result, pitches, counts, runners and scoring-play flags.
Returns: {allPlays:[{result, about:{inning,halfInning,isScoringPlay}, matchup:{batter,pitcher}, playEvents:[...], count}], scoringPlays, currentPlay}
Auth: none needed.
Inputs: gamePk (required), timecode.
mlb_playerARead-onlyIdempotent
Player biographical profile — name, DOB, bats/throws, height/weight, position, debut, current team. One personId.
Returns: {people:[{id, fullName, primaryNumber, birthDate, currentAge, height, weight, primaryPosition, batSide, pitchHand, mlbDebutDate, currentTeam}]}
Auth: none needed.
Inputs: personId (required), hydrate.
mlb_player_game_statsARead-onlyIdempotent
One player's stat line for one specific game (batting/pitching/fielding for that gamePk).
Returns: {stats:[{group, splits:[{stat:{...}, game}]}]}
Auth: none needed.
Inputs: gamePk (required), personId (required).
mlb_player_searchARead-onlyIdempotent
Find players by name — resolves a name to personId(s) and basic bio.
Returns: {people:[{id, fullName, firstName, lastName, birthDate, primaryPosition}]}
Auth: none needed.
Inputs: names (required), limit.
mlb_player_statsARead-onlyIdempotent
One player's stats — by type (season / career / yearByYear / gameLog) and group (hitting/pitching/fielding).
Returns: {stats:[{type, group, splits:[{season, stat:{...}, team, league}]}]}
Auth: none needed.
Inputs: personId (required), group, stats, season.
mlb_scheduleARead-onlyIdempotent
Game schedule — by single date or startDate/endDate range, optionally for one team. Each game carries gamePk, status, teams and score.
Returns: {totalGames, dates:[{date, games:[{gamePk, gameDate, status, teams:{away:{team,score}, home:{team,score}}, venue}]}]}
Auth: none needed.
Inputs: date, season, teamId, endDate, +4 more.
mlb_schedule_postseasonARead-onlyIdempotent
Postseason schedule — all playoff games (optionally a single season / series type).
Returns: {totalGames, dates:[{date, games:[{gamePk, seriesDescription, teams, status}]}]}
Auth: none needed.
Inputs: season, hydrate, sportId, gameTypes.
mlb_schedule_postseason_seriesARead-onlyIdempotent
Postseason series view — games grouped by series (e.g. ALDS, NLCS, World Series).
Returns: {series:[{series:{id, gameType}, totalItems, games:[...]}]}
Auth: none needed.
Inputs: season, sportId.
mlb_schedule_postseason_tuneinARead-onlyIdempotent
Postseason broadcast 'tune-in' info (where/when to watch playoff games).
Returns: {dates:[{games:[{gamePk, broadcasts:[...]}]}]}
Auth: none needed.
Inputs: season, sportId.
mlb_schedule_tiedBRead-onlyIdempotent
Tie-breaker / tied games for a season.
Returns: {totalGames, dates:[{games:[...]}]}
Auth: none needed.
Inputs: season (required), hydrate, gameTypes.
mlb_seasonARead-onlyIdempotent
Single season detail by seasonId — key dates and game-count info.
Returns: {seasons:[{seasonId, regularSeasonStartDate, regularSeasonEndDate, postSeasonStartDate, postSeasonEndDate}]}
Auth: none needed.
Inputs: seasonId (required), sportId.
mlb_seasonsARead-onlyIdempotent
Season catalogue with key dates (regular-season start/end, postseason, etc.). Pass sportId=1.
Returns: {seasons:[{seasonId, regularSeasonStartDate, regularSeasonEndDate, seasonStartDate, seasonEndDate, preSeasonStartDate, postSeasonEndDate}]}
Auth: none needed.
Inputs: season, sportId.
mlb_seasons_allARead-onlyIdempotent
Every season in MLB history (151+) with key dates — the /seasons/all catalogue. (Plain /seasons only returns the current season; an ?all=true query there is a no-op.)
Returns: {seasons:[{seasonId, regularSeasonStartDate, regularSeasonEndDate, seasonStartDate, seasonEndDate, preSeasonStartDate, qualifierPlateAppearances, hasWildcard}]}
Auth: none needed.
Inputs: sportId, leagueId, divisionId.
mlb_sportsARead-onlyIdempotent
Sport catalogue — the sportId lookup (1 = Major League Baseball; others are MiLB levels, college, international).
Returns: {sports:[{id, code, name, abbreviation, sortOrder, activeStatus}]}
Auth: none needed.
Inputs: sportId.
mlb_sports_playersARead-onlyIdempotent
All players in a sport for a season — the full player catalogue (name → id resolution). sportId=1 for MLB.
Returns: {people:[{id, fullName, firstName, lastName, primaryNumber, birthDate, currentAge}]} (large)
Auth: none needed.
Inputs: season (required), sportId (required), hydrate.
mlb_standingsARead-onlyIdempotent
Division standings — per-team W/L, pct, GB, streak, run differential, wild-card and division ranks. Pass leagueId (103=AL, 104=NL).
Returns: {records:[{division, league, teamRecords:[{team, wins, losses, winningPercentage, gamesBack, streak, runDifferential, divisionRank, wildCardRank}]}]}
Auth: none needed.
Inputs: date, season, hydrate, leagueId, +1 more.
mlb_statsARead-onlyIdempotent
Season stats query across players — by group (hitting/pitching/fielding) and type (season, career, byDateRange, ...). Sort + limit for top-N tables.
Returns: {stats:[{type, group, splits:[{season, player, team, stat:{...}}]}]}
Auth: none needed.
Inputs: group, limit, stats, season, +4 more.
mlb_teamARead-onlyIdempotent
Single team detail by id — name, league/division, venue, colours, founding.
Returns: {teams:[{id, name, abbreviation, league, division, venue, locationName, firstYearOfPlay}]}
Auth: none needed.
Inputs: teamId (required), season, hydrate.
mlb_team_alumniARead-onlyIdempotent
Former players (alumni) for a team in a season + group (hitting/pitching/fielding).
Returns: {people:[{id, fullName, primaryPosition, mlbDebutDate}]}
Auth: none needed.
Inputs: season (required), teamId (required), group.
mlb_team_coachesBRead-onlyIdempotent
A team's coaching staff — manager, hitting/pitching/bench coaches, etc.
Returns: {roster:[{person, jobId, job, title}], teamId}
Auth: none needed.
Also answers this: espn_core_call.
Inputs: teamId (required), date, season.
mlb_team_leadersARead-onlyIdempotent
A team's statistical leaders for given categories (e.g. homeRuns, era) in a season.
Returns: {teamLeaders:[{leaderCategory, season, leaders:[{rank, value, person}]}]}
Auth: none needed.
Inputs: season (required), teamId (required), leaderCategories (required), limit, +1 more.
mlb_team_personnelBRead-onlyIdempotent
A team's front-office / non-uniformed personnel.
Returns: {roster:[{person, job, title}], teamId}
Auth: none needed.
Also answers this: espn_core_call.
Inputs: teamId (required), date.
mlb_team_rosterARead-onlyIdempotent
A team's roster — players with position and jersey number. rosterType selects active / 40-man / full-season / depth chart.
Returns: {roster:[{person:{id, fullName}, jerseyNumber, position:{abbreviation, name}, status}], teamId, rosterType}
Auth: none needed.
Inputs: teamId (required), date, season, hydrate, +1 more.
mlb_teamsARead-onlyIdempotent
Team catalogue — id, name, abbreviation, location, league/division, home venue. Pass sportId=1 for the 30 MLB clubs.
Returns: {teams:[{id, name, abbreviation, teamName, locationName, league, division, venue, firstYearOfPlay}]}
Auth: none needed.
Inputs: season, hydrate, sportId, leagueIds.
mlb_teams_affiliatesARead-onlyIdempotent
A club's affiliated teams across the minor-league levels.
Returns: {teams:[{id, name, sport, league, parentOrgId, parentOrgName}]}
Auth: none needed.
Inputs: teamIds (required), season, hydrate.
mlb_teams_historyARead-onlyIdempotent
Franchise history (name/league/division changes over time) for one or more teams.
Returns: {teams:[{id, name, season, league, division, locationName, active}]}
Auth: none needed.
Inputs: teamIds (required), endSeason, startSeason.
mlb_teams_statsARead-onlyIdempotent
Aggregate stats across all teams — league-wide team leaderboard by season + group. Sort + limit for top-N.
Returns: {stats:[{type, group, splits:[{team, stat:{...}}]}]}
Auth: none needed.
Inputs: season (required), group, limit, stats, +2 more.
mlb_team_statsARead-onlyIdempotent
One team's aggregate stats — by season + group (hitting/pitching/fielding) and stat type.
Returns: {stats:[{type, group, splits:[{season, team, stat:{...}}]}]}
Auth: none needed.
Inputs: season (required), teamId (required), group, stats, +1 more.
mlb_team_uniformsARead-onlyIdempotent
Uniform assets / descriptions for one or more teams.
Returns: {uniforms:[{teamId, uniformAssets:[{uniformAssetText, uniformAssetType, ...}]}]}
Auth: none needed.
Inputs: teamIds (required), season.
mlb_transactionsARead-onlyIdempotent
Roster transactions — signings, trades, call-ups, IL moves, DFA, etc. Filter by team, player, single date or date range.
Returns: {transactions:[{id, person, fromTeam, toTeam, date, typeCode, typeDesc, description]}]}
Auth: none needed.
Inputs: date, teamId, endDate, sportId, +2 more.
mlb_umpiresARead-onlyIdempotent
Current umpire crew list.
Returns: {roster:[{person, jobType, job}]}
Auth: none needed.
Also answers this: pl_match_officials.
Inputs: date, sportId.
mlb_venuesARead-onlyIdempotent
Venue detail for one or more venueIds — name, location, field/roof info.
Returns: {venues:[{id, name, location, fieldInfo, timeZone, active}]}
Auth: none needed.
Inputs: venueIds (required), season, hydrate.
motogp_categoriesARead-onlyIdempotent
The classes running at one event — MotoGP, Moto2, Moto3, MotoE.
Returns: [{id (uuid), name:'MotoGP™', legacy_id}] — id is the categoryUuid the session and standings tools need
Example: Classes at one Grand Prix {"eventUuid": "0f4c9f38-3e30-40f4-8a4a-9e05ba0d0daa"}
Auth: none needed.
Inputs: eventUuid (required).
motogp_eventsARead-onlyIdempotent
The Grand Prix weekends in a season, with circuit, country and dates.
Returns: [{id (uuid), name, short_name:'QAT', sponsored_name, date_start, date_end, circuit:{id, name, nation}, country:{iso, name}, season, event_files}]
Example: Completed rounds of a season {"seasonUuid": "dd12382e-1d9f-46ee-a5f7-c5104db28e43", "isFinished": true}
Auth: none needed.
Inputs: seasonUuid (required), isFinished.
motogp_seasonsARead-onlyIdempotent
Every MotoGP season (1949 →) with its uuid — the entry point to everything else.
Returns: [{id (uuid), year, current}] (top-level array, newest first) — id is the seasonUuid every other tool needs; current: true marks the live season
Example: All seasons
Auth: none needed.
Inputs: no named parameters.
motogp_session_classificationARead-onlyIdempotent
The result of one session: finishing order, rider, team, bike, time/gap and points.
Returns: {classification:[{position, points, total_laps, time, gap:{first, lap}, rider:{id, full_name, number, country}, team:{name}, constructor:{name}, average_speed, top_speed, status}], records, file}
Example: A race result {"sessionUuid": "5b0827b6-7faf-4a1b-a4c2-de630ba1941a"}
Auth: none needed.
Inputs: sessionUuid (required), test.
motogp_sessionsARead-onlyIdempotent
The sessions for one class at one event — practice, qualifying, sprint and race.
Returns: [{id (uuid), type:'RAC'|'SPR'|'Q1'|'Q2'|'FP1'|'PR', number, date, condition:{track, air, humidity, ground, weather}}] — pick type 'RAC' for the race
Example: Sessions for MotoGP at one round {"eventUuid": "0f4c9f38-3e30-40f4-8a4a-9e05ba0d0daa", "categoryUuid": "e8c110ad-64aa-4e8e-8a86-f2f152f6a942"}
Auth: none needed.
Inputs: eventUuid (required), categoryUuid (required).
motogp_standingsARead-onlyIdempotent
Championship standings for one class in one season.
Returns: {classification:[{position, points, rider:{id, full_name, number, country}, team:{name}, constructor:{name}}], file}
Example: MotoGP riders' championship {"seasonUuid": "dd12382e-1d9f-46ee-a5f7-c5104db28e43", "categoryUuid": "e8c110ad-64aa-4e8e-8a86-f2f152f6a942"}
Auth: none needed.
Inputs: seasonUuid (required), categoryUuid (required).
mysportsfeeds_boxscoreARead-onlyIdempotent
Full box score for one game, team and player level.
Returns: {game:{…}, scoring:{…}, stats:{away:{teamStats:[…], players:[{player:{id, firstName, lastName, position}, playerStats:[…]}]}, home:{…}}} — SHAPE FROM VENDOR DOCS. The game id may be given as '20240115-LAL-BOS', which is often easier than looking one up.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One game's box score {"league": "nba", "season": "current", "game": "20240115-LAL-BOS"}
Auth: needs your own key in MYSPORTSFEEDS_API_KEY.
Inputs: game (required), league (required), season (required), playerstats.
mysportsfeeds_gamesARead-onlyIdempotent
Games for a season in one league, with scores and venue.
Returns: {lastUpdatedOn, games:[{schedule:{id, week, startTime, awayTeam:{id, abbreviation}, homeTeam:{…}, venue, playedStatus}, score:{awayScoreTotal, homeScoreTotal, quarters|periods|innings:[…], currentQuarter, currentIntermission}}]} — SHAPE FROM VENDOR DOCS. NOTE identity lives under schedule and the result under score: a game is TWO nested objects, not one flat one.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: This NFL season's games {"league": "nfl", "season": "current"}
Auth: needs your own key in MYSPORTSFEEDS_API_KEY.
Inputs: league (required), season (required), date, team, +1 more.
mysportsfeeds_injuriesARead-onlyIdempotent
Current injury list for a league.
Returns: {players:[{id, firstName, lastName, position, currentTeam:{abbreviation}, currentInjury:{description, playingProbability}}]} — SHAPE FROM VENDOR DOCS. Note there is NO season segment on this path — injuries are always 'now'.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NBA injuries {"league": "nba"}
Auth: needs your own key in MYSPORTSFEEDS_API_KEY.
Inputs: league (required), team, player.
mysportsfeeds_player_gamelogsARead-onlyIdempotent
Per-game statistics for players across a season — the cleanest surface this API has.
Returns: {gamelogs:[{game:{id, startTime, awayTeamAbbreviation, homeTeamAbbreviation}, player:{id, firstName, lastName, position, jerseyNumber}, team:{id, abbreviation}, stats:{…sport-specific groups…}}]} — SHAPE FROM VENDOR DOCS. stats groups differ per sport (passing/rushing for NFL, offense/rebounds for NBA).
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A team's player game logs {"league": "nba", "season": "current", "team": ["LAL"]}
Auth: needs your own key in MYSPORTSFEEDS_API_KEY.
Inputs: league (required), season (required), date, team, +1 more.
mysportsfeeds_standingsARead-onlyIdempotent
Standings for a league and season.
Returns: {teams:[{team:{id, abbreviation, city, name}, stats:{standings:{wins, losses, winPct, gamesBack}}, divisionRank:{rank, gamesBack}, conferenceRank:{…}, overallRank:{…}}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: This season's standings {"league": "nba", "season": "current"}
Auth: needs your own key in MYSPORTSFEEDS_API_KEY.
Inputs: league (required), season (required), team.
nascar_race_listARead-onlyIdempotent
Every race in a season across all three series, with winner, track, distance, cautions and lead changes. LARGE (~430 KB).
Returns: {series_1:[{race_id, series_id, race_season, race_name, track_name, track_id, date_scheduled, scheduled_distance, actual_laps, number_of_cautions, number_of_lead_changes, average_speed, margin_of_victory, pole_winner_driver_id, winner_driver_id, attendance}], series_2:[…], series_3:[…]} — series 1=Cup, 2=Xfinity, 3=Truck
Example: 2024 season across all series {"season": 2024}
Auth: none needed.
Inputs: season (required).
nascar_weekend_feedARead-onlyIdempotent
One race weekend in full: the finishing order with laps led, points and status, plus every practice and qualifying run.
Returns: {weekend_race:[{race_id, race_name, track_name, results:[{finishing_position, starting_position, car_number, driver_fullname, team_name, laps_completed, laps_led, points_earned, status, delta_leader}], caution_segments, race_comments}], weekend_runs:[{run_type, run_name, results:[{finishing_position, driver_name, best_lap_time, best_lap_speed}]}]} — weekend_race is the race, weekend_runs is practice + qualifying. WARNING: results is NOT sorted and INCLUDES non-starters with finishing_position 0 (DNQ/DNS). Verified on the 2024 Daytona 500, where results[0] is a driver who did not qualify. The winner is the row with finishing_position == 1 — never results[0].
Example: One Cup race weekend {"season": 2024, "series": 1, "raceId": 5376}
Auth: none needed.
Inputs: raceId (required), season (required), series.
nba_boxscoreARead-onlyIdempotent
Live/final box score for one game from the CDN: per-player and per-team stat lines, by period. gameId comes from nba_scoreboard_today or nba_schedule.
Returns: {game:{gameId, homeTeam:{teamId, players:[{name, statistics}]}, awayTeam:{...}}}
Example: Box score for one game. {"gameId": "0022300001"}
Auth: none needed.
Inputs: gameId (required).
nba_daily_lineupsARead-onlyIdempotent
Projected/confirmed starting lineups for a date's games, from the stats.nba.com JS data feed. date is YYYYMMDD.
Returns: {games:[{gameId, homeTeam, awayTeam, lineups}]} (feed shape varies)
Example: Daily lineups for a date. {"date": "20260101"}
Auth: none needed.
Inputs: date (required).
nba_odds_todayARead-onlyIdempotent
Sportsbook odds for today's games from the live CDN odds feed (spread, money line, total per game and book).
Returns: {games:[{gameId, markets:[{name, books:[{name, outcomes:[...]}]}]}]}
Example: Today's game odds.
Auth: none needed.
Inputs: no named parameters.
nba_playbyplayARead-onlyIdempotent
Event-level play-by-play log for one game from the CDN: every action with clock, score, player and description. gameId from nba_scoreboard_today / nba_schedule.
Returns: {game:{gameId, actions:[{actionNumber, period, clock, scoreHome, scoreAway, description}]}}
Example: Play-by-play for one game. {"gameId": "0022300001"}
Auth: none needed.
Inputs: gameId (required).
nba_scheduleARead-onlyIdempotent
Full league schedule for the current season (every game, date, broadcasters, arena). Large payload (~8 MB) — prefer nba_scoreboard_today for just today.
Returns: {leagueSchedule:{seasonYear, gameDates:[{gameDate, games:[{gameId, homeTeam, awayTeam, ...}]}]}}
Example: Whole-season schedule.
Auth: none needed.
Inputs: no named parameters.
nba_scoreboard_todayARead-onlyIdempotent
Today's games from the live CDN scoreboard: matchups, period/clock state, live scores and game ids. The fastest way to get today's gameId values for nba_boxscore / nba_playbyplay.
Returns: {scoreboard:{gameDate, games:[{gameId, gameStatus, gameStatusText, period, gameClock, homeTeam, awayTeam}]}}
Example: Today's NBA scoreboard.
Auth: none needed.
Inputs: no named parameters.
nba_stats_callARead-onlyIdempotent
Gateway to the stats.nba.com /stats/ analytics API (138 operations). Supply an
operation (the /stats/ path segment, e.g. "leaguedashplayerstats",
"shotchartdetail", "boxscoretraditionalv3", "playercareerstats") plus a
query_params map; each operation already carries NBA's full default param set,
so override only the fields you need (e.g. {Season: "2024-25", PlayerID: "201939"}).
Browse every operation, its required params and its defaults in the
nba://stats/operations resource. Most responses are column-oriented
({resultSets:[{name, headers, rowSet}]}); zip headers with each row.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
nbl_ladderARead-onlyIdempotent
The NBL ladder (standings) for one season — 10 clubs with position, played/won/lost, points_percentage, win_percentage, points_for/against, last_5 and current streak. year is the season start year (2025 = current NBL26).
Returns: {type, count, data:[{id, position, played, won, lost, points_percentage, win_percentage, points_for, points_against, last_5, streak, team}]}
Example: Current-season ladder {"year": 2025, "seasonType": "regular"}
Auth: none needed.
Inputs: year (required), seasonType.
nbl_match_boxscoreARead-onlyIdempotent
One game's box score: final score, every player's line (minutes, points, rebounds, assists, shooting splits including four-pointers, +/-, efficiency) and team totals by quarter. Get the match id from nbl_schedule (data[].id).
Returns: {type, count, data:[{id, match_title, start_time, status, home_score, away_score, venue:{name}, home_team:{id, name, team_code}, away_team:{…}, boxscore_field_mapping:{points:'PTS', …}, player_match_statistics:[{player:{full_name, jersey_number, playing_position}, team:{team_code}, period:'0', starter, participated, minutes:'24:30', points, rebounds, assists, …}], team_match_statistics:[{team:{team_code}, period:'0'|'1'…'4', points, rebounds, …}]}]} — data is a one-element list. TEAM rows are per quarter: period '0' is the full game and '1'-'4' the quarters, so filter on period before summing or you count every point twice. Player rows are full-game (period '0'). The NBL has four-point shots, hence the four_points_* columns. Check participated to skip players who did not play. TYPES: the header's home_score/away_score are STRINGS ('86'), while every stat is a number, and percentages are fractions (0.4 = 40%), so convert before comparing a stat to the score.
Example: Tasmania JackJumpers v NZ Breakers, NBL Blitz, 6 Sep 2026 {"matchId": "3d09795f-58a7-11f1-aed3-b7a799a5060e"}
Auth: none needed.
Inputs: matchId (required).
nbl_match_outcomesARead-onlyIdempotent
Per-team match outcomes (results) for a season — win/loss rows by team, for head-to-head and form analysis.
Returns: {type, count, data:[{team, …per-match outcome rows}]}
Auth: none needed.
Inputs: year (required), seasonType.
nbl_match_playbyplayARead-onlyIdempotent
One game's full play-by-play: every event with period, game clock, shot clock, type, the player, success on shots, shot coordinates and the running score. Large: ~1,000 events for a game. Get the match id from nbl_schedule (data[].id).
Returns: {type, count, data:[{id, match_title, status, home_score, away_score, home_team:{name, team_code}, away_team:{…}, play_by_play:[{action_id, period, period_type, clock:'02:12', shot_clock, action_type:'2pt'|'3pt'|'freeThrow'|'rebound'|'foul'|'substitution'|'possession'|…, readable_action_type:'2-Point Shot - Driving Layup', success, score_1, score_2, coordinates:{x, y}, team:{team_code}, player:{full_name, jersey_number}, timestamp}]}]} — score_1 is the HOME score and score_2 the away score. success is set on shots only. player is absent on team events (possession, period markers). Free throws are freeThrow, camel-cased. About 40% of events are possession and clock bookkeeping, not plays. score_1/score_2 are integers, but the header home_score/away_score are STRINGS.
Example: Tasmania JackJumpers v NZ Breakers, NBL Blitz, 6 Sep 2026 {"matchId": "3d09795f-58a7-11f1-aed3-b7a799a5060e"}
Auth: none needed.
Inputs: matchId (required).
nbl_newsARead-onlyIdempotent
NBL news articles (latest ~200) — each with title, slug, body (HTML), excerpt, sub_headline, byline, published_date, categories/tags, a related_player and match_slug link, and featured_image_url. NOTE: this feed returns a RAW ARRAY (not the {type,count,data} envelope). Use limit to cap rows.
Returns: array of {id, status, title, slug, body, excerpt, sub_headline, byline, published_date, categories, tags, related_player, match_slug, featured_image_url, likes} (RAW ARRAY, not enveloped)
Example: Latest 10 NBL articles {"limit": 10}
Auth: none needed.
Inputs: limit.
nbl_next_matchesARead-onlyIdempotent
Upcoming matches across all NBL teams for a season (empty in the deep off-season). For the full fixture incl. completed games use nbl_schedule.
Returns: {type, count, data:[{id, start_time, round, home_team, away_team}]}
Auth: none needed.
Inputs: year (required).
nbl_player_boxscoresARead-onlyIdempotent
Game-by-game box scores for one player across a season — per match the points/rebounds/assists/blocks/steals/turnovers and playing position. The score-series / game-log source.
Returns: {type, count, data:[{period, playing_position, points, rebounds, assists, blocks, steals, turnovers}]}
Auth: none needed.
Inputs: year (required), playerId (required), seasonType.
nbl_playersARead-onlyIdempotent
All players for one season (~165) — each with jersey_number, playing_position and embedded player {id, first_name, last_name, …}, team and season objects. The player id (UUID) feeds nbl_player_stats / nbl_player_boxscores.
Returns: {type, count, data:[{jersey_number, playing_position, player:{id, first_name, last_name}, team:{id, name, team_code}, season}]}
Example: All NBL26 players {"year": 2025}
Auth: none needed.
Inputs: year (required).
nbl_player_statsARead-onlyIdempotent
Season statistics for one player — points/rebounds/assists/blocks/steals/turnovers and their per-game averages, shooting splits (field goals / three-pointers / free throws made-attempted-percentage), fouls, minutes. playerId is the player UUID from nbl_players.
Returns: {type, count, data:[{points_average, rebounds_total_average, assists_average, blocks_average, steals_average, turnovers_average, field_goals_percentage, three_pointers_percentage, free_throws_percentage, fouls_average, minutes}]}
Auth: none needed.
Inputs: playerId (required).
nbl_scheduleARead-onlyIdempotent
Every match for one season: start_time, round, status, home/away scores, attendance, venue, match_slug/title, and home_team/away_team (id, name, team_code, logo, colour). id is the match id for nbl_match_boxscore and nbl_match_playbyplay. Rows are NOT in date order, so sort by start_time. seasonType=all for the whole season.
Returns: {type, count, data:[{id, external_id, start_time, round, match_type, status:'SCHEDULED'|'CONFIRMED'|'DRAFT', match_status:'scheduled'|'complete'|'draft', home_score, away_score, attendance, match_slug, match_title, play_by_play, venue:{name}, home_team:{id, name, team_code, team_logo, color_primary}, away_team:{…}}]} — a finished game is status CONFIRMED / match_status complete. play_by_play is an id string once a game has play-by-play and null before; it is not a flag. Scores are STRINGS ('86', not 86) and null until a game is played.
Example: Full NBL27 schedule and results {"year": 2026, "seasonType": "all"}
Auth: none needed.
Inputs: year (required), limit, offset, seasonType.
nbl_season_currentARead-onlyIdempotent
The current season(s). Convenience shortcut over nbl_seasons; may return empty in the deep off-season (the call still resolves). Use limit to cap rows.
Returns: {type, count, data:[{id, name, year, season_type, external_id, start_date, end_date}]}
Auth: none needed.
Inputs: limit.
nbl_seasonsARead-onlyIdempotent
Every NBL season (~73: NBL27, NBL26, blitz/preseason/tournament variants…), each with id (UUID), name, year (season start year), season_type, the Genius external_id, and start/end dates. The discovery entry point — take a season's id for nbl_stat_leaders, or its year for the year-scoped feeds. Current regular season is the latest year with season_type=regular.
Returns: {type, count, source, data:[{id, name, year, season_type, external_id, start_date, end_date, competition}]}
Auth: none needed.
Inputs: no named parameters.
nbl_stat_leadersARead-onlyIdempotent
Season statistical leaders (points/rebounds/assists/etc. averages, per player) for one season — pass the season UUID (seasonId) from nbl_seasons (data[].id), NOT the year. Use limit to cap rows (limit=-1 for all).
Returns: {type, count, data:[{player, team, points_average, rebounds_total_average, assists_average, field_goals_percentage, three_pointers_made_average, …}]}
Example: Top 50 scorers for NBL26 {"seasonId": "1f8e4a79-e98b-457b-85a5-e4b898c6c0bd", "limit": 50, "sort": "-points_average"}
Auth: none needed.
Inputs: seasonId (required), sort, limit.
nbl_team_rosterARead-onlyIdempotent
One team's roster for a season. teamId comes from the team objects in nbl_players / nbl_schedule / nbl_ladder.
Returns: {type, count, data:[{jersey_number, playing_position, player:{id, first_name, last_name}, team}]}
Auth: none needed.
Inputs: year (required), teamId (required).
nbl_teamsARead-onlyIdempotent
The NBL club catalogue (~78 incl. historical/relocated franchises) — each with id (UUID), name, team_code, team_nickname, logos and brand colours. Join team_id from nbl_players / nbl_schedule back to here.
Returns: {type, count, data:[{id, external_id, name, team_code, team_nickname, team_logo, color_primary, color_secondary}]}
Auth: none needed.
Inputs: no named parameters.
nbl_team_statsARead-onlyIdempotent
Team statistics for a season — totals and per-game averages across assists, rebounds (offensive/defensive), blocks, steals, turnovers, and shooting (field goals / three-pointers / free throws made-attempted-percentage).
Returns: {type, count, data:[{team, assists, assists_average, defensive_rebounds, blocks, steals, turnovers, field_goals_made, field_goals_attempted, field_goals_percentage, three_pointers_percentage}]}
Example: Team stats, current season {"year": 2025, "seasonType": "regular"}
Auth: none needed.
Inputs: year (required), seasonType.
ncaa_rankingsARead-onlyIdempotent
Poll rankings — AP, coaches and others — for a college sport and division.
Returns: {sport, title, updated, page, pages, data:[{RANK, SCHOOL, POINTS, PREVIOUS, RECORD}]} — keys here are UPPERCASE, unlike standings
Example: AP football poll {"sport": "football", "division": "fbs", "poll": "associated-press"}
Auth: none needed.
Inputs: poll, sport, division.
ncaa_scoreboardARead-onlyIdempotent
Current scoreboard for one college sport and division — games with scores, state and clock.
Returns: {updated_at, games:[{game:{gameID, startDate, startTime, gameState, currentPeriod, contestClock, home:{names:{short, full}, score, winner, conferences}, away:{…}, url, network}}]} — note each entry is a one-key object wrapping game
Example: FBS football scoreboard {"sport": "football", "division": "fbs"}
Auth: none needed.
Inputs: sport, division.
ncaa_standingsARead-onlyIdempotent
Conference standings for a college sport and division.
Returns: {sport, title, updated, page, pages, data:[{conference:'ACC', standings:[{School, 'Conference W', 'Conference L', 'Overall W', 'Overall L', 'Overall PF', 'Overall PA', 'Overall HOME', 'Overall AWAY', 'Overall STREAK'}]}]} — GROUPED BY CONFERENCE: data[] is one entry per conference, each holding its own standings list. The inner column names are human-readable strings WITH SPACES and vary by sport; all values are strings.
Example: FBS football standings {"sport": "football", "division": "fbs"}
Auth: none needed.
Inputs: sport, division.
nhl_boxscoreARead-onlyIdempotent
Full box score for one game: both lineups with goals, assists, plus-minus, shots, hits, blocks and time on ice.
Returns: {id, gameDate, gameState, gameOutcome, homeTeam:{abbrev, score, sog}, awayTeam:{…}, playerByGameStats:{homeTeam:{forwards:[{playerId, name, goals, assists, points, plusMinus, sog, hits, blockedShots, toi}], defense:[…], goalies:[…]}, awayTeam:{…}}, clock, periodDescriptor}
Example: One completed game {"gameId": 2024020500}
Auth: none needed.
Inputs: gameId (required).
nhl_club_scheduleARead-onlyIdempotent
One club's entire season schedule with results — the team game log.
Returns: {games:[{id, gameDate, gameType, gameState, homeTeam:{abbrev, score}, awayTeam:{abbrev, score}, gameOutcome:{lastPeriodType}, venue, neutralSite}], currentSeason, previousSeason, nextSeason, clubTimezone} (~200 KB for a full season)
Example: Toronto's full 2024-25 season {"team": "TOR", "season": "20242025"}
Auth: none needed.
Inputs: team (required), season (required).
nhl_game_landingARead-onlyIdempotent
Game landing page: scoring summary by period, three stars, penalties and team game stats.
Returns: {id, gameDate, gameState, homeTeam, awayTeam, summary:{scoring:[{periodDescriptor, goals:[{timeInPeriod, firstName, lastName, assists, strength}]}], penalties:[…], threeStars:[…], teamGameStats:[…]}, clock}
Example: One completed game {"gameId": 2024020500}
Auth: none needed.
Inputs: gameId (required).
nhl_goalie_leadersARead-onlyIdempotent
League leaders among goalies — wins, save percentage, goals-against average and shutouts.
Returns: {wins:[{id, firstName:{default}, lastName:{default}, teamAbbrev, value, headshot}], savePctg:[…], goalsAgainstAverage:[…], shutouts:[…]}
Example: Current goalie leaders {"season_or_current": "current", "limit": 10}
Auth: none needed.
Inputs: limit, categories, season_or_current.
nhl_playerARead-onlyIdempotent
One player's landing page: bio, draft details, current season splits, career totals and awards.
Returns: {playerId, firstName, lastName, position, sweaterNumber, currentTeamAbbrev, birthDate, birthCity, birthCountry, draftDetails:{year, round, overallPick, teamAbbrev}, featuredStats, careerTotals:{regularSeason, playoffs}, seasonTotals:[…], awards:[{trophy, seasons}]}
Example: Connor McDavid {"playerId": 8478402}
Auth: none needed.
Inputs: playerId (required).
nhl_rosterARead-onlyIdempotent
A club's full roster for one season, split into forwards / defensemen / goalies with bio, height/weight, shoots-catches and birthplace.
Returns: {forwards:[…], defensemen:[…], goalies:[{id, firstName, lastName, sweaterNumber, positionCode, shootsCatches, heightInInches, weightInPounds, birthDate, birthCity, birthCountry, headshot}]} — three parallel arrays, NOT one players list
Example: Toronto's 2024-25 roster {"team": "TOR", "season": "20242025"}
Auth: none needed.
Inputs: team (required), season (required).
nhl_scheduleARead-onlyIdempotent
League schedule for the current week (or a given date's week), grouped by day.
Returns: {gameWeek:[{date, dayAbbrev, numberOfGames, games:[{id, startTimeUTC, gameState, gameType, homeTeam:{abbrev, score}, awayTeam:{…}, venue}]}], regularSeasonStartDate, regularSeasonEndDate, playoffEndDate, nextStartDate, previousStartDate}
Example: This week's games {"date": "now"}
Auth: none needed.
Inputs: date.
nhl_scoresARead-onlyIdempotent
Live scoreboard: every game on a date with current score, clock and period.
Returns: {currentDate, prevDate, nextDate, games:[{id, gameState, gameScheduleState, startTimeUTC, homeTeam:{abbrev, score, sog}, awayTeam:{…}, clock:{timeRemaining, running, inIntermission}, periodDescriptor:{number, periodType}, goals:[…]}], gameWeek:[…]}
Example: Today's scores {"date": "now"}
Auth: none needed.
Inputs: date.
nhl_seasonsARead-onlyIdempotent
Every season the standings API covers, with its start/end dates and which rules applied — call this to get valid season ids.
Returns: {currentDate, seasons:[{id:20242025, standingsStart, standingsEnd, conferencesInUse, divisionsInUse, tiesInUse, wildcardInUse, pointForOTlossInUse}]} — id is the concatenated-year season format every other tool wants
Example: All seasons
Auth: none needed.
Inputs: no named parameters.
nhl_skater_leadersARead-onlyIdempotent
League leaders among skaters — goals, assists, points, plus-minus, power-play and short-handed goals, penalty minutes, ice time.
Returns: {goals:[{id, firstName:{default}, lastName:{default}, teamAbbrev, position, value, headshot}], assists:[…], points:[…], plusMinus:[…], goalsPp:[…], goalsSh:[…], penaltyMins:[…], toi:[…]} — one array per category
Example: Current season leaders {"season_or_current": "current", "limit": 10}
Auth: none needed.
Inputs: limit, categories, season_or_current.
nhl_standingsARead-onlyIdempotent
League standings with division/conference/wildcard sequencing and clinch indicators.
Returns: {standings:[{teamName:{default}, teamAbbrev:{default}, conferenceName, divisionName, gamesPlayed, wins, losses, otLosses, points, pointPctg, goalFor, goalAgainst, goalDifferential, divisionSequence, conferenceSequence, wildcardSequence, l10Wins, streakCode, streakCount, clinchIndicator}], wildCardIndicator, standingsDateTimeUtc}
Example: Current standings {"date": "now"}
Auth: none needed.
Inputs: date.
nrl_application_settingsARead-onlyIdempotent
NRL match-centre application config: the current-season competition list (competitionList), stat-grid column layouts (dataGrids), UI components and team/competition image paths. Handy for discovering the active competitionIds and which statistics the official site surfaces.
Returns: {applicationInfo, userInfo, competitionList, components, dataGrids, shellGroups}
Example: Current NRL competition list + stat-grid config.
Auth: none needed.
Inputs: no named parameters.
nrl_competitionsARead-onlyIdempotent
Global Champion Data competition catalogue. Returns every competition id (NRL, State of Origin, plus other Champion Data sports) with its season and round count. Find the NRL competitionId here (e.g. 12999 = 2026 NRL Premiership, 13009 = 2026 State of Origin) to pass to nrl_fixture / nrl_match.
Returns: {competitionDetails:{competition:[{id, name, season, rounds, regulationPeriods, regulationPeriodLength}]}}
Example: All Champion Data competitions (filter client-side for NRL by name/season).
Auth: none needed.
Inputs: no named parameters.
nrl_fixtureARead-onlyIdempotent
Full fixture + results for one competition. One entry per match with round, status, kickoff times (local + UTC), home/away squad ids/names/scores and venue. Use it to list a round's games and to resolve the matchId for nrl_match.
Returns: {fixture:{match:[{matchId, roundNumber, matchStatus, utcStartTime, localStartTime, homeSquadId, homeSquadName, homeSquadScore, awaySquadId, awaySquadName, awaySquadScore, venueId, venueName}]}}
Example: Every 2026 NRL Premiership match (round + result). {"competitionId": 12999}
Auth: none needed.
Inputs: competitionId (required).
nrl_matchARead-onlyIdempotent
Full match file: per-player match statistics (tries, tackles, runMetres, lineBreaks, tryAssists, offloads, handlingErrors, metresGained, …), per-period player stats, team/player rosters, period durations, sin bins and on-report records. This is the per-player, per-match stat source. Decode stat codes via the nrl://stats/definitions resource.
Returns: {matchStats:{matchInfo, teamInfo:{team[]}, playerInfo:{player[]}, periodInfo:{qtr[]}, playerStats:{player[]}, playerPeriodStats:{player[]}, sinBins:{binned[]}, reports:{onReport[]}, created}, jobId}
Example: Knights v Cowboys, round 1 2026 — full player stat lines. {"competitionId": 12999, "matchId": 129990101}
Auth: none needed.
Inputs: matchId (required), competitionId (required).
oddsapiio_bookmakersBRead-onlyIdempotent
The 274 bookmakers indexed, and whether each is currently active. VERIFIED live — works without a key.
Returns: [{name:'10BET', active:true}] — VERIFIED live: 274 entries, 263 active. Names are the vendor's own spelling and are what the odds calls filter on.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every bookmaker
Auth: needs your own key in ODDS_API_IO_KEY.
Inputs: no named parameters.
oddsapiio_eventsARead-onlyIdempotent
Upcoming events for a sport or league, without prices. NEEDS A KEY.
Returns: [{id, sport, league, home, away, starts, status}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Upcoming football {"sport": "football"}
Auth: needs your own key in ODDS_API_IO_KEY.
Inputs: date, sport, league.
oddsapiio_leaguesARead-onlyIdempotent
Leagues within a sport. NEEDS A KEY.
Returns: [{id, name, country, sport}] — SHAPE FROM VENDOR DOCS, not probed.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Football leagues {"sport": "football"}
Auth: needs your own key in ODDS_API_IO_KEY.
Inputs: sport (required), country.
oddsapiio_oddsARead-onlyIdempotent
Odds for one event across the indexed bookmakers. NEEDS A KEY.
Returns: {id, home, away, starts, bookmakers:{'':{markets…}}} — SHAPE FROM VENDOR DOCS. Reported to key bookmakers by NAME rather than as a list; inspect what you receive before indexing.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One event's odds {"eventId": ""}
Auth: needs your own key in ODDS_API_IO_KEY.
Inputs: eventId (required), markets, bookmakers.
oddsapiio_sportsARead-onlyIdempotent
The 34 sports covered, with the slug every other tool needs. VERIFIED live — works without a key.
Returns: [{name:'Football', slug:'football'}] — VERIFIED live: 34 entries, slugs include football, basketball, tennis, baseball, american-football, ice-hockey, esports, darts, mixed-martial-arts, boxing, handball, volleyball, snooker, table-tennis, rugby, cricket, aussie-rules, gaelic-football, padel, bandy, golf, cycling.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every sport
Auth: needs your own key in ODDS_API_IO_KEY.
Inputs: no named parameters.
opendota_heroesARead-onlyIdempotent
The hero catalogue — id, name, primary attribute, attack type and roles.
Returns: [{id, name:'npc_dota_hero_antimage', localized_name:'Anti-Mage', primary_attr:'agi', attack_type:'Melee', roles:[str], legs}] (top-level array, ~127 heroes)
Example: All heroes
Auth: none needed.
Inputs: no named parameters.
opendota_hero_statsARead-onlyIdempotent
Per-hero win and pick counts broken down by skill bracket — the hero meta.
Returns: [{id, localized_name, pro_pick, pro_win, pro_ban, 1_pick, 1_win, …, 8_pick, 8_win}] — the numeric prefixes are skill brackets (1=lowest … 8=highest); win rate is _win / _pick, NOT a percentage field
Example: Hero meta across brackets
Auth: none needed.
Inputs: no named parameters.
opendota_leaguesARead-onlyIdempotent
Every Dota 2 league/tournament OpenDota knows. LARGE (~1 MB) — includes years of historical events.
Returns: [{leagueid, name, tier:'premium'|'professional'|'amateur', ticket, banner}] (~1 MB — filter client-side by tier)
Example: All leagues
Auth: none needed.
Inputs: no named parameters.
opendota_matchARead-onlyIdempotent
Full detail for one match: every player's hero, items, KDA, gold/XP curves and objectives. LARGE (~250 KB).
Returns: {match_id, duration, radiant_win, radiant_score, dire_score, league, players:[{account_id, hero_id, player_slot, kills, deaths, assists, gold_per_min, xp_per_min, last_hits, hero_damage, items, gold_t:[…], xp_t:[…]}], objectives, picks_bans, teamfights} — player_slot < 128 means Radiant
Example: One professional match {"match_id": 8937822821}
Auth: none needed.
Inputs: match_id (required).
opendota_playerARead-onlyIdempotent
A player's profile with rank tier and estimated MMR.
Returns: {profile:{account_id, personaname, name, avatarfull, steamid, country_code, is_pro}, rank_tier, leaderboard_rank, competitive_rank} — rank_tier is two digits: tens=medal (1 Herald … 8 Immortal), units=star
Example: One player's profile {"account_id": 88367253}
Auth: none needed.
Inputs: account_id (required).
opendota_player_heroesARead-onlyIdempotent
Which heroes a player uses and how they perform on each.
Returns: [{hero_id, games, win, with_games, with_win, against_games, against_win, last_played}] — ordered by games played; join hero_id via opendota_heroes
Example: Hero pool {"account_id": 88367253}
Auth: none needed.
Inputs: account_id (required), limit.
opendota_player_matchesARead-onlyIdempotent
A player's recent matches with hero, result and KDA.
Returns: [{match_id, player_slot, radiant_win, duration, hero_id, kills, deaths, assists, start_time, lane_role}] — you won a match when (player_slot < 128) == radiant_win
Example: Last 20 matches {"account_id": 88367253, "limit": 20}
Auth: none needed.
Inputs: account_id (required), win, limit, hero_id.
opendota_player_winlossARead-onlyIdempotent
A player's win/loss totals, with the same filters as their match list.
Returns: {win, lose} — two integers
Example: Career win/loss {"account_id": 88367253}
Auth: none needed.
Inputs: account_id (required), limit, hero_id.
opendota_pro_matchesARead-onlyIdempotent
Recent professional matches with teams, league, duration and result.
Returns: [{match_id, duration, start_time, radiant_team_id, radiant_name, dire_team_id, dire_name, leagueid, league_name, series_id, series_type, radiant_score, dire_score, radiant_win}] — Dota sides are RADIANT and DIRE, not home/away; radiant_win is the result
Example: Latest pro matches
Auth: none needed.
Inputs: less_than_match_id.
opendota_public_matchesARead-onlyIdempotent
A sample of recent public (non-professional) matches — the ladder meta rather than the pro scene.
Returns: [{match_id, start_time, duration, avg_rank_tier, radiant_win, radiant_team:[hero_id], dire_team:[hero_id]}] — hero ids only, no player identity
Example: Recent public matches
Auth: none needed.
Inputs: min_rank, less_than_match_id.
opendota_teamsARead-onlyIdempotent
Professional teams ranked by rating, with win/loss records.
Returns: [{team_id, name, tag, rating, wins, losses, last_match_time, logo_url}] (~250 KB, ordered by rating)
Example: Pro teams by rating
Auth: none needed.
Inputs: no named parameters.
openf1_car_dataARead-onlyIdempotent
Car telemetry at ~3.7 Hz — speed, throttle, brake, gear, RPM, DRS. HIGH VOLUME: always pass session_key + driver_number.
Returns: [{date, driver_number, speed, throttle, brake, n_gear, rpm, drs, session_key}] (top-level array; large — use date>=/date<= operators on the raw API to window it)
Auth: none needed.
Inputs: session_key (required), driver_number (required), meeting_key.
openf1_championship_driversARead-onlyIdempotent
Drivers' championship standings around a race — points and position before/after the session.
Returns: [{driver_number, position_start, position_current, points_start, points_current, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), meeting_key, driver_number.
openf1_championship_teamsARead-onlyIdempotent
Constructors' championship standings around a race — points and position before/after the session.
Returns: [{team_name, position_start, position_current, points_start, points_current, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), team_name, meeting_key.
openf1_driversARead-onlyIdempotent
Drivers entered in a session — number, name, acronym, team and colours. Pass session_key (or 'latest').
Returns: [{driver_number, full_name, name_acronym, broadcast_name, team_name, team_colour, headshot_url, session_key, meeting_key}] (top-level array)
Auth: none needed.
Inputs: team_name, meeting_key, session_key, name_acronym, +1 more.
openf1_intervalsARead-onlyIdempotent
Live gap data during a race — each driver's gap to the leader and interval to the car ahead, sampled over time.
Returns: [{date, driver_number, gap_to_leader, interval, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), meeting_key, driver_number.
openf1_lapsARead-onlyIdempotent
Per-lap timing for a driver — lap + sector durations, speed-trap (i1/i2/st) speeds, mini-sector segment colours, pit-out flag.
Returns: [{driver_number, lap_number, lap_duration, duration_sector_1/2/3, i1_speed, i2_speed, st_speed, is_pit_out_lap, segments_sector_1/2/3, date_start}] (top-level array)
Auth: none needed.
Inputs: session_key (required), lap_number, meeting_key, driver_number.
openf1_locationARead-onlyIdempotent
Car (x, y, z) track position at ~3.7 Hz. HIGH VOLUME: always pass session_key + driver_number (and ideally a date window on the raw API).
Returns: [{date, driver_number, x, y, z, session_key}] (top-level array; large)
Auth: none needed.
Inputs: session_key (required), driver_number (required), meeting_key.
openf1_meetingsARead-onlyIdempotent
Grand Prix weekends (meetings). Filter by year/country, or pass meeting_key=latest for the current event.
Returns: [{meeting_key, meeting_name, meeting_official_name, country_name, country_code, circuit_short_name, location, year, date_start}] (top-level array)
Auth: none needed.
Inputs: year, meeting_key, country_name, meeting_name.
openf1_overtakesARead-onlyIdempotent
Overtake events in a race — who passed whom, when, and for which position.
Returns: [{date, overtaking_driver_number, overtaken_driver_number, position, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), meeting_key, overtaken_driver_number, overtaking_driver_number.
openf1_pitARead-onlyIdempotent
Pit stops — lap, total time in pit lane and stationary stop duration per driver.
Returns: [{date, driver_number, lap_number, pit_duration, lane_duration, stop_duration, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), lap_number, meeting_key, driver_number.
openf1_positionARead-onlyIdempotent
Driver track position over time — position changes throughout a session.
Returns: [{date, driver_number, position, session_key, meeting_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), position, meeting_key, driver_number.
openf1_race_controlARead-onlyIdempotent
Race-control messages — flags, safety cars, incidents, investigations, penalties — the official message feed.
Returns: [{date, category, flag, scope, sector, lap_number, driver_number, message, session_key}] (top-level array)
Auth: none needed.
Inputs: flag, category, lap_number, meeting_key, +2 more.
openf1_session_resultARead-onlyIdempotent
Final classification of a session — per-driver position, laps, points, gap, DNF/DNS/DSQ flags.
Returns: [{position, driver_number, number_of_laps, points, dnf, dns, dsq, duration, gap_to_leader, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), position, meeting_key, driver_number.
openf1_sessionsARead-onlyIdempotent
F1 sessions (Practice / Qualifying / Sprint / Race). This is the fixtures feed — filter by year, country or session_name to find a session_key.
Returns: [{session_key, session_name, session_type, date_start, date_end, meeting_key, circuit_short_name, country_name, year}] (top-level array)
Auth: none needed.
Inputs: year, meeting_key, session_key, country_name, +3 more.
openf1_starting_gridARead-onlyIdempotent
Race starting grid — per-driver grid position and lap time. (Sparse feed: OpenF1 returns a 404 'No results found' for sessions where no grid is published, which is currently most of them.)
Returns: [{position, driver_number, lap_duration, session_key, meeting_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), position, meeting_key.
openf1_stintsARead-onlyIdempotent
Tyre stints — compound and tyre age per driving period (lap_start → lap_end).
Returns: [{stint_number, driver_number, lap_start, lap_end, compound, tyre_age_at_start, session_key}] (top-level array)
Auth: none needed.
Inputs: session_key (required), compound, meeting_key, driver_number.
openf1_team_radioBRead-onlyIdempotent
Team-radio clips — recording URLs of driver/pit-wall radio exchanges during a session.
Returns: [{date, driver_number, recording_url, session_key, meeting_key}] (top-level array)
Auth: none needed.
Also answers this: afl_live_audio.
Inputs: meeting_key, session_key, driver_number.
openf1_weatherARead-onlyIdempotent
Track weather, updated ~once a minute — air/track temperature, humidity, pressure, wind, rainfall.
Returns: [{date, air_temperature, track_temperature, humidity, pressure, wind_speed, wind_direction, rainfall, session_key}] (top-level array)
Auth: none needed.
Inputs: meeting_key, session_key.
openligadb_current_matchdayARead-onlyIdempotent
Which matchday a league is currently on — resolve 'this week' without guessing.
Returns: {groupID, groupName:'1. Spieltag', groupOrderID} — a single object, not a list
Example: Current Bundesliga matchday {"league": "bl1"}
Auth: none needed.
Inputs: league.
openligadb_leaguesARead-onlyIdempotent
Every competition + season OpenLigaDB carries — call this to find the league shortcut and season year the other tools need.
Returns: [{leagueId, leagueName, leagueShortcut:'bl1', leagueSeason:'2024', sport:{sportId, sportName}}] (~819 entries, ~120 KB)
Example: All competitions
Auth: none needed.
Inputs: no named parameters.
openligadb_matchARead-onlyIdempotent
One match by id, with goals and scorers.
Returns: {matchID, matchDateTime, team1, team2, matchIsFinished, matchResults:[…], goals:[{goalID, scoreTeam1, scoreTeam2, matchMinute, goalGetterName, isPenalty, isOwnGoal}], location}
Example: A single match {"matchId": 66222}
Auth: none needed.
Inputs: matchId (required).
openligadb_matchday_matchesARead-onlyIdempotent
One matchday's fixtures and results — the everyday call.
Returns: Same shape as openligadb_season_matches, restricted to one matchday (~9 matches for the Bundesliga)
Example: Matchday 1 of 2024/25 {"league": "bl1", "season": "2024", "matchday": 1}
Auth: none needed.
Inputs: season (required), matchday (required), league.
openligadb_matchdaysARead-onlyIdempotent
The matchdays ('groups') in a season — OpenLigaDB calls a Spieltag a 'group'.
Returns: [{groupID, groupName:'1. Spieltag', groupOrderID}] — groupOrderID is the matchday number the match tools take
Example: Bundesliga matchdays {"league": "bl1", "season": "2024"}
Auth: none needed.
Inputs: season (required), league.
openligadb_season_matchesARead-onlyIdempotent
Every match in a league season with results. LARGE (~550 KB for a Bundesliga season) — prefer the matchday tool.
Returns: [{matchID, matchDateTime, matchDateTimeUTC, timeZoneID, leagueName, leagueSeason, group:{groupName, groupOrderID}, team1:{teamId, teamName}, team2:{…}, matchIsFinished, matchResults:[{resultName:'Endergebnis'|'Halbzeit', pointsTeam1, pointsTeam2}], goals:[…], location}]
Example: Whole 2024/25 Bundesliga season {"league": "bl1", "season": "2024"}
Auth: none needed.
Inputs: season (required), league.
openligadb_tableARead-onlyIdempotent
The league table for a season.
Returns: [{teamInfoId, teamName, shortName, points, opponentGoals, goals, matches, won, lost, draw, goalDiff, teamIconUrl}] — ordered top to bottom; goals is scored, opponentGoals is conceded
Example: Bundesliga table {"league": "bl1", "season": "2024"}
Auth: none needed.
Inputs: season (required), league.
openligadb_teamsARead-onlyIdempotent
The clubs contesting one league season.
Returns: [{teamId, teamName, shortName, teamIconUrl, teamGroupName}]
Example: 2024/25 Bundesliga clubs {"league": "bl1", "season": "2024"}
Auth: none needed.
Inputs: season (required), league.
pandascore_leaguesARead-onlyIdempotent
Leagues (the recurring competitions tournaments belong to).
Returns: [{id, name, slug, image_url, url, videogame:{id, name, slug}, series:[…]}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All leagues
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, per_page, filter_videogame.
pandascore_matchesARead-onlyIdempotent
Matches across every title, or one — upcoming, running or past.
Returns: [{id, name, slug, status, begin_at, end_at, number_of_games, opponents:[{type, opponent:{id, name, acronym, image_url}}], results:[{team_id, score}], league:{id, name}, serie, tournament, videogame, winner_id, live:{supported, url}}] (top-level array; totals in X-Total header) — SHAPE FROM VENDOR DOCS. Note opponents wraps each team under an opponent key.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Upcoming CS2 matches {"filter_videogame": "csgo", "filter_status": "not_started"}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, sort, per_page, filter_status, +2 more.
pandascore_match_oddsARead-onlyIdempotent
Betting markets and prices for one esports match — the part opendota cannot give you.
Returns: {match_id, markets:[{name, bookmakers:[{name, odds:[{name, value, ...}]}]}]} — SHAPE FROM VENDOR DOCS AND LIKELY APPROXIMATE; odds access is a paid add-on on some plans, so a free key may 403 here.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Odds for one match {"matchId": 1}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: matchId (required).
pandascore_playersARead-onlyIdempotent
Esports players with role, nationality and current team.
Returns: [{id, name, first_name, last_name, role, nationality, image_url, current_team:{id, name, acronym}, current_videogame}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Dota 2 players {"filter_videogame": "dota2"}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, per_page, search_name, filter_videogame.
pandascore_seriesARead-onlyIdempotent
Series — a league's seasonal editions (e.g. 'LEC Summer 2025').
Returns: [{id, name, full_name, slug, season, year, begin_at, end_at, league:{id, name}, videogame, winner_id}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: LoL series {"filter_videogame": "lol"}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, per_page, filter_videogame.
pandascore_teamsARead-onlyIdempotent
Esports teams with their current rosters.
Returns: [{id, name, acronym, slug, image_url, location, current_videogame, players:[{id, name, first_name, last_name, role, nationality}]}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: CS2 teams {"filter_videogame": "csgo"}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, per_page, search_name, filter_videogame.
pandascore_tournamentsARead-onlyIdempotent
Tournaments — upcoming, running or past — optionally for one title.
Returns: [{id, name, slug, begin_at, end_at, prizepool, tier, league:{id, name}, serie:{id, full_name}, videogame, teams:[…]}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: LoL tournaments {"filter_videogame": "lol"}
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: page, per_page, filter_videogame.
pandascore_videogamesARead-onlyIdempotent
The titles PandaScore covers, with the slug every other tool needs. Call this first rather than guessing a slug.
Returns: [{id, name:'Counter-Strike', slug:'cs-go', current_version}] (top-level array) — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: All titles
Auth: needs your own key in PANDASCORE_TOKEN.
Inputs: no named parameters.
pinnacle_carouselARead-onlyIdempotent
Featured matchups carousel across all sports (homepage highlights).
Returns: [{id, league:{name}, participants:[{name}], startTime, hasMarkets, hasLive}] (top-level array)
Auth: none needed.
Inputs: no named parameters.
pinnacle_enumsARead-onlyIdempotent
Reference enums (countries, currencies, occupations, etc.) used across the API.
Returns: {countries:[{code2, code3, legalAge, license:{name}}], ...}
Auth: none needed.
Inputs: no named parameters.
pinnacle_labelsARead-onlyIdempotent
Per-sport market-label dictionary — decodes market keys/types into human names (moneyline → 'Match Odds', etc.).
Returns: [{sport, labels:[{marketLabels:[{full, short, type}]}]}] (top-level array, one per sport)
Auth: none needed.
Inputs: no named parameters.
pinnacle_league_matchupsARead-onlyIdempotent
All matchups for one league (competition) — e.g. every NBA game on the board.
Returns: [{id, league:{name}, participants:[{name, alignment}], startTime, hasMarkets, isLive}] (top-level array)
Auth: none needed.
Inputs: leagueId (required).
pinnacle_league_matchups_liveARead-onlyIdempotent
Live (in-play) matchups for one league (competition).
Returns: [{id, league:{name}, participants:[{name}], startTime, isLive, liveMode}] (top-level array; empty when nothing live)
Auth: none needed.
Inputs: leagueId (required).
pinnacle_matchupARead-onlyIdempotent
One matchup's detail: participants, league, periods, start time, state.
Returns: {id, league:{name}, participants:[{name, alignment}], periods:[...], startTime, state, type, rotation}
Auth: none needed.
Inputs: matchupId (required).
pinnacle_matchup_marketsARead-onlyIdempotent
All straight (non-parlay) markets + American-odds prices for one matchup and its related markets.
Returns: [{key, matchupId, period, cutoffAt, isAlternate, limits:[{amount, type}], prices:[{designation, points, price}]}] (top-level array; price is American odds)
Auth: none needed.
Inputs: matchupId (required).
pinnacle_matchup_parlay_marketsARead-onlyIdempotent
Parlay (same-game multi) markets + prices for one matchup and its related markets.
Returns: Same shape as pinnacle_matchup_markets: [{key, type, period, prices:[{designation, price}], limits, status, cutoffAt}]. Prices are AMERICAN odds.
⚠ VERIFIED 2026-08-30: this returns data IDENTICAL to pinnacle_matchup_markets — same markets, same prices, same limits, byte-for-byte on every matchup tested. Pinnacle does NOT apply a correlation adjustment to parlays, so a combination's price is simply the PRODUCT of its legs and there is nothing extra to fetch. Do not present this as a distinct 'parlay price'.
Before offering any combination, read parlayRestriction on the matchup itself (from pinnacle_sport_matchups): unique_matchups means legs must come from DIFFERENT games, forbidden means no parlay, and only allowed permits a same-game multi — 42 of 16,040 matchups surveyed.
Auth: none needed.
Inputs: matchupId (required).
pinnacle_sport_leaguesARead-onlyIdempotent
Leagues (competitions) for one sport, with feature/group info.
Returns: [{id, name, group, isFeatured, matchupCount}] (top-level array)
Example: Baseball leagues {"sportId": 3}
Auth: none needed.
Inputs: sportId (required).
pinnacle_sport_matchupsARead-onlyIdempotent
Highlighted matchups for one sport (teams, league, start time, market flags).
Returns: [{id, league:{name}, participants:[{name, alignment}], startTime, hasMarkets, isLive}] (top-level array)
Example: Highlighted baseball matchups {"sportId": 3}
Auth: none needed.
Inputs: sportId (required).
pinnacle_sport_matchups_allARead-onlyIdempotent
All matchups for one sport (the full list, not just highlighted).
Returns: [{id, league:{name}, participants:[{name, alignment}], startTime, hasMarkets, isLive}] (top-level array)
Example: All baseball matchups {"sportId": 3}
Auth: none needed.
Inputs: sportId (required).
pinnacle_sport_matchups_liveARead-onlyIdempotent
Live (in-play) matchups for one sport.
Returns: [{id, league:{name}, participants:[{name}], startTime, isLive, liveMode}] (top-level array)
Auth: none needed.
Inputs: sportId (required).
pinnacle_sportsARead-onlyIdempotent
All sports with their matchup counts and primary market type.
Returns: [{id, name, primaryMarketType, matchupCount, isFeatured, isHidden}] (top-level array)
Auth: none needed.
Inputs: no named parameters.
pinnacle_sports_liveARead-onlyIdempotent
Sports that currently have live (in-play) matchups.
Returns: [{id, name, matchupCount, primaryMarketType}] (top-level array)
Auth: none needed.
Inputs: no named parameters.
pinnacle_statusARead-onlyIdempotent
API system status (online/offline + per-service health).
Returns: {code, description, services:[{name, status}]}
Auth: none needed.
Inputs: no named parameters.
pl_awardsARead-onlyIdempotent
Season awards — Player/Manager of the Month and other honours for a season.
Returns: {player_awards:[…], manager_awards:[…]}
Auth: none needed.
Also answers this: mlb_awards.
Inputs: cid (required), sid (required).
pl_broadcasting_eventsARead-onlyIdempotent
TV/broadcast schedule for a date range (ISO 8601 UTC).
Returns: {pageInfo, content:[{match/broadcast schedule entries}]}
Auth: none needed.
Inputs: toDate, fromDate, pageSize.
pl_broadcast_match_eventsARead-onlyIdempotent
Broadcast events for a specific match (sportDataId = SDP match id).
Returns: {pageInfo, content:[{broadcast entries for the match}]}
Auth: none needed.
Inputs: sportDataId (required), pageSize.
pl_clubs_metadataARead-onlyIdempotent
Club metadata (names, stadiums, websites, colours) for theming — static config blob.
Returns: [{id, name, stadium, website}] (top-level array)
Auth: none needed.
Inputs: no named parameters.
pl_competitionARead-onlyIdempotent
One competition by id (8 = Premier League).
Returns: {id, code, name}
Auth: none needed.
Inputs: cid (required).
pl_competitionsARead-onlyIdempotent
All competitions on the platform (Premier League = id 8). Paginated.
Returns: {pagination, data:[{id, code, name}]}
Auth: none needed.
Inputs: limit, next_cursor.
pl_contentARead-onlyIdempotent
Content list/search (articles, video, photos) — filter by content types, entity references (SDP_FOOTBALL_MATCH/PLAYER/TEAM) and tags.
Returns: {pageInfo, content:[{id, type, title, description, date, references, tags}]}
Example: Latest articles + videos {"lang": "en", "contentTypes": "TEXT,VIDEO", "limit": 5}
Auth: none needed.
Inputs: lang (required), limit, detail, offset, +4 more.
pl_content_itemARead-onlyIdempotent
One content item by type + id (TEXT/VIDEO/PHOTO/PLAYLIST/PROMO/AUDIO).
Returns: {id, type, title, description, date, body, ...}
Auth: none needed.
Inputs: lang (required), type (required), contentId (required), detail.
pl_countryARead-onlyIdempotent
Echoes the caller's detected country (used by the site for content geo-gating).
Returns: {country}
Auth: none needed.
Inputs: no named parameters.
pl_current_gameweekARead-onlyIdempotent
The current matchweek number (static config blob).
Returns: {matchweek}
Auth: none needed.
Inputs: no named parameters.
pl_matchARead-onlyIdempotent
Single match detail (match centre) — richer than the list item; adds seasonInfo.
Returns: {matchId, competitionId, competition, seasonInfo, matchWeek, phase, kickoff, period, clock, ground, attendance, homeTeam, awayTeam, resultType}
Auth: none needed.
Inputs: id (required).
pl_match_commentaryARead-onlyIdempotent
Live text commentary feed for a match (paginated).
Returns: {pagination, data:[{type, time, timestamp, comment, team1, team2}]}
Auth: none needed.
Inputs: id (required), sort, limit, next_cursor.
pl_matchesARead-onlyIdempotent
Primary fixtures/results feed — filter by competition, season, matchweek, team, period (PreMatch/Live/FullTime) or a kickoff date range. Paginated.
Returns: {pagination, data:[{matchId, competition, season, matchWeek, phase, kickoff, period, clock, ground, attendance, homeTeam:{id, name, score, halfTimeScore}, awayTeam, resultType}]}
Example: 2025/26 matchweek 1 results {"competition": 8, "season": 2025, "matchweek": 1, "limit": 10}
Auth: none needed.
Inputs: sort, team, limit, period, +6 more.
pl_match_eventsARead-onlyIdempotent
Match events — goals, cards, subs split by home/away team, each with playerId, time, period, timestamp.
Returns: {homeTeam:[{type, playerId, time, period, timestamp}], awayTeam:[…]}
Auth: none needed.
Inputs: id (required).
pl_match_lineupsARead-onlyIdempotent
Match lineups — home_team/away_team players[] with formation and subs.
Returns: {home_team:{players, formation, subs}, away_team:{…}}
Auth: none needed.
Also answers this: seriea_match_lineups.
Inputs: id (required).
pl_match_officialsARead-onlyIdempotent
Match officials — referee, assistants, fourth official, VAR.
Returns: {matchId, matchOfficials:[{role, name, …}]}
Auth: none needed.
Inputs: id (required).
pl_match_statsARead-onlyIdempotent
Full team match stats — one block per side with ~200 granular Opta metrics (possession, shots, xG, passes, tackles, …).
Returns: [{side: Home, teamId, stats:{possessionPercentage, totalScoringAtt, expectedGoals, accuratePass, totalTackle, …}}, {side: Away, …}] (top-level array of 2)
Auth: none needed.
Inputs: id (required).
pl_matchweek_matchesARead-onlyIdempotent
Matches for one matchweek (v1 path alternative to pl_matches?matchweek=).
Returns: {pagination, data:[{matchId, kickoff, homeTeam, awayTeam, ground, period}]}
Auth: none needed.
Inputs: mw (required), cid (required), sid (required), limit.
pl_metadataARead-onlyIdempotent
Generic entity metadata (external/fantasy profile links). type ∈ SDP_FOOTBALL_PLAYER, SDP_FOOTBALL_TEAM.
Returns: {metadata:{…external links / fantasy ids}}
Auth: none needed.
Inputs: mid (required), type (required).
pl_news_latestARead-onlyIdempotent
Latest news, smart-ranked (homepage feed).
Returns: [{title, author, body, contentSummary, canonicalUrl, date}] (top-level array)
Example: Latest news {"limit": 5}
Auth: none needed.
Inputs: tags, limit.
pl_news_popularARead-onlyIdempotent
Popular news over the last recency hours, smart-ranked.
Returns: [{title, author, contentSummary, canonicalUrl, date}] (top-level array)
Auth: none needed.
Inputs: limit, recency.
pl_playerARead-onlyIdempotent
Full player career — one entry per club/season spell with dates, height/weight, shirtNum, preferredFoot, position.
Returns: [{id, name, position, currentTeam, country, countryOfBirth, height, dates}] (top-level array, one per spell)
Auth: none needed.
Inputs: pid (required).
pl_player_basicARead-onlyIdempotent
Lightweight player profile — name, position, country, currentTeam.
Returns: {id, name, firstName, lastName, position, country, currentTeam}
Auth: none needed.
Inputs: pid (required).
pl_player_comp_statsARead-onlyIdempotent
A player's career stats aggregated across the competition (all seasons).
Returns: {player, stats:{…Opta player metrics: goals, goalAssists, expectedGoals, totalPasses, …}}
Auth: none needed.
Inputs: cid (required), pid (required).
pl_player_infoARead-onlyIdempotent
Player bio scoped to a season — team/shirt/dates as they were that season.
Returns: {id, name, currentTeam, shirtNum, country, countryOfBirth, weight, dates}
Auth: none needed.
Inputs: cid (required), pid (required), sid (required).
pl_player_leaderboardARead-onlyIdempotent
Player stat leaderboard for a season — sort by any Opta metric (goals, goal_assists, clean_sheets, total_passes, …); filter by position. Each row: {playerMetadata, stats}.
Returns: {pagination, data:[{playerMetadata:{id, name, position, team}, stats:{goals, goalAssists, …}}]}
Example: 2025/26 top scorers {"cid": 8, "sid": 2025, "sort": "goals:desc", "limit": 10}
Auth: none needed.
Inputs: cid (required), sid (required), sort, limit, +2 more.
pl_playersARead-onlyIdempotent
Player directory for a season (paginated; the Players index page).
Returns: {pagination, data:[{id, name, position, country, currentTeam, shirtNum, preferredFoot}]}
Example: First page of 2025/26 players {"cid": 8, "sid": 2025, "limit": 10}
Auth: none needed.
Inputs: cid (required), sid (required), limit, position, +1 more.
pl_players_by_idARead-onlyIdempotent
Batch player lookup by a list of ids (hydrates lineups/squads).
Returns: [{id, name, firstName, lastName}] (top-level array)
Auth: none needed.
Inputs: id (required).
pl_player_season_statsBRead-onlyIdempotent
A player's stats for one season.
Returns: {player, stats:{…season Opta metrics}}
Auth: none needed.
Inputs: cid (required), pid (required), sid (required).
pl_season_teamsARead-onlyIdempotent
The teams in a given season (the 20 in that season's table).
Returns: {pagination, data:[{id, name, shortName, abbr, stadium}]}
Auth: none needed.
Inputs: cid (required), sid (required), limit.
pl_squadARead-onlyIdempotent
Full squad for a team in a season — players[] with name, shirtNum, position, height/weight, dates, country.
Returns: {id, team, players:[{id, name, shirtNum, position, height, weight, country, dates}]}
Auth: none needed.
Inputs: cid (required), sid (required), tid (required).
pl_standingsARead-onlyIdempotent
The league table for a season. Each entry has overall/home/away blocks (position, played, won, drawn, lost, GF, GA, points). live=true folds in in-progress matches.
Returns: {matchweek, season, competition, live, deductions, tables:[{entries:[{team, overall:{position, played, won, drawn, lost, goalsFor, goalsAgainst, points}, home, away}]}]}
Example: 2025/26 Premier League table {"cid": 8, "sid": 2025, "live": false}
Auth: none needed.
Inputs: cid (required), sid (required), live.
pl_structureARead-onlyIdempotent
Season structure — current phase + phase/matchweek layout for one season.
Returns: {currentPhase, structure}
Auth: none needed.
Inputs: cid (required), sid (required).
pl_teamARead-onlyIdempotent
One team within a competition by id.
Returns: {name, shortName, abbreviation, player_id}
Auth: none needed.
Inputs: cid (required), tid (required).
pl_team_formARead-onlyIdempotent
One team's recent matches/form within a season.
Returns: [{kickoff, homeTeam, awayTeam, competition, ground, clock, attendance}] (top-level array of matches)
Auth: none needed.
Inputs: cid (required), sid (required), tid (required), seasons, +1 more.
pl_teamformARead-onlyIdempotent
Every team's form for the season in one call (the table's form guide) — recent results + next fixture per team.
Returns: [{id, name, shortName, abbr, form, next}] (top-level array, one per team)
Auth: none needed.
Inputs: cid (required), sid (required).
pl_team_leaderboardARead-onlyIdempotent
Team stat leaderboard — sort by any Opta team metric. NOTE: season is a query param here, not a path segment. Each row: {teamMetadata, stats}.
Returns: {pagination, data:[{teamMetadata:{id, name}, stats:{…team Opta metrics}}]}
Example: 2025/26 teams by tackles won {"cid": 8, "season": 2025, "sort": "tackles_won:desc", "limit": 10}
Auth: none needed.
Inputs: cid (required), season (required), sort, limit.
pl_team_next_fixtureARead-onlyIdempotent
A team's next scheduled fixture. Returns 404 when none is scheduled (e.g. off-season).
Returns: {kickoff, homeTeam, awayTeam, ground, competition} (404 when no fixture scheduled)
Auth: none needed.
Inputs: cid (required), sid (required), tid (required).
pl_teamsARead-onlyIdempotent
All teams that have played the competition, each with seasons[], stadium, name, shortName, abbr, id. Paginated.
Returns: {pagination, data:[{id, name, shortName, abbr, stadium, seasons}]}
Example: All Premier League teams {"cid": 8}
Auth: none needed.
Inputs: cid (required), limit, next_cursor.
pl_teams_by_idARead-onlyIdempotent
Batch team lookup by a list of ids.
Returns: [{id, name, shortName, abbr, stadium}] (top-level array)
Auth: none needed.
Inputs: id (required).
pl_team_statsARead-onlyIdempotent
Team aggregate stats (all-time in the competition) — ~130 Opta metrics.
Returns: {team, stats:{…Opta team metrics: goals, possessionPercentage, passingAccuracy, totalShots, …}}
Auth: none needed.
Inputs: cid (required), tid (required).
pl_video_latestARead-onlyIdempotent
Latest video, smart-ranked.
Returns: [{title, canonicalUrl, date, duration, …}] (top-level array)
Example: Latest video {"limit": 5}
Auth: none needed.
Inputs: tags, limit.
pl_video_popularARead-onlyIdempotent
Popular video over the last recency hours.
Returns: [{title, canonicalUrl, date}] (top-level array)
Auth: none needed.
Inputs: limit, recency.
pointsbet_competition_eventsARead-onlyIdempotent
Featured events for one competition (paged) with their insight/featured markets.
Returns: {key, name, nextPage, events:[{key, name, insightMarkets:[], featuredMarkets:[]}]}
Example: AFL competition events, first page {"competitionKey": 7523, "page": 1}
Auth: none needed.
Inputs: competitionKey (required), page.
pointsbet_content_callARead-onlyIdempotent
Fetch one of PointsBet's static CMS / navigation JSON assets from pointsbet.com.au by operation name (no params). These drive the site's menus, tiles, logo mappings, build manifest and maintenance banner. Read pointsbet://content/operations for the operation list.
Returns: (JSON object)
Auth: none needed.
Inputs: operation (required), path_params, query_params.
pointsbet_eventARead-onlyIdempotent
Full event detail: all fixed-odds markets + selections + prices, SGM, team stats, insights.
Returns: {key, name, competitionName, startsAt, sgmStatus, fixedOddsMarkets:[{key, name, eventClass, enableCorrelatedMulti, outcomes:[{key, name, price, isOpenForBetting}]}], sgmCollisionGroups:[], prePricedSgm:{}, homeTeamStats:{}} — 82 markets and ~4MB on a verified AFL fixture, so ask for the markets you need rather than the whole event where you can.
THIS IS WHERE SGM LEG IDS COME FROM: fixedOddsMarkets[].key is the MarketKey and its own outcomes[].key is the OutcomeKey that pointsbet_sgm_price wants. Outcome keys repeat across markets, so only the pair identifies a leg. sgmStatus: "Available" says the event sells same game multis at all; enableCorrelatedMulti on a market does NOT say the market is eligible (it was true on all 82 while the pricer still refused First Goalscorer), and sgmCollisionGroups lists the families that overwrite one another.
Auth: none needed.
Inputs: eventKey (required).
pointsbet_event_searchARead-onlyIdempotent
Search sport events by class / competition, optionally with historic head-to-head stats.
Returns: {events:[{key, name, competitionKey, startsAt, homeTeam, awayTeam}]}
Example: AFL events with historic stats {"competitionKey": 7523, "numberOfSportEvents": 50, "includeHistoricStats": true}
Auth: none needed.
Inputs: eventClassIds, competitionKey, numberOfSportEvents, includeHistoricStats.
pointsbet_events_nextupARead-onlyIdempotent
Next-up sport events across all codes, ordered by start time (homepage feed).
Returns: {events:[{key, name, sportKey, competitionName, startsAt, homeTeam, awayTeam, isLive}]}
Auth: none needed.
Inputs: v2Limit.
pointsbet_inplay_streamingARead-onlyIdempotent
In-play events that carry a live video stream, grouped by sport.
Returns: {sports:[{key, name, events:[{key, name, visionData:[]}]}], numberOfInPlayEvents}
Auth: none needed.
Inputs: no named parameters.
pointsbet_preprice_multisARead-onlyIdempotent
Pre-priced "5 for $25" multi suggestions (one pre-built multi per featured event).
Returns: [{key, name, competitionName, startsAt, homeTeam, awayTeam, ...preBuilt legs}]
Auth: none needed.
Inputs: no named parameters.
pointsbet_promo_codeARead-onlyIdempotent
Sign-up splash content (info text + hero image) for a named promo code.
Returns: {info, image}
Example: Welcome promo splash {"code": "WELCOME"}
Auth: none needed.
Inputs: code (required).
pointsbet_promotionsARead-onlyIdempotent
Live promotions for a display surface (carousel, etc.) from the promotions service.
Returns: [{id, type, title, description, ...}]
Auth: none needed.
Inputs: lang, displayTarget.
pointsbet_racing_featuredARead-onlyIdempotent
Featured races across codes with a preview of their top runners.
Returns: [{raceId, racingType, name, venue, number, advertisedStartTimeUtc, runners:[]}]
Auth: none needed.
Inputs: raceCount, runnerCount.
pointsbet_racing_formARead-onlyIdempotent
Detailed form guide for one race: tips, predicted order and per-runner history.
Returns: {RaceId, RaceNumber, RaceName, RacePreview:{PredictedOrder:[]}, RaceTips:[{Comment}]}
Example: Form for Sandown race 1 {"country": "aus", "venue": "sandown", "meetingNumber": 1, "date": "-am", "raceNumber": "01"}
Auth: none needed.
Also answers this: betr_race_form, tab_racing_race_form.
Inputs: date (required), venue (required), country (required), raceNumber (required), +1 more.
pointsbet_racing_futuresARead-onlyIdempotent
Racing futures markets (Cup/Carnival outrights and other long-running racing markets).
Returns: {events:[{key, name, competitionName, startsAt}]}
Auth: none needed.
Inputs: no named parameters.
pointsbet_racing_hourly_quaddieARead-onlyIdempotent
Hourly Quaddie schedule — the four-leg quaddie races grouped by hour.
Returns: [{date, hour, advertisedHourUtc, races:[{raceId, venue, number, advertisedStartTimeUtc}]}]
Auth: none needed.
Also answers this: tab_racing_jackpots.
Inputs: no named parameters.
pointsbet_racing_insightsARead-onlyIdempotent
Editorial form insights for one race (may be empty / 204 before they are published).
Returns: {raceId, insights:[{heading, body}]} (204 No Content when none yet)
Auth: none needed.
Inputs: raceId (required).
pointsbet_racing_meetingARead-onlyIdempotent
One race meeting by id: venue, conditions, and the full list of its races.
Returns: {meetingId, venue, racingType, meetingStartDateTimeUtc, races:[{raceId, raceNumber, name}]}
Auth: none needed.
Inputs: meetingId (required).
pointsbet_racing_meetingsARead-onlyIdempotent
All race meetings (every code) for a date window, each with its races.
Returns: [{groupLabel, meetings:[{meetingId, venue, racingType, races:[{raceId, raceNumber, advertisedStartTimeUtc}]}]}]
Example: All meetings for one day {"startDate": "T00:00:00.000Z", "endDate": "T23:59:59.000Z"}
Auth: none needed.
Inputs: endDate (required), startDate (required).
pointsbet_racing_raceARead-onlyIdempotent
Full racecard for one race: runners, prices, track/conditions, plus results + dividends once run.
Returns: {raceId, name, venue, number, trackCondition, runners:[{number, name, price}], results:{winners:[], straightDividends:[]}}
Auth: none needed.
Inputs: raceId (required).
pointsbet_racing_racesARead-onlyIdempotent
Racecards for several races in one call (batch by race ids).
Returns: [{raceId, name, venue, number, runners:[{number, name, price}]}]
Auth: none needed.
Inputs: raceIds (required).
pointsbet_racing_srmARead-onlyIdempotent
Same Race Multi (SRM) market for one race (availability + legs/prices when open).
Returns: {marketType, displayName, isAvailable, availabilityTimeUtc, legs:[]}
Auth: none needed.
Also answers this: entain_graphql_call, sportsbet_racing_popular_srms.
Inputs: raceId (required).
pointsbet_racing_tipsARead-onlyIdempotent
Tipster selections for a racing code + country for today, grouped by venue.
Returns: [{date, racingType, venue:{name, stateCode}, tips:[{tipster:{name}, links}]}]
Example: Australian thoroughbred tips for today {"racingType": "thoroughbred", "country": "aus"}
Auth: none needed.
Inputs: country (required), racingType (required).
pointsbet_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it selections from one PointsBet event, get the correlation-adjusted combined price. Prices combinations PointsBet has not pre-built (for the ones it has, see pointsbet_preprice_multis).
Returns: {success: true, price: 3.6, message: null, invalidSelections: null} — VERIFIED live 2026-08-27 against AFL Western Bulldogs v Collingwood (event 2860313).
THE PRICE IS NOT THE PRODUCT OF THE LEGS, which is the entire reason to ask. Match Result Bulldogs (1.96) with Over 169.5 (1.90) returns 3.60, not 3.724. Combine that same 1.96 with Bulldogs +1.5 (1.90) and it returns 1.96 FLAT — the line leg is implied by the head-to-head, so it is worth nothing, against a naive 3.724. Never multiply PointsBet legs yourself; the error runs to tens of percent.
REDUNDANT LEGS ARE SILENTLY COLLAPSED AND NOTHING SAYS SO. The response has no leg echo at all: a three-leg request priced as two comes back looking identical to a genuine three-leg quote. Unlike TAB, which marks dropped legs redundant, PointsBet gives you no way to detect it from the response. So STATE THE LEGS YOU SENT whenever you report a price, and treat a price that equals the shorter combination's price as evidence a leg was absorbed. Exact duplicates are deduplicated the same silent way.
enableCorrelatedMulti ON THE MARKET IS NOT ELIGIBILITY. It was true on all 82 markets of the verified event, yet the pricer still refused with Market ... event class First Goalscorer - Home is not allowed for Same Game Multi. Only the pricer knows; do not pre-filter on that flag and do not promise a combination before pricing it.
REFUSALS ARRIVE AS HTTP 200 with success: false and price: 0 — the engine raises these rather than passing a zero off as a quote. Three kinds seen live: a suspended or unknown market names the legs in invalidSelections, mutually exclusive legs give OddsFactory returned price 1 or less, and a disallowed market names its event class. An unknown eventKey is the one that does NOT follow the pattern: it 500s.
Example: Price Bulldogs to win with over 169.5 total points {"eventKey": "2860313", "selectedOutcomes": [{"MarketKey": "114096420", "OutcomeKey": "1"}, {"MarketKey": "114104206", "OutcomeKey": "11"}]}
Auth: none needed.
Inputs: eventKey (required), selectedOutcomes (required).
pointsbet_sport_competitionsARead-onlyIdempotent
Competitions for one sport, grouped by locale (Featured / country buckets).
Returns: {key, name, locales:[{key, name, competitions:[{key, name, numberOfEvents}]}]}
Example: AFL / Australian-rules competitions {"sportKey": "aussie-rules"}
Auth: none needed.
Inputs: sportKey (required).
pointsbet_sport_featured_eventsARead-onlyIdempotent
Featured (highlighted) events for one sport (event headers; call pointsbet_event for markets).
Returns: {key, name, events:[{key, name, competitionKey, startsAt, homeTeam, awayTeam}]}
Auth: none needed.
Inputs: sportKey (required).
pointsbet_sports_inplayARead-onlyIdempotent
Sports currently in-play, with a live event count per sport.
Returns: {sports:[{key, name, numberOfInPlayEvents}], numberOfInPlayEvents}
Auth: none needed.
Inputs: no named parameters.
pointsbet_sports_listARead-onlyIdempotent
Full catalogue of sports and their competitions (every code, featured flags).
Returns: {sports:[{key, name, competitions:[{key, name, isFeatured}]}]}
Example: Whole sports + competitions catalogue {"date": "02May2018"}
Auth: none needed.
Inputs: date (required).
polymarket_bookARead-onlyIdempotent
Full order book (bids + asks with sizes) for one outcome token.
Returns: {market, asset_id, bids:[{price, size}], asks:[{price, size}], tick_size, neg_risk, timestamp}
Auth: none needed.
Also answers this: kalshi_orderbook.
Inputs: token_id (required).
polymarket_clob_marketsARead-onlyIdempotent
CLOB market catalogue (condition ids, token pairs, tick sizes) — cursor-paginated; the trading-plane view of the same markets.
Returns: {limit, count, next_cursor, data:[{condition_id, question, market_slug, tokens:[{token_id, outcome}], minimum_tick_size, active, closed}]}
Auth: none needed.
Also answers this: kalshi_markets.
Inputs: next_cursor.
polymarket_eventARead-onlyIdempotent
One event by Gamma id, with all its markets.
Returns: {id, title, slug, description, volume, liquidity, endDate, tags, markets:[…]}
Auth: none needed.
Inputs: id (required).
polymarket_eventsARead-onlyIdempotent
Event catalogue (an event groups related markets, e.g. one game or election) with nested markets.
Returns: [{id, title, slug, description, volume, liquidity, endDate, tags, markets:[{id, question, clobTokenIds, outcomePrices}]}] (top-level array)
Example: Most-traded active events {"limit": 5, "active": true, "closed": false, "order": "volume24hr", "ascending": false}
Auth: none needed.
Inputs: slug, limit, order, active, +10 more.
polymarket_holdersBRead-onlyIdempotent
Top holders of a market's outcome tokens.
Returns: [{token, holders:[{proxyWallet, amount, name, …}]}] (top-level array)
Auth: none needed.
Also answers this: kalshi_trades.
Inputs: market (required), limit.
polymarket_marketARead-onlyIdempotent
One market's full detail by Gamma id — question, outcomes + prices, CLOB token ids, volume/liquidity, resolution source.
Returns: {id, question, description, slug, conditionId, clobTokenIds, outcomes, outcomePrices, volumeNum, liquidityNum, endDate, resolutionSource, events:[…]}
Auth: none needed.
Also answers this: kalshi_market.
Inputs: id (required).
polymarket_marketsARead-onlyIdempotent
Market catalogue with current outcome prices — filter/sort by activity, volume, liquidity, tag or slug.
Returns: [{id, question, slug, conditionId, clobTokenIds, outcomes, outcomePrices, volumeNum, liquidityNum, volume24hr, endDate, active, closed, events:[…]}] (top-level array)
Example: Most-traded active markets {"limit": 5, "active": true, "closed": false, "order": "volume24hr", "ascending": false}
Auth: none needed.
Also answers this: kalshi_markets.
Inputs: slug, limit, order, active, +11 more.
polymarket_midpointARead-onlyIdempotent
Midpoint (between best bid and best ask) for one outcome token.
Returns: {mid}
Auth: none needed.
Also answers this: kalshi_orderbook.
Inputs: token_id (required).
polymarket_priceBRead-onlyIdempotent
Best price for one outcome token on one side of the book.
Returns: {price}
Auth: none needed.
Also answers this: kalshi_orderbook.
Inputs: side (required), token_id (required).
polymarket_price_historyARead-onlyIdempotent
Historical price series for one outcome token — by named interval or an explicit ts window.
Returns: {history:[{t, p}]} (unix seconds, price 0-1)
Auth: none needed.
Also answers this: kalshi_candlesticks, kalshi_candlesticks_batch.
Inputs: market (required), endTs, startTs, fidelity, +1 more.
polymarket_searchARead-onlyIdempotent
Site-wide search over events/markets/profiles by free-text query.
Returns: {events:[…], tags:[…], profiles:[…]}
Auth: none needed.
Inputs: q (required), events_status, limit_per_type.
polymarket_seriesARead-onlyIdempotent
One series by Gamma id, with its events.
Returns: {id, title, slug, seriesType, recurrence, events:[…]}
Auth: none needed.
Inputs: id (required).
polymarket_series_listARead-onlyIdempotent
Series catalogue — a series groups recurring events (e.g. a league's season of games); the top of Gamma's series → events → markets hierarchy.
Returns: [{id, title, slug, seriesType, recurrence, active, closed, volume, liquidity, events:[…]}] (top-level array)
Auth: none needed.
Inputs: slug, limit, order, closed, +2 more.
polymarket_sportsARead-onlyIdempotent
Sports metadata catalogue — each sport with its tag ids, league/resolution links and series, the entry point for sports markets (feed tag_id into polymarket_markets/polymarket_events).
Returns: [{sport, image, resolution, ordering, tags, series}] (top-level array)
Auth: none needed.
Inputs: no named parameters.
polymarket_spreadBRead-onlyIdempotent
Bid-ask spread for one outcome token.
Returns: {spread}
Auth: none needed.
Also answers this: kalshi_orderbook.
Inputs: token_id (required).
polymarket_tagsARead-onlyIdempotent
Tag catalogue (Sports, Politics, Crypto, NBA, …) — tag ids feed the tag_id filters.
Returns: [{id, label, slug, forceShow, …}] (top-level array)
Auth: none needed.
Inputs: limit, offset.
polymarket_tradesARead-onlyIdempotent
Public trade tape — recent fills, optionally for one market (condition id) or user.
Returns: [{proxyWallet, side, asset, conditionId, size, price, timestamp, title, outcome}] (top-level array)
Auth: none needed.
Also answers this: kalshi_trades.
Inputs: side, user, limit, market, +1 more.
puntersedge_demo_best_oddsARead-onlyIdempotent
No key needed. A small live sample: the best price per selection across books, with an arbitrage flag, for up to 3 upcoming events in one sport.
Returns: {demo:true, note, signup_url, sport, cached, events:[{home_team, away_team, commence_time, selections:[{name, best_price, best_bookmaker}], arb_exists, arb_profit_pct}]} — arb_exists is true when the best prices ACROSS books beat the field. Team naming is per-bookmaker, so the same fixture can appear twice under different spellings ('Warriors' and 'New Zealand Warriors'); the keyed tools carry canonical_event_id to join them.
Example: Best odds + arb flag for a live sport, keyless
Auth: works without a key; PUNTERSEDGE_API_KEY unlocks more if set.
Inputs: sport.
puntersedge_demo_book_sportARead-onlyIdempotent
No key needed. A small live sample of one bookmaker's prices for one sport — a few events, or a few races when the sport is a racing code.
Returns: {demo:true, note, signup_url, book, sport, type:'sports'|'racing', has_data, cached, items:[…]} — items shape follows type: sports → [{home_team, away_team, commence_time, prices:[{name, price}]}]; racing → [{venue, race_number, start_time, runners:[{name, number, price}]}]. Read type before indexing.
Example: Sportsbet's AFL prices, keyless {"book": "sportsbet", "sport": "afl"}
Auth: works without a key; PUNTERSEDGE_API_KEY unlocks more if set.
Inputs: book (required), sport (required).
puntersedge_demo_racing_next_to_goARead-onlyIdempotent
No key needed. A small live sample: the next 3 races, up to 5 runners each, with the best 3 bookmaker win prices per runner.
Returns: {demo:true, note, signup_url, shape, races:[{race_id, venue, race_number, category:'horse'|'greyhound'|'harness', start_time, country, runners:[{name, number, bookmakers:[{key, win_price, source_url}]}]}]} — an ENVELOPE, unlike the keyed puntersedge_racing_next_to_go, which returns a bare array of much richer race objects. race_id is the same id, so anything built here carries over.
Example: The next three races, keyless
Auth: works without a key; PUNTERSEDGE_API_KEY unlocks more if set.
Inputs: no named parameters.
puntersedge_racing_best_oddsARead-onlyIdempotent
Best win, place and tote price per runner across all books, with the book offering it, the spread to the worst price, and a race-level market percentage under 100 when the best prices beat the field. Costs 3 credits.
Returns: [{race_id, venue, race_number, race_name, category, country, start_time, books_compared, market_percentage, runners:[{name, number, barrier, jockey, trainer, best_win:{price, bookmaker, age_seconds, stale, source_url}, best_place:{…}, best_tote:{…}, books_quoting_win, books_quoting_place, price_spread_pct}], scratchings, data_age_seconds, stale}] (top-level ARRAY). market_percentage UNDER 100 = a cross-book arb; any single book is always over 100. ⚠ best_tote is NOT comparable to best_win — a pre-race tote figure is an estimate that moves as the pool fills, and taking the max across books is upward-biased by construction (greyhound pools are thinnest and swing hardest). books_quoting_win and books_quoting_place are DIFFERENT sets.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Best price per runner across books on the next 5 races {"num_races": 5, "country": "AU", "include_unresolved": true}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: venue, country, num_races, bookmakers, +2 more.
puntersedge_racing_closing_linesARead-onlyIdempotent
The permanent closing-line archive: one row per race/runner/bookmaker with the last price before the jump, the first price after the market opened, and the finishing position. The CLV and backtesting surface. Costs 5 credits (JSON). Needs Standard or higher — Free and Hobby get a 403. Standard reads a rolling 90 days, Plus and above the whole archive; window_days on the response says which.
Returns: {archive_from, limit, offset, total_rows, rows_returned, resulted_rows, rows:[{race_id, venue, venue_id, venue_site, race_number, category, country, start_time, meeting_date_aet, bookmaker_key, runner_name, runner_number, runner_key, runner_ref, open_win_price, close_win_price, open_secs_to_jump, close_secs_to_jump, points_observed, is_closing_line, open_is_baseline, finish_position, result_status, venue_split_suspect, name_fragment_suspect}]} — an ENVELOPE with rows, not a bare array. Read the flags before modelling: only 85.5% of series have their final observation within 300s of the jump.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Yesterday's AU thoroughbred closing lines with results attached {"date": "", "category": "horse", "country": "AU", "resulted_only": true, "limit": 500}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: date, limit, venue, format, +10 more.
puntersedge_racing_eventsARead-onlyIdempotent
The CARD: every race scheduled in the next few hours, priced or not, with distance, class, track condition and scratchings. Every country by default — pass country=AU with include_unresolved=true for an Australian card. Costs 1 credit. Use this for the schedule and next-to-go for the prices.
Returns: [{race_id, venue, venue_id, venue_canonical, venue_site, race_number, category, start_time, country, race_name, distance_m, track_condition, weather, race_class, conditions, prize_total, rail, track_name, scratchings:[{name, number, barrier, scratched_at}]}] (top-level ARRAY, NO prices). A race listed here with no prices yet is one no book has opened — the priced window is puntersedge_racing_next_to_go.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every AU race carded in the next 12 hours {"hours_ahead": 12, "country": "AU", "include_unresolved": true}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: country, categories, hours_ahead, include_unresolved.
puntersedge_racing_moversARead-onlyIdempotent
Steamers and drifters: runners whose price has moved materially since the market opened, confirmed across several books. Costs 3 credits.
Returns: [{runner, number, venue, race_number, category, country, start_time, mins_to_jump, direction:'firming'|'drifting', move_pct, open_price, current_price, books_firming, books_drifting, books_unchanged, books_quoting, books_with_history, bookmakers:[{key, open_price, current_price, move_pct, open_secs_to_jump, points, counted_in_consensus}]}] (top-level ARRAY). move_pct is NEGATIVE for a firming runner (price shortened, money has arrived) and positive for a drifter. open_price is the first price CAPTURED inside the 60-minute pre-race window, not a true market open, and how close that is to 60 minutes varies sharply by book — read each book's open_secs_to_jump rather than assuming.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Runners firming 15%+ on at least 4 books {"direction": "firming", "min_move_pct": 15, "min_books": 4}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: limit, country, direction, min_books, +4 more.
puntersedge_racing_next_to_goARead-onlyIdempotent
The priced card: the next races with every runner and EVERY bookmaker's win and place price, plus scratchings and per-book freshness. Every country by default — pass country=AU with include_unresolved=true for an Australian card. Costs 2 credits up to 20 races, 3 for 21–60, 4 for 61–200; num_races=200 pulls every currently quoted race in one call.
Returns: [{race_id, venue, venue_id, venue_canonical, venue_site, race_number, category, start_time, country, race_name, distance_m, track_condition, race_class, scratchings:[{name, number, barrier, scratched_at}], runners:[{name, number, barrier, jockey, trainer, bookmakers:[{key, win_price, place_price, age_seconds, stale, refresh_tier, source_url}]}], data_age_seconds, freshest_age_seconds, refresh_tier, stale, stale_bookmakers}] (top-level ARRAY). Freshness is reported WORST-FIRST: data_age_seconds is the age of the OLDEST quote in the race, so read each bookmaker's own age_seconds before comparing two books.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Next 5 AU thoroughbred races with every book's price {"num_races": 5, "categories": "horse", "country": "AU", "include_unresolved": true}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: venue, country, num_races, bookmakers, +2 more.
puntersedge_racing_resultsARead-onlyIdempotent
Settled AU/NZ results: finishing order, each bookmaker's settled fixed price, starting prices, dividends, scratchings and their deductions. Costs 2 credits.
Returns: [{race_id, venue, venue_canonical, race_number, category, country, start_time, race_name, distance_m, track_condition, going, status:'final'|'interim'|'abandoned', status_note, field_status, placings:[{name, number, position, win_price, place_price, sp, sp_note}], runners:[{name, number, position, status:'ran'|'scratched'|'late_scratching'|'reserve', dead_heat, jockey, trainer, sp, margin, time_s, abnormal, runner_ref}], deductions, dividends, resulted_at}] (top-level ARRAY). A runners entry is NOT necessarily a starter — read its status. A scratched runner can still carry an sp, and that price is NOT what its deduction was struck from: take the deduction from deductions, never from 1/sp.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Yesterday's settled AU thoroughbred results {"hours_back": 24, "categories": "horse", "country": "AU", "status": "final"}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Also answers this: pointsbet_racing_race, sportsbet_racing_resulted_events, tab_racing_race.
Inputs: date, limit, venue, offset, +4 more.
puntersedge_racing_venuesARead-onlyIdempotent
Canonical venue directory — every track actually served recently, with its canonical id, multi-track site key and every raw spelling observed. The join key between this API's data and official sources that spell venues differently. Costs 1 credit.
Returns: [{venue_id, venue_canonical, venue_site, country, categories:['horse'|'harness'|'greyhound'], spellings:[…]}] (top-level ARRAY). The LIST is measured — a venue appears because races actually ran there — while the identity is curated. venue_site joins multi-track complexes: Sandown, Sandown Hillside, Sandown Lakeside and Sandown Park all carry site 'sandown'. spellings is what lets you map historical data you already stored.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: no named parameters.
puntersedge_sport_best_oddsARead-onlyIdempotent
Best available price per selection across all books for one sport's upcoming events, with every book's price alongside and an arbitrage flag. Costs 3 credits. An unknown sport_key returns 404 and costs nothing.
Returns: [{id, sport_key, home_team, away_team, commence_time, selections:[{name, best_price, best_bookmaker, all_prices:[{bookmaker, price}]}], arb_exists, arb_profit_pct}] (top-level ARRAY). arb_exists is true when the best prices ACROSS books beat the field; all_prices carries every book's price on that selection, so the spread is readable without a second call.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Best price per selection across books for the AFL {"sport_key": "afl"}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: sport_key (required).
puntersedge_sport_oddsARead-onlyIdempotent
Every bookmaker's prices for one sport's upcoming events, with per-book freshness and a data-quality score. Costs 1 credit PER REQUESTED MARKET, so keep markets narrow. PRE-MATCH ONLY — there is no in-play feed.
Returns: [{id, sport_key, sport_title, competition, odds_format, commence_time, home_team, away_team, canonical_event_id, bookmakers:[{key, title, last_update, age_seconds, stale, quality:{score, status, issues, source_count, stale_after_seconds}, markets:[{key:'h2h', quality:{…}, outcomes:[{name, price, point}]}]}], data_quality, data_age_seconds, stale, stale_bookmakers}] (top-level ARRAY). Outcome name is a TEAM NAME, not home/away. An event LEAVES this endpoint the moment it starts — nothing here updates during a match. canonical_event_id joins the same fixture across books that spell the teams differently.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Head-to-head prices across every book for the NRL {"sport_key": "nrl", "markets": "h2h"}
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: sport_key (required), markets, bookmakers, oddsFormat, +3 more.
puntersedge_sportsARead-onlyIdempotent
The sports catalogue — every sport_key the odds tools accept, with its title and group. Costs 1 credit. Start here; racing is NOT in this list and has its own tools.
Returns: [{key:'afl'|'nrl'|'nba'|'soccer_epl'|…, title, group, active}] (top-level ARRAY). There is no racing sport_key — horse, harness and greyhound racing live under the puntersedge.racing tools, and passing 'horse-racing' to the odds tools returns 404.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Auth: needs your own key in PUNTERSEDGE_API_KEY.
Inputs: no named parameters.
racingandsports_match_listARead-onlyIdempotent
Sports match list (the site's non-racing fixtures feed). Cloudflare-challenged from datacenter IPs.
Returns: (sports fixtures feed; shape served to the site's XHR)
Auth: none needed.
Inputs: no named parameters.
racingandsports_race_oddsARead-onlyIdempotent
Bookmaker odds for one race. Needs a per-race token (issued by the form-guide page); raceId + token come from the form-guide view.
Returns: (per-runner bookmaker odds; shape served to the form-guide XHR)
Auth: none needed.
Inputs: token (required), raceId (required).
racingandsports_todays_racingARead-onlyIdempotent
Today's race meetings across all codes (thoroughbred / harness / greyhound), grouped by country, each meeting with its form-guide / results URLs.
Returns: [{Discipline:'T'|'H'|'G', DisciplineFullText, Countries:[{CountryName, countryCode, Flag, HasResults, Meetings:[{Course, RaceNumber, HasResults, Remaining, MeetingClosed, FormGuideUrl, PostMeetingUrl, PreMeetingUrl, PDFUrl}]}]}] (top-level array, one per discipline)
Auth: none needed.
Inputs: no named parameters.
seriea_competitionsARead-onlyIdempotent
All Lega Serie A competitions (Serie A, Coppa Italia, Super Cup, Primavera, …), each with its SDP competitionId.
Returns: {competitions:[{competitionId, name, officialName, shortName, acronymName, providerId, imagery}]}
Auth: none needed.
Inputs: locale.
seriea_matchesARead-onlyIdempotent
All 380 matches for a season — scores, status, kickoff, stadium, matchday. Season-scoped. NOTE: returns the WHOLE season in one ~1.2 MB payload — it cannot be narrowed server-side (matchday/round/page params are all ignored); filter the returned matches by matchSet/roundName (the matchweek) client-side.
Returns: {matches:[{matchId, home, away, providerHomeScore, providerAwayScore, status (FINISHED/…), matchDateUtc, stadiumName, roundName, matchSet:{matchSetId}, winTeamId}]} (matchSet = the matchweek, providerId opta:MatchDay:N — group by it client-side)
Auth: none needed.
Inputs: seasonId (required), locale.
seriea_match_lineupsARead-onlyIdempotent
Lineups for one match — per side: tacticalFormation, the fielded XI (with average pitch positions, captain/GK flags, per-player events), the bench, and staff. Discover the matchId from seriea_matches.
Returns: {matchId, pitchSizeX, pitchSizeY, home:{teamId, tacticalFormation, fielded:[{displayName, bibNumber, isCaptain, isGoalkeeper, averageXPosition, averageYPosition, events}], benched, staff}, away:{…}}
Auth: none needed.
Also answers this: pl_match_lineups.
Inputs: matchId (required), seasonId (required), locale.
seriea_playersARead-onlyIdempotent
Every player in a season with identity AND full Opta stats[] (~279 {statsId, statsValue} pairs) — no separate squad call needed. Paginated 30/page (pagination.totalPages / isLastPage; the pageSize param is ignored). NOTE: category selects which STAT SET is returned (General or Goalkeeping; others 400) — it is NOT a position filter, every category returns all players.
Returns: {players:[{playerId, displayName, mediaFirstName, mediaLastName, shirtName, role (1 GK,2 DEF,3 MID,4 FWD), roleLabel, nationalityIsoCode, team, imagery, stats:[{statsId, statsValue}]}], pagination:{totalPages, currentPage, isLastPage}}
Example: 2025/26 outfield player stats, page 1 {"seasonId": "serie-a::Football_Season::5f0e080fc3a44073984b75b3a8e06a8a", "category": "General", "page": 1}
Auth: none needed.
Inputs: seasonId (required), page, locale, category.
seriea_seasonARead-onlyIdempotent
One season's detail by seasonId.
Returns: {season:{seasonId, seasonName, startDateUtc, endDateUtc, competitionId, imagery}}
Auth: none needed.
Inputs: seasonId (required), locale.
seriea_seasonsARead-onlyIdempotent
All 41 Serie A seasons (1986/87 → 2026/27) with seasonId + seasonName. The Serie A competition id is baked in — start here to get a seasonId, then drill into standings/teams/players/matches.
Returns: {seasons:[{seasonId, seasonName, startDateUtc, endDateUtc, competitionId, providerId, imagery}]} (seasonName like '2025/2026')
Auth: none needed.
Inputs: locale.
seriea_standingsARead-onlyIdempotent
League table for a season. Returns three tables — standings[0]=overall, [1]=home, [2]=away — each with 20 teams; each team carries stats[] keyed by statsId (rank, points, matches-played, win, draw, lose, goals-for, goals-against, goal-difference).
Returns: {standings:[{type: table|home|away, teams:[{teamId, mediaName, providerId, imagery, stats:[{statsId, statsLabel, statsValue}]}]}]}
Example: 2025/26 Serie A table {"seasonId": "serie-a::Football_Season::5f0e080fc3a44073984b75b3a8e06a8a"}
Auth: none needed.
Inputs: seasonId (required), locale.
seriea_teamsARead-onlyIdempotent
The 20 teams in a season, with identity + imagery (logos). Season-scoped.
Returns: {competition, teams:[{teamId, providerId, officialName, mediaName, shortName, acronymName, countryCode, imagery:{teamLogo}}]}
Auth: none needed.
Inputs: seasonId (required), locale.
seriea_team_statsARead-onlyIdempotent
Team stat leaderboard for a season — all 20 teams with full Opta team stats[] (~402 {statsId, statsValue} pairs: games-played, total-points, total-wins/losses/draws, …). Same category rule as players (General or Goalkeeping; others 400).
Returns: {teams:[{teamId, mediaName, providerId, imagery, stats:[{statsId, statsLabel, statsValue}]}], pagination:{totalPages, currentPage, isLastPage}}
Auth: none needed.
Inputs: seasonId (required), page, locale, category.
sleeper_draftBRead-onlyIdempotent
One draft's configuration: type, rounds, slot order and status.
Returns: {draft_id, league_id, season, status, type, settings:{rounds, teams, pick_timer}, draft_order, slot_to_roster_id, start_time, last_picked}
Example: A draft's settings {"draft_id": "289646328504385537"}
Auth: none needed.
Inputs: draft_id (required).
sleeper_draft_picksARead-onlyIdempotent
Every pick in a draft, in order, with the player taken and who took them.
Returns: [{pick_no, round, draft_slot, roster_id, picked_by, player_id, is_keeper, metadata:{first_name, last_name, position, team}}] — metadata carries the player's NAME, so you don't need the 15 MB player file
Example: All picks in a draft {"draft_id": "289646328504385537"}
Auth: none needed.
Inputs: draft_id (required).
sleeper_leagueARead-onlyIdempotent
League configuration: scoring rules, roster slots, playoff format, waiver settings and status.
Returns: {league_id, name, season, season_type, status, sport, total_rosters, roster_positions:[…], scoring_settings:{…}, settings:{playoff_week_start, waiver_type, …}, draft_id, previous_league_id, bracket_id}
Example: Sleeper's public example league {"league_id": "289646328504385536"}
Auth: none needed.
Inputs: league_id (required).
sleeper_league_draftsARead-onlyIdempotent
The drafts belonging to a league (a dynasty league has one per season).
Returns: [{draft_id, league_id, season, status, type:'snake'|'auction'|'linear', settings:{rounds, teams}, draft_order:{user_id: slot}, start_time}]
Example: Drafts for the example league {"league_id": "289646328504385536"}
Auth: none needed.
Inputs: league_id (required).
sleeper_league_rostersARead-onlyIdempotent
Every roster in a league: the player ids each manager holds, their starters, and season record.
Returns: [{roster_id, owner_id, league_id, players:[player_id], starters:[player_id], reserve:[…], taxi:[…], settings:{wins, losses, ties, fpts, fpts_against, waiver_position}}] — join owner_id to sleeper_league_users.user_id for a human name
Example: All rosters in the example league {"league_id": "289646328504385536"}
Auth: none needed.
Inputs: league_id (required).
sleeper_league_usersARead-onlyIdempotent
The people in a league — display names and team names, keyed by user_id.
Returns: [{user_id, display_name, avatar, is_owner, metadata:{team_name}}] — the ONLY place a human name lives; rosters carry owner_id, not names
Example: Managers in the example league {"league_id": "289646328504385536"}
Auth: none needed.
Inputs: league_id (required).
sleeper_matchupsARead-onlyIdempotent
One week's matchups with each roster's points, starters and per-player scoring.
Returns: [{roster_id, matchup_id, points, custom_points, starters:[player_id], starters_points:[float], players:[player_id], players_points:{player_id: float}}] — rosters sharing a matchup_id played each other; there is no home/away
Example: Week 1 matchups {"league_id": "289646328504385536", "week": 1}
Auth: none needed.
Also answers this: espnfantasy_matchups, espnfantasy_matchup_score.
Inputs: week (required), league_id (required).
sleeper_playersARead-onlyIdempotent
THE player id → name table. Every other Sleeper tool speaks in player ids and nothing else; this is the only thing that resolves them. HUGE — read the caching note before calling it.
Returns: {player_id: {full_name, team, position, status}} — an OBJECT keyed by player id, not an array. team is null for a free agent, which is how you tell one.
CALL THIS AT MOST ONCE A DAY AND CACHE IT. Sleeper says so explicitly, and it is 14.6 MB before projection — 12,221 players including every retired and practice-squad name they have ever held. Projected here to four fields, it is still far too large to put in a model's context: resolve the handful of ids you actually care about and discard the rest.
VERIFIED live 2026-08-24: 12,221 players, 3,250 of them on an NFL team.
Example: The id → name table (large; cache it) {"sport": "nfl"}
Auth: none needed.
Inputs: sport.
sleeper_playoff_bracketARead-onlyIdempotent
The playoff bracket — who plays whom in each round, and who advanced.
Returns: [{r, m, t1, t2, w, l, t1_from, t2_from}] — TERSE keys: r=round, m=match id, t1/t2=roster ids, w=winner, l=loser, *_from=which earlier match fed this slot
Example: Championship bracket {"league_id": "289646328504385536", "bracket": "winners_bracket"}
Auth: none needed.
Also answers this: espnfantasy_matchups, espnfantasy_matchup_score.
Inputs: league_id (required), bracket.
sleeper_stateARead-onlyIdempotent
Current NFL state — season, week, and whether scoring has started. Call this to resolve 'this week' instead of guessing.
Returns: {season, season_type:'pre'|'regular'|'post', week, leg, display_week, season_start_date, previous_season, league_season, season_has_scores}
Example: Where the NFL season is up to {"sport": "nfl"}
Auth: none needed.
Inputs: sport.
sleeper_traded_picksARead-onlyIdempotent
Draft picks that have changed hands — who owns which future pick (dynasty leagues).
Returns: [{season, round, roster_id, previous_owner_id, owner_id}] — roster_id is the pick's ORIGINAL owner; owner_id holds it now
Example: Traded picks in the example league {"league_id": "289646328504385536"}
Auth: none needed.
Inputs: league_id (required).
sleeper_transactionsARead-onlyIdempotent
Adds, drops, waiver claims and trades for one week.
Returns: [{transaction_id, type:'free_agent'|'waiver'|'trade', status, roster_ids:[int], adds:{player_id: roster_id}, drops:{player_id: roster_id}, draft_picks:[…], settings:{waiver_bid}, created}]
Example: Week 1 transactions {"league_id": "289646328504385536", "week": 1}
Auth: none needed.
Inputs: week (required), league_id (required).
sleeper_trending_playersARead-onlyIdempotent
Players being added or dropped most across all of Sleeper — the waiver-wire signal, without downloading the 15 MB player file.
Returns: [{player_id, count}] (top-level array) — count is how many leagues made the move. Resolve player_id via a roster or Sleeper's player file.
Example: Most-added players in the last 24h {"sport": "nfl", "add_or_drop": "add", "limit": 25}
Auth: none needed.
Also answers this: espnfantasy_player_info.
Inputs: limit, sport, add_or_drop, lookback_hours.
sleeper_userARead-onlyIdempotent
Look up a Sleeper user by username (or user id) — the first step to finding someone's leagues.
Returns: {user_id, username, display_name, avatar, is_bot} — user_id is what sleeper_user_leagues needs
Example: Resolve a username to a user_id {"username_or_id": "sleeperuser"}
Auth: none needed.
Inputs: username_or_id (required).
sleeper_user_leaguesARead-onlyIdempotent
Every league a user is in for one sport and season — how you get a league_id from a username.
Returns: [{league_id, name, season, status, sport, total_rosters, scoring_settings, roster_positions, settings, draft_id, previous_league_id}] (top-level array)
Example: A user's 2025 NFL leagues {"user_id": "483459259485384704", "sport": "nfl", "season": "2025"}
Auth: none needed.
Inputs: season (required), user_id (required), sport.
sportmonks_fixtureARead-onlyIdempotent
One fixture. The include you choose decides whether you get lineups, events and statistics.
Returns: {data:{id, name, starting_at, result_info, participants:[…], scores:[…], events:[{type_id, minute, player_name, related_player_name, result}], lineups:[…], statistics:[…]}} — SHAPE FROM VENDOR DOCS. Events use NUMERIC type_ids, not names — resolve them via sportmonks_types.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A fixture with events {"id": 18535517, "include": "participants;scores;events"}
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: id (required), include.
sportmonks_fixtures_by_dateARead-onlyIdempotent
Fixtures on one date. Add include=participants;scores or you will get ids without teams or a score.
Returns: {data:[{id, sport_id, league_id, season_id, name:'Home vs Away', starting_at, result_info, state_id, participants:[…only if included…], scores:[{score:{goals, participant}, description:'CURRENT'|'1ST_HALF'|…}]}], pagination} — SHAPE FROM VENDOR DOCS. scores is a LIST of period scores; pick description == 'CURRENT' for the live/final figure.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A date's fixtures with teams and scores {"date": "2024-08-17", "include": "participants;scores"}
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: date (required), include, per_page.
sportmonks_leaguesARead-onlyIdempotent
Leagues your plan can see. On the free tier this is the Danish Superliga and Scottish Premiership.
Returns: {data:[{id, sport_id, country_id, name, active, short_code, image_path, type, sub_type, last_played_at}], pagination:{count, per_page, current_page, next_page, has_more}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Leagues on your plan
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: page, include, per_page.
sportmonks_livescoresARead-onlyIdempotent
Fixtures in progress now.
Returns: {data:[{id, name, starting_at, state_id, participants:[…], scores:[…], periods:[{minutes, seconds, ticking}]}]} — SHAPE FROM VENDOR DOCS. periods[].ticking is how you tell a running clock from a half-time pause.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: In-play now {"include": "participants;scores"}
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: include.
sportmonks_playersARead-onlyIdempotent
Players, with season statistics when included.
Returns: {data:[{id, sport_id, country_id, nationality_id, position_id, name, common_name, firstname, lastname, display_name, date_of_birth, height, weight}], pagination} — SHAPE FROM VENDOR DOCS. Statistics arrive only via include=statistics.details, and each detail row is keyed by a numeric type_id.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Players on your plan
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: page, include, per_page.
sportmonks_standingsARead-onlyIdempotent
League table for a season.
Returns: {data:[{id, participant_id, position, points, result, sport_id, league_id, season_id, group_id, round_id, standing_rule_id, participant:{…only if included…}}]} — SHAPE FROM VENDOR DOCS. Without include=participant you get team IDS ONLY, which is the most common complaint about this endpoint.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A season's table with team names {"seasonId": 19686, "include": "participant"}
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: seasonId (required), include.
sportmonks_teamsARead-onlyIdempotent
Clubs, by search or by season.
Returns: {data:[{id, sport_id, country_id, venue_id, name, short_code, image_path, founded, type}], pagination} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Teams on your plan
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: page, include, per_page.
sportmonks_typesARead-onlyIdempotent
The type catalogue — resolves the numeric type_ids that appear all over events, statistics and standings details.
Returns: {data:[{id, name:'Goal'|'Yellow Card'|'Shots Total'|…, code, developer_name, model_type, stat_group}], pagination} — SHAPE FROM VENDOR DOCS. Without this, a fixture's events and a player's statistics.details are unreadable — they are numbers.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: The type catalogue {"per_page": 50}
Auth: needs your own key in SPORTMONKS_TOKEN.
Inputs: page, per_page.
sportsbet_bet_historyARead-onlyIdempotent
Your own bets at Sportsbet. THIS IS HOW A PLACEMENT IS CONFIRMED — placing answers 202 Accepted, so a bet is only really on once it appears here.
Returns: {betList:[…]} — the account's bets. VERIFIED live 2026-08-28.
THE KEY IS betList, NOT bets. Reading bets returns nothing and looks exactly like an empty account — which is a dangerous false negative when you are checking whether a placement landed.
THIS IS HOW A PLACEMENT IS CONFIRMED. sportsbet_place_bet answers 202 Accepted, which means taken for processing rather than on, so a bet is only really placed once it appears here. Match on the betId the placement returned, and check the STAKE AND THE PRICE, not merely that a bet exists.
filterType takes SETTLED and PENDING — both verified 2026-08-28 alongside limit and includeLegData. PENDING is what you want for reading back a bet you have just placed.
Rows carry betId, receipt, stake, price, placedAt, summary, and per-leg detail including externalClassId / externalMeetingId / externalOutcomeId — the racing external ids that placement itself does NOT use.
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: appToken (required), customerId (required), limit, channel, +6 more.
sportsbet_bet_liveARead-onlyIdempotent
BetLive feed — events currently in-play and bettable live.
Returns: {events:[{eventId, name, classId, score, startTime}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: birType, excludeNonLiveEvents, includePrimaryMarket.
sportsbet_class_couponARead-onlyIdempotent
Coupon (grouped markets) for a whole sport class.
Returns: {class:{classId, name}, competitions:[{competitionId, events:[{eventId, markets:[]}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: classId (required).
sportsbet_cms_messagesARead-onlyIdempotent
Sitewide CMS messages (banners, notices).
Returns: {messages:[{id, type, text}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_cms_pageARead-onlyIdempotent
CMS page block by competition id or page path (one of the two is required).
Returns: {page:{path, blocks:[{type, content}]}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: loggedIn, pagePath, competitionId.
sportsbet_cms_settingsARead-onlyIdempotent
Global CMS settings / feature flags for the app.
Returns: {settings:{}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_competition_matchesARead-onlyIdempotent
Match-type events for a sport competition.
Returns: {events:[{eventId, name, startTime, score}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: competitionId (required).
sportsbet_competition_outrightsARead-onlyIdempotent
Outright (futures) events for a sport competition.
Returns: {events:[{eventId, name, markets:[{name, selections:[{name, price:{winPrice}}]}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: competitionId (required).
sportsbet_event_commentaryARead-onlyIdempotent
Live score + text commentary for one or more sport events.
Returns: {events:[{eventId, score, commentary:[{time, text}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventIds (required).
sportsbet_event_marketsARead-onlyIdempotent
All markets + selections + live prices for one sport event.
Returns: {markets:[{marketId, name, selections:[{selectionId, name, price:{winPrice, winPriceNum, winPriceDen}}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required).
sportsbet_event_resultsARead-onlyIdempotent
Results for a finished sport event (final score + settled markets).
Returns: {event:{eventId, finalScore}, markets:[{marketId, winningSelections:[]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required).
sportsbet_event_statusARead-onlyIdempotent
Live status flags for a sport event (suspended, in-play, settled).
Returns: {eventId, status, inPlay, suspended}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required).
sportsbet_graphql_callARead-onlyIdempotent
Call any of Sportsbet's persisted GraphQL operations against www.sportsbet.com.au/apigw/sportsbook/graph by name + variables. Hashes are managed server-side; a PERSISTED_QUERY_NOT_FOUND error means the bundle drifted. Read sportsbet://graphql/operations for the op list + variable signatures.
Returns: (JSON object)
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: operation (required), variables.
sportsbet_league_ladderARead-onlyIdempotent
League ladder / standings for a sport competition.
Returns: {ladder:[{position, teamName, played, won, lost, points}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: competitionId (required).
sportsbet_match_previewARead-onlyIdempotent
Editorial match preview (text + video) for one sport event.
Returns: {preview:{title, body, videoUrl}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventDate (required), eventName (required), sportsClass (required), sportsCompetitionName (required).
sportsbet_multiple_racecardsARead-onlyIdempotent
Racecards for several races in one call (batch by event ids).
Returns: {racecards:[{event:{}, markets:[]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventIds (required).
sportsbet_page_contentARead-onlyIdempotent
Homepage tab content (sports or racing landing modules).
Returns: {modules:[{type, items:[]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: tab (required), loggedIn, popularsrms.
sportsbet_popular_promotionsARead-onlyIdempotent
Trending / popular promotions for a promo provider + client.
Returns: {promotions:[{id, title, url}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: clientId (required), provider (required), limit, loggedIn.
sportsbet_price_slipARead-onlyIdempotent
PRICE A BET SLIP — the authoritative, current price for selections you are about to back. Call this IMMEDIATELY before sportsbet_place_bet: placement takes a price you assert, not a quote id, so this is the only way to place at a real number.
Returns: {betBuilds:[{betNo, enhancedOdds:[{outcome, priceDecimal, priceNum, priceDen, legType}], betCombinations:[{betType, betTypeName, betMinStake, betNoOfLines, cashoutAvailable, betEnhancedPrice}], vouchers:[]}]} — VERIFIED live 2026-08-27.
THIS IS THE AUTHORITATIVE PRICE, and it is the call to make immediately before placing. sportsbet_place_bet does NOT take a quote id: it takes a price you assert, so the only way to place at a real price is to read it here first and send THAT number. A price remembered from thirty seconds ago is not a price.
betMinStake comes back per combination and was 0.01 on the verified slip — the smallest possible test bet is a cent, not a dollar.
Prices appear twice and in two forms: priceDecimal on each enhanced odd, and priceNum/priceDen which is what placement wants. Carry the fraction across unchanged rather than re-deriving it from the decimal, which rounds.
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: appToken (required), betItems (required), customerId (required), channel, +8 more.
sportsbet_racecardBRead-onlyIdempotent
Racecard for one race: runners, prices, scratchings.
Returns: {event:{eventId, raceNumber}, markets:[{marketId, name, selections:[{name, price:{winPrice, winPriceNum, winPriceDen}}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required), selectionNames.
sportsbet_racecard_with_contextARead-onlyIdempotent
Racecard plus surrounding context (meeting, results, related markets) for one race.
Returns: {event:{}, markets:[], meeting:{}, context:{}}
Example: Racecard with context for one race {"eventId": 10513900, "classId": 1}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: classId (required), eventId (required).
sportsbet_race_previewARead-onlyIdempotent
Editorial race preview (text + video) for one race.
Returns: {preview:{title, body, videoUrl}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: raceType (required), eventDate (required), trackName (required), raceNumber (required).
sportsbet_racing_allracingARead-onlyIdempotent
All race meetings (every code) for one date, grouped by meeting.
Returns: {meetings:[{competitionId, name, raceType, events:[{eventId, raceNumber, advertisedStartTime}]}]}
Example: All racing for a given day {"eventDate": ""}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventDate (required).
sportsbet_racing_best_betsARead-onlyIdempotent
Editorially-selected best bets across racing.
Returns: {bestBets:[{eventId, selectionName, price:{winPrice}}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_best_bets_with_eventsARead-onlyIdempotent
Best bets with their full parent event objects inlined.
Returns: {bestBets:[{event:{eventId, raceNumber}, selectionName, price:{winPrice}}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_challengesARead-onlyIdempotent
All racing challenges / promotions feed.
Returns: {challenges:[{id, name, status}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_competitionARead-onlyIdempotent
Racing competition (meeting) detail by competition id.
Returns: {competition:{competitionId, name, raceType}, events:[{eventId, raceNumber}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: competitionId (required).
sportsbet_racing_event_meetingARead-onlyIdempotent
Meeting context for one racing event (parent meeting + sibling races).
Returns: {meeting:{competitionId, name}, races:[{eventId, raceNumber}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required).
sportsbet_racing_futuresARead-onlyIdempotent
Racing futures markets (Cup outrights and other long-running racing markets).
Returns: {futures:[{marketId, name, selections:[{name, price:{winPrice}}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_megabetsARead-onlyIdempotent
Racing Megabets (large multi suggestions across races).
Returns: {megabets:[{id, legs:[{eventId, selectionName}], price:{winPrice}}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_multis_eventsARead-onlyIdempotent
Events available for racing multis, ordered by start (next-to-jump style feed).
Returns: {events:[{eventId, raceNumber, advertisedStartTime, meetingName}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_racing_popular_srmsARead-onlyIdempotent
Popular Same Race Multi (SRM) combinations for races / meetings.
Returns: {srms:[{eventId, legs:[{selectionName}], price:{winPrice}}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Also answers this: entain_graphql_call, pointsbet_racing_srm.
Inputs: ids (required), hierarchyLevel (required), sortBy, maxItems, +2 more.
sportsbet_racing_resulted_eventsARead-onlyIdempotent
Resulted races (placings + dividends) for a racing competition + class + date.
Returns: {events:[{eventId, raceNumber, results:[{place, selectionName}], dividends:[]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Also answers this: pointsbet_racing_race, puntersedge_racing_results, tab_racing_race.
Inputs: date (required), classId (required), competitionId (required).
sportsbet_racing_top_jockeysARead-onlyIdempotent
Top jockeys hub (leading jockeys and their rides today).
Returns: {jockeys:[{name, rides:[{eventId, selectionName}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_results_classesARead-onlyIdempotent
Sport classes that have results available for a date.
Returns: {classes:[{classId, name}]}
Example: Classes with results today {"date": "today"}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: date (required).
sportsbet_results_competitionsARead-onlyIdempotent
Competitions with results for a sport class on a date.
Returns: {competitions:[{competitionId, name, events:[{eventId, finalScore}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), classId (required).
sportsbet_safer_gambling_messageARead-onlyIdempotent
Current safer-gambling message block for the site.
Returns: {message:{title, body}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: no named parameters.
sportsbet_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it legs from one event, get the combined price back. The only tool here that prices a combination the book has not already built.
Returns: {price:{quoteId, numerator, denominator}} — VERIFIED live 2026-08-25 against AFL Western Bulldogs v Collingwood: two legs returned 7/5.
THE PRICE IS FRACTIONAL. Decimal = 1 + numerator/denominator, so 7/5 is $2.40. It is NOT the product of the legs — Sportsbet applies a correlation adjustment, which is the entire point of asking.
quoteId is a per-request token with a short life. Treat the price as a quote, not a cached fact: re-request rather than reusing one from minutes ago.
ERRORS COME BACK 400 WITH A CODE: ERR-MP-001 means fewer than two outcomes; ERR-VE means the body failed schema validation (usually an id passed where an externalId was wanted). Legs the book will not combine are refused rather than priced.
Example: Price a two-leg AFL same game multi {"classExternalId": 103, "competitionExternalId": 17131, "eventExternalId": 16374542, "outcomesExternalIds": [{"marketExternalId": 602153262, "outcomeExternalId": 2870628965}, {"marketExternalId": 602153262, "outcomeExternalId": 2870628954}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: classExternalId (required), eventExternalId (required), outcomesExternalIds (required), competitionExternalId (required).
sportsbet_sport_card_legacyARead-onlyIdempotent
Legacy single sport event card (event + primary markets).
Returns: {event:{eventId, name, startTime}, markets:[]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required).
sportsbet_sport_competitionARead-onlyIdempotent
Sport competition page: matches, outrights and optional top markets.
Returns: {competition:{competitionId, name}, events:[{eventId, name, startTime, markets:[]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: competitionId (required), numMarkets, displayType, eventFilter, +2 more.
sportsbet_sport_resulted_eventsARead-onlyIdempotent
Resulted (finished) events for a sport competition + class + date.
Returns: {events:[{eventId, name, finalScore}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), classId (required), competitionId (required).
sportsbet_sports_cardARead-onlyIdempotent
Full sport event card (all markets + selections) or the resulted event if finished.
Returns: {event:{eventId, name, startTime}, markets:[{marketId, name, selections:[{name, price:{winPrice}}]}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventId (required), includeIncidents, includeAllMarkets, includeCommentary, +2 more.
sportsbet_sports_classesARead-onlyIdempotent
Sport classes (sports) with their competitions for a date window.
Returns: {classList:[{classId, className, classDisplayOrder}]}
Example: Sports with events in the next 24 hours {"fromDate": "T10:00:00", "toDate": "<today+1>T10:00:59"}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: toDate (required), fromDate (required), includeLiveEvents, excludeNonLiveEvents.
sportsbet_track_reportARead-onlyIdempotent
Track report (going, rail, weather) for a racing meeting on a date.
Returns: {track:{name, going, railPosition, weather}}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: eventDate (required), raceType, trackName.
sportsbet_trending_sgmARead-onlyIdempotent
Trending Same Game Multi (SGM) combinations for one sport event.
Returns: {sgms:[{legs:[{selectionName}], price:{winPrice}}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: id (required).
sportsbet_upcoming_eventsARead-onlyIdempotent
Upcoming sport events across all codes (homepage upcoming feed).
Returns: {events:[{eventId, name, classId, competitionId, startTime}]}
Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.
Inputs: maxEvents, includePrimaryMarket.
sportsdata_feedbackA
Report whether an answer from this server was useful.
Call this when a tool gave a wrong, empty or misleading answer — especially if the response shape did not match its description, which is the failure mode the maintainers most need to hear about.
Recorded locally. It is only ever transmitted if the operator has explicitly
enabled sharing (SPORTSDATA_TELEMETRY=1 plus a configured endpoint), and note
is sent verbatim, so do not put anything private in it.
Inputs: helpful (required), note, tool. Returns: object
sportsdataio_mlb_games_by_dateARead-onlyIdempotent
MLB games on a date, with probable pitchers and the line.
Returns: [{GameID, Season, Status, DateTime, AwayTeam, HomeTeam, AwayTeamRuns, HomeTeamRuns, Inning, InningHalf, AwayTeamProbablePitcherID, HomeTeamProbablePitcherID, PointSpread, OverUnder}] — SHAPE FROM VENDOR DOCS. The keyless official mlb provider is deeper for everything except the line and the DFS layer.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A date's MLB games {"date": "2024-07-04"}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: date (required).
sportsdataio_nba_dfs_slatesARead-onlyIdempotent
NBA DFS slates and salaries for a date.
Returns: [{SlateID, Operator, OperatorName, OperatorStartTime, DfsSlatePlayers:[{SlatePlayerID, PlayerID, OperatorPlayerName, OperatorPosition, OperatorSalary, FantasyPoints}]}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A date's NBA slates {"date": "2024-01-15"}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: date (required).
sportsdataio_nba_games_by_dateARead-onlyIdempotent
NBA games on a date, with the closing spread and total.
Returns: [{GameID, Season, Status, DateTime, AwayTeam, HomeTeam, AwayTeamScore, HomeTeamScore, PointSpread, OverUnder, Quarters:[…], StadiumID}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A date's NBA games {"date": "2024-01-15"}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: date (required).
sportsdataio_nfl_dfs_slatesARead-onlyIdempotent
DFS slates and player SALARIES for a week — DraftKings, FanDuel and Yahoo. Not available from the official NFL feeds.
Returns: [{SlateID, Operator:'DraftKings'|'FanDuel'|'Yahoo', OperatorSlateID, OperatorName, OperatorDay, OperatorStartTime, NumberOfGames, IsMultiDaySlate, DfsSlateGames:[…], DfsSlatePlayers:[{SlatePlayerID, PlayerID, OperatorPlayerName, OperatorPosition, OperatorSalary, FantasyPoints, FantasyPointsPerDollar}]}] — SHAPE FROM VENDOR DOCS. FantasyPointsPerDollar is value; salaries are integers in dollars.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week's DFS slates {"season": "2023", "week": 1}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: week (required), season (required).
sportsdataio_nfl_injuriesARead-onlyIdempotent
NFL injury report for a week.
Returns: [{InjuryID, PlayerID, Name, Position, Team, Status:'Questionable'|'Out'|…, BodyPart, Practice, PracticeDescription, Updated}] — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week's injuries {"season": "2023", "week": 1}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: week (required), season (required).
sportsdataio_nfl_projectionsARead-onlyIdempotent
Projected NFL player game statistics for a week.
Returns: [{PlayerID, Name, Team, Position, PassingYards, PassingTouchdowns, RushingYards, ReceivingYards, Receptions, FantasyPoints, FantasyPointsPPR, FantasyPointsDraftKings, FantasyPointsFanDuel}] — SHAPE FROM VENDOR DOCS. Note the per-operator scoring columns: DraftKings and FanDuel score differently, so use the matching one.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week's projections {"season": "2023", "week": 1}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: week (required), season (required).
sportsdataio_nfl_scoresARead-onlyIdempotent
NFL scores for one season and week.
Returns: [{GameKey, SeasonType, Season, Week, Date, AwayTeam, HomeTeam, AwayScore, HomeScore, Quarter, TimeRemaining, PointSpread, OverUnder, StadiumDetails}] — SHAPE FROM VENDOR DOCS. SeasonType 1=pre, 2=regular, 3=post.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week's scores {"season": "2023", "week": 1}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: week (required), season (required).
sportsdataio_nfl_teamsARead-onlyIdempotent
NFL franchises with conference, division, stadium and coach.
Returns: [{Key:'BUF', TeamID, PlayerID, City, Name, Conference, Division, FullName, StadiumDetails:{…}, HeadCoach, OffensiveCoordinator, PrimaryColor}] — SHAPE FROM VENDOR DOCS. Fields are PascalCase throughout this API.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every NFL team
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: no named parameters.
sportsdataio_nhl_games_by_dateARead-onlyIdempotent
NHL games on a date, with the line.
Returns: [{GameID, Season, Status, DateTime, AwayTeam, HomeTeam, AwayTeamScore, HomeTeamScore, Period, TimeRemainingMinutes, PointSpread, OverUnder, Periods:[…]}] — SHAPE FROM VENDOR DOCS. The keyless official nhl provider is deeper for play-by-play and box scores.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A date's NHL games {"date": "2024-01-15"}
Auth: needs your own key in SPORTSDATAIO_MLB_KEY or SPORTSDATAIO_NBA_KEY or SPORTSDATAIO_NFL_KEY or SPORTSDATAIO_NHL_KEY.
Inputs: date (required).
sportsdata_session_statsARead-onlyIdempotent
How this server has performed for you THIS session: per-tool call counts, error rates, error codes, latency buckets, and how often a tool succeeded but returned nothing.
Useful when a tool seems to be misbehaving — a 100% error rate with code
AUTH_REQUIRED means a missing key, while a high empty count on a working tool
usually means the upstream has no data for what was asked, not that the call is
wrong.
This is read from local counters. Nothing here has been sent anywhere.
Inputs: no named parameters. Returns: object
sportsgameodds_bookmakersARead-onlyIdempotent
The bookmakers indexed, with the ids used in byBookmaker.
Returns: {success:true, data:[{bookmakerID, name, isLive}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every bookmaker
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: no named parameters.
sportsgameodds_eventsARead-onlyIdempotent
Events with their odds attached, including player props. The main tool here.
Returns: {success:true, data:[{eventID, leagueID, sportID, status:{started, completed, displayShort}, teams:{home:{teamID, names}, away:{…}}, odds:{'':{oddID, statID, statEntityID, periodID, betTypeID, sideID, bookOdds, bookSpread, bookOverUnder, byBookmaker:{'':{odds, spread, overUnder, available, lastUpdatedAt}}}}}], nextCursor} — SHAPE FROM VENDOR DOCS. NOTE odds is an OBJECT KEYED BY oddID, not a list, and each entry carries a byBookmaker map: two levels of dictionary before you reach a price.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL events with odds {"leagueID": "NFL", "oddsAvailable": true}
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: limit, cursor, eventID, sportID, +5 more.
sportsgameodds_leaguesARead-onlyIdempotent
Leagues, with the leagueID other tools filter on (NFL, NBA, MLB, NHL, EPL, NCAAF…).
Returns: {success:true, data:[{leagueID:'NFL', sportID:'FOOTBALL', name, enabled}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Football leagues {"sportID": "FOOTBALL"}
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: sportID.
sportsgameodds_playersARead-onlyIdempotent
Players, with the playerIDs that appear inside prop oddIDs.
Returns: {success:true, data:[{playerID:'JOSH_ALLEN_1_NFL', teamID, leagueID, firstName, lastName, position}]} — SHAPE FROM VENDOR DOCS. The playerID is the statEntityID half of a prop's oddID, which is how you find every market on one player.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A team's players {"leagueID": "NFL", "teamID": "BUFFALO_BILLS_NFL"}
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: teamID, leagueID, playerID.
sportsgameodds_sportsARead-onlyIdempotent
Sports covered, with the sportID other tools filter on.
Returns: {success:true, data:[{sportID:'FOOTBALL', enabled}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Every sport
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: no named parameters.
sportsgameodds_statsARead-onlyIdempotent
The statistics catalogue — the statIDs that form the first segment of every prop oddID.
Returns: {success:true, data:[{statID:'passing_yards', name, leagueID, entityType:'player'|'team'}]} — SHAPE FROM VENDOR DOCS. Read this before constructing prop filters; guessing statIDs is the usual way to get an empty result.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL statistics {"leagueID": "NFL"}
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: leagueID.
sportsgameodds_teamsARead-onlyIdempotent
Teams in a league, with the teamIDs used inside event objects.
Returns: {success:true, data:[{teamID, leagueID, names:{long, medium, short}, colors}]} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL teams {"leagueID": "NFL"}
Auth: needs your own key in SPORTSGAMEODDS_API_KEY.
Inputs: teamID, leagueID.
squiggle_gamesARead-onlyIdempotent
AFL fixture + results: each game with scores by goals/behinds, venue, and completion state.
Returns: {games:[{id, round, year, date, unixtime, venue, hteam, hteamid, hscore, hgoals, hbehinds, ateam, ateamid, ascore, agoals, abehinds, complete, is_final, winnerteamid, updated}]}
Example: Round 1 of 2026 {"q": "games", "year": 2026, "round": 1}
Auth: none needed.
Inputs: q, game, team, year, +2 more.
squiggle_ladderARead-onlyIdempotent
PROJECTED end-of-season ladder per model, with each team's simulated finishing-position distribution (swarms).
Returns: {ladder:[{source, sourceid, year, round, team, teamid, rank, mean_rank, wins, percentage, swarms:[str], updated}]} — swarms is the simulated distribution over finishing positions; rank here is PROJECTED, unlike squiggle_standings
Example: Projected ladder after round 1, 2026 {"q": "ladder", "year": 2026, "round": 1}
Auth: none needed.
Inputs: q, year, round, source.
squiggle_sourcesARead-onlyIdempotent
The forecasting models Squiggle tracks — call this first to learn the sourceid values the tip tools filter on.
Returns: {sources:[{id, name, url, icon}]} — id is the source filter on squiggle_tips / squiggle_ladder
Example: Every tracked model {"q": "sources"}
Auth: none needed.
Inputs: q, year.
squiggle_standingsARead-onlyIdempotent
The ACTUAL AFL ladder — real wins/losses/percentage, not a projection.
Returns: {standings:[{rank, id, name, played, wins, losses, draws, pts, for, against, percentage, goals_for, goals_against, behinds_for, behinds_against}]}
Example: Current 2026 ladder {"q": "standings", "year": 2026}
Auth: none needed.
Inputs: q, year, round.
squiggle_teamsARead-onlyIdempotent
AFL clubs with Squiggle's team ids — the id every other Squiggle tool keys off.
Returns: {teams:[{id, name, abbrev, logo, debut, retirement}]} — retirement 9999 means still active
Example: All AFL clubs {"q": "teams"}
Auth: none needed.
Inputs: q, year.
squiggle_tipsARead-onlyIdempotent
What each model tipped for a game: winner, predicted margin, confidence %, and — for played games — whether it was right.
Returns: {tips:[{gameid, round, year, date, source, sourceid, hteam, hteamid, ateam, ateamid, tip, tipteamid, margin, confidence, hconfidence, hmargin, correct, bits, err, updated}]} — confidence is a %, bits is the model's information score, correct is null until played
Example: Every model's tips for round 1, 2026 {"q": "tips", "year": 2026, "round": 1}
Auth: none needed.
Also answers this: apisports_football_predictions, datagolf_pre_tournament, datagolf_pre_tournament_archive.
Inputs: q, game, year, round, +2 more.
supercoach_leaguesARead-onlyIdempotent
The game's public/featured leagues for one sport+season+mode — each with name, code, type, competition_id, experience, description and sponsor metadata. Useful to discover competition_ids and the league types on offer.
Returns: array of {id, name, code, type, competition_id, experience, description, sponsor_filename, sponsor_content}
Example: AFL classic leagues {"sport": "afl", "year": 2026}
Auth: none needed.
Inputs: year (required), sport (required), mode.
supercoach_playerARead-onlyIdempotent
A single player's base record by SuperCoach id (id, first/last name, team_id, previous_games/previous_average/previous_total, feed_id). A thin subset of supercoach_players — for the full price/projection/matchup snapshot use supercoach_players with a round.
Returns: {id, first_name, last_name, team_id, previous_games, previous_average, previous_total, feed_id}
Example: AFL player 1 {"sport": "afl", "year": 2026, "id": 1}
Auth: none needed.
Inputs: id (required), year (required), sport (required), mode.
supercoach_playersARead-onlyIdempotent
THE feed — every player's full snapshot for one round: price + price_change, avg/avg3/avg5, the ppts1 projection, owned %, positions, availability, dated news and the next-three-opponents matchup context. LARGE (~1–3 MB; 174–1032 players depending on sport). Pass round (from supercoach_settings.next_round) for a forward snapshot; loop round=1..current_round with embed=player_match_stats to build a per-round score series. The embed set is CLOSED — only positions, player_stats, player_match_stats, notes, odds add data (anything else is ignored).
Returns: array of {id, first_name, last_name, team:{name, abbrev}, team_id, played_status:{status}, injury_suspension_status_text, positions:[{position, position_long}], notes:[{note, created_on}], player_stats:[{price, price_change, total_price_change, avg, avg3, avg5, ppts1, ppts, owned, total_games, total_points, opp:{abbrev}, opph, oppavg, ven:{name}, venavg, opp1, opp2, opp3, total_<sport stats…>}], player_match_stats:[{games, points}]} — USE ppts1 (real projection, ≈avg, present for afl/nrl; falls back to avg when absent, e.g. nba). AVOID ppts (erratic). In mode=draft each player also carries top-level predraft_rank + player_stats.position_ranks. LARGE.
Example: AFL round-16 forward snapshot (price + projection + matchup) {"sport": "afl", "year": 2026, "round": 16, "embed": "positions,player_stats,notes"}
Auth: none needed.
Inputs: year (required), sport (required), mode, embed, +1 more.
supercoach_real_fixtureARead-onlyIdempotent
Fixtures for one game+season — each carries kickoff, both teams, venue/location, final scores (team1_score/team2_score + verbose), live match_status/period, AND the head-to-head bookmaker odds (team1_odds/team2_odds + bookmaker title/link). Pass round for one round, or omit it for the whole season (AFL ≈ 207 rows). Paginate with page/page_size.
Returns: array of {id, season, round, kickoff, team1, team2, location, venue, team1_score, team2_score, team1_score_verbose, team2_score_verbose, team1_odds, team2_odds, margin_game, match_status, period, period_status, featured, team1_bookmaker_title, team1_bookmaker_link, …}
Example: AFL round-16 fixtures + scores + odds {"sport": "afl", "year": 2026, "round": 16}
Auth: none needed.
Inputs: year (required), sport (required), mode, page, +2 more.
supercoach_settingsARead-onlyIdempotent
Competition state for one game+season: competition.current_round (last round scored), next_round (the one to project), is_lockout / lockout_start / lockout_end, is_closed, num_users, num_leagues. Call this FIRST to learn which round to pass to supercoach_players. Tiny (~15 KB).
Returns: {system, game, content, competition:{current_round, next_round, status, is_lockout, is_partial_lockout, lockout_start, lockout_end, is_closed, num_users, num_leagues}}
Example: AFL current round / next round {"sport": "afl", "year": 2026}
Auth: none needed.
Inputs: year (required), sport (required), min, mode.
supercoach_teamsARead-onlyIdempotent
The club/team catalogue for one game+season (AFL 18, NRL 17, EPL 20, NBA 30, NBL 10, NFL 32, BBL 8) — each with id, name and abbrev. Join team_id from supercoach_players back to here.
Returns: array of {id, name, abbrev, ...}
Example: AFL clubs {"sport": "afl", "year": 2026}
Auth: none needed.
Inputs: year (required), sport (required), mode.
tab_cms_callARead-onlyIdempotent
Fetch one of TAB's CMS content feeds from cmsapi.tab.com.au by operation name (homepage / offers / promotions / racing). Each ships the standard query defaults (platform, os, jurisdiction, authentication-status); override jurisdiction via query_params if needed. Read tab://cms/operations for the list.
Returns: (JSON object)
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: operation (required), path_params, query_params.
tab_competitionARead-onlyIdempotent
Competition page: its matches, bet options and (optionally) top markets.
Returns: {id, name, matches:[{id, name, startTime, _links:{self}}], betOptions, sameGame}
Example: AFL competition page {"sport": "AFL Football", "competition": "AFL"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: sport (required), competition (required), jurisdiction, numTopMarkets.
tab_featured_eventsARead-onlyIdempotent
Editorially featured events across racing + sports for the homepage carousel.
Returns: {nextToGoRaces:[{raceName, raceNumber, raceStartTime}], prioritySports:[{name, competitionName}], nextToGoMatches:[{name, startTime}]}
Example: Featured events for NSW {"jurisdiction": "NSW"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
tab_live_events_summaryARead-onlyIdempotent
Summary of events currently in-play / live across sports.
Returns: {liveMatches:{count, sports:[{name, displayName, count}]}, _links}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
tab_matchARead-onlyIdempotent
Full match book: all markets + bet options, Same Game Multi, contestants, live state and stats.
Returns: {id, name, startTime, markets:[{id, name, betOption, bettingStatus, closeTime}], sameGame, contestants, inPlay, stats}
Example: One AFL match's full markets {"sport": "AFL Football", "competition": "AFL", "match": "Adelaide v Geelong"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: match (required), sport (required), competition (required), jurisdiction.
tab_match_marketsARead-onlyIdempotent
Just the markets + selections + prices for one match (leaner than the full match object).
Returns: {markets:[{id, name, betOption, bettingStatus, propositions:[{name, returnWin}]}], betOptionPriority}
Example: Markets for one AFL match {"sport": "AFL Football", "competition": "AFL", "match": "Adelaide v Geelong"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: match (required), sport (required), competition (required), jurisdiction.
tab_multi_builderARead-onlyIdempotent
Multi-builder items for one sport (suggested legs / combinations for building multis).
Returns: {id, name, sportName, displayName, ...multi-builder markets for the sport}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: sport (required), jurisdiction.
tab_price_slipARead-onlyIdempotent
PRICE A BET SLIP on your own account and get the decoTokens that tab_place_bet requires. The account-tier twin of tab_sgm_price: same envelope, but only this version issues the tokens that bind a bet to a quoted price.
Returns: {uuid, clientDetails:{accountNumber, customerId, channel, jurisdiction, homeState}, bets:[{type, status, stake, legs:[{decoToken, type, propositionId, odds}], multiplierAvailable, …}]} — VERIFIED live 2026-08-27.
THE decoToken IS THE POINT OF THIS CALL. Each priced leg comes back carrying one, and tab_place_bet will not take a leg without it. That token is what binds the bet to a price TAB actually quoted — so unlike Sportsbet, where the client asserts a number and hopes, here the quote is a thing you hold. Price, then place with the tokens you were given; never with tokens from an older enquiry.
THIS IS THE ACCOUNT-TIER TWIN OF tab_sgm_price. Same service, same envelope, but addressed at /accounts/{accountNumber}/ and authenticated — and only this version issues decoTokens. tab_sgm_price stays the right tool for comparing prices across books; this one is for the moment before placing.
bets[].status is 'ok' on a priced bet, and per-leg errors surface alongside rather than as an HTTP failure — read them before assuming a price.
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: bets (required), uuid (required), jurisdiction (required), accountNumber (required), +2 more.
tab_racing_datesARead-onlyIdempotent
Racing dates that have meetings (today, tomorrow, future), each linking to its meetings.
Returns: {dates:[{meetingDate, dateName, _links:{meetings}}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
tab_racing_futures_meetingsARead-onlyIdempotent
Futures racing meetings (ante-post / long-dated markets like Cup outrights).
Returns: {meetings:[{meetingName, raceType, races:[{raceName, meetingDate, _links}]}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: returnPromo, jurisdiction, returnOffers.
tab_racing_futures_raceARead-onlyIdempotent
Racecard for one FUTURES market: futures URLs put the race NAME (not a number) in the race slot, so the integer-typed tab_racing_race cannot reach them.
Returns: {raceName, raceStartTime, runners:[{runnerNumber, runnerName, fixedOdds:{returnWin, returnPlace, bettingStatus}}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), raceName (required), raceType (required), fixedOdds, +2 more.
tab_racing_jackpotsARead-onlyIdempotent
Current racing jackpot / carryover pools across meetings.
Returns: {jackpots:[{poolType, meeting, amount}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Also answers this: pointsbet_racing_hourly_quaddie.
Inputs: jurisdiction.
tab_racing_meeting_racesARead-onlyIdempotent
The races for one meeting (by race type + venue code), each linking to its full racecard.
Returns: {races:[{raceNumber, raceName, raceStartTime, raceStatus, hasFixedOdds, _links:{self, form}}]}
Example: Races at the Hawkesbury thoroughbred meeting {"date": "", "raceType": "R", "venueMnemonic": "HAW"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), raceType (required), venueMnemonic (required), jurisdiction.
tab_racing_meetingsARead-onlyIdempotent
All race meetings (thoroughbred/greyhound/harness) for a date, each with its races.
Returns: {meetings:[{meetingName, location, raceType, venueMnemonic, trackCondition, races:[{raceNumber, raceName, raceStartTime}], _links:{races}}]}
Example: All meetings for a day {"date": ""}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), returnPromo, jurisdiction, returnOffers.
tab_racing_next_to_goARead-onlyIdempotent
Races about to jump across all codes, ordered by start time; each links to its racecard.
Returns: {races:[{raceName, meeting:{venueMnemonic, raceType}, raceStartTime, raceNumber, _links:{self}}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: returnPromo, jurisdiction, returnOffers, includeFixedOdds.
tab_racing_raceARead-onlyIdempotent
Full racecard for one race: runners with fixed + parimutuel odds, form ratings, pools, bet types; results + dividends once run.
Returns: {raceNumber, raceName, raceDistance, raceStartTime, runners:[{runnerNumber, runnerName, fixedOdds, parimutuel, riderDriverName, barrierNumber, last5Starts}], results, pools, betTypes, multiLegApproximates}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), raceType (required), raceNumber (required), venueMnemonic (required), +1 more.
tab_racing_race_formARead-onlyIdempotent
Detailed form guide for one race (past performances, ratings, comments per runner).
Returns: {raceNumber, formData:[{runnerNumber, runnerName, pastPerformances:[]}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Also answers this: betr_race_form, pointsbet_racing_form.
Inputs: date (required), raceType (required), raceNumber (required), venueMnemonic (required), +1 more.
tab_racing_runner_formARead-onlyIdempotent
DETAILED per-runner form: full past-start history with positions, margins, distances and dates.
Returns: {runnerName, runnerNumber, previousStarts/pastPerformances:[{position, fieldSize?, distance, date, margin, ...}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: date (required), raceType (required), raceNumber (required), runnerNumber (required), +2 more.
tab_recommendation_featuredARead-onlyIdempotent
Featured items for one recommendation category (e.g. Jockey Challenge, Racing Extras). 404s when the category isn't currently featured.
Returns: {id, name, displayName, competitions:[{id, name, hasMarkets, _links}], _links}
Example: Featured Jockey Challenge markets {"category": "Jockey Challenge"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: category (required), jurisdiction.
tab_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it propositions from one match, get the combined price and a validation matrix back. Prices combinations TAB has not pre-built.
Returns: {bets:[{status:'ok', legs:[{odds:{decimal:'15.00'}, propositions:[…], redundantPropositions:[{propositionId, status:'redundant'|'valid'}]}]}]} — VERIFIED live 2026-08-28 against AFL Wst Bulldogs v Collingwood: H2H Bulldogs (1.95) + Naughton first goal (11.00) priced 15.00.
THE PRICE IS NOT THE PRODUCT OF THE LEGS. 1.95 x 11.00 is 21.45; TAB returns 15.00, because it applies a correlation adjustment — which is the whole reason to ask rather than multiply. Here it priced DOWN (a Bulldogs win makes a Bulldogs player scoring first likelier); other combinations price up.
REDUNDANT LEGS ARE COLLAPSED, NOT REFUSED. Pick two propositions that imply one another (both sides of a line, say) and TAB drops one, marks it redundant, and prices what is left — so a two-leg request can come back as a one-leg price. ALWAYS check redundantPropositions before reporting: the odds you got may not be the bet you asked for.
Only markets with sameGame: true in tab_match_markets can be combined (52 of 109 on the verified match).
Example: Price a two-leg AFL same game multi {"jurisdiction": "NSW", "bets": [{"type": "FIXED_ODDS", "legs": [{"type": "SAME_GAME_MULTI", "propositions": [{"type": "WIN", "propositionId": 1016}, {"type": "WIN", "propositionId": 8529}]}]}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: bets (required), jurisdiction (required), channel, returnValidationMatrix.
tab_sportARead-onlyIdempotent
One sport by name with its competitions. Also fronts the racing-adjacent pseudo-sports (Jockey Challenge, Racing Extras).
Returns: {id, name, competitions:[{id, name, _links:{self}}]}
Example: AFL Football and its competitions {"sport": "AFL Football"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: sport (required), jurisdiction.
tab_sportsARead-onlyIdempotent
All sports offered, each linking to its competitions (HATEOAS root for the sports tree).
Returns: {sports:[{id, name, displayName, _links:{self}}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
tab_sports_next_to_goARead-onlyIdempotent
Sport events about to close, ordered by close time (next-to-go sports feed).
Returns: {matches:[{name, competition, startTime, _links:{self}}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: next, limit, openOnly, futuresOnly, +3 more.
tab_sports_resultsARead-onlyIdempotent
Recently resulted sport events with final scores / settled markets.
Returns: {sports:[{name, competitions:[{matches:[{name, results}]}]}]}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
tab_tournamentARead-onlyIdempotent
Tournament page nested inside a competition (tennis, golf and other tournament-structured sports): its matches with top markets. Competitions whose page shows matches:[] list their events here.
Returns: {id, name, matches:[{id, name, startTime, markets:[...]}], betOptions}
Example: Wimbledon Mens Singles matches {"sport": "Tennis", "competition": "Wimbledon", "tournament": "Wimbledon Mens Singles"}
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: sport (required), tournament (required), competition (required), jurisdiction, +1 more.
tab_trending_propsBRead-onlyIdempotent
Trending sports propositions / bets across the book.
Returns: [{sportName, competitionName, matchName, matchId, ...}] (top-level array)
Auth: works without a key; TAB_CLIENT_ID or TAB_CLIENT_SECRET or TAB_REFRESH_TOKEN unlocks more if set.
Inputs: jurisdiction.
theoddsapi_event_oddsARead-onlyIdempotent
Odds for ONE event, including player props and other markets not available on the competition-wide call.
Returns: {id, sport_key, commence_time, home_team, away_team, bookmakers:[{key, title, markets:[{key, outcomes:[{name, price, point, description}]}]}]} — a single object, unlike the competition call's array; description carries the player name on prop markets
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One event's markets {"sport": "soccer_epl", "eventId": "", "regions": ["au"], "markets": ["h2h"]}
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: sport (required), eventId (required), markets, regions, +1 more.
theoddsapi_eventsARead-onlyIdempotent
Upcoming events for a competition WITHOUT odds. Free — costs no quota — so use it to find event ids cheaply.
Returns: [{id, sport_key, sport_title, commence_time, home_team, away_team}] (top-level array, no bookmakers)
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Upcoming EPL fixtures {"sport": "soccer_epl"}
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: sport (required), dateFormat.
theoddsapi_historical_oddsARead-onlyIdempotent
Odds as they stood at a past timestamp — the paid-tier time machine for CLV work.
Returns: {timestamp, previous_timestamp, next_timestamp, data:[…same shape as theoddsapi_odds…]} — WRAPPED in a snapshot envelope, unlike the live call. Historical access is a PAID add-on: the free tier returns 401/422 here.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: EPL odds at a past moment {"sport": "soccer_epl", "date": "2024-08-16T12:00:00Z", "regions": ["au"], "markets": ["h2h"]}
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: date (required), sport (required), markets, regions, +1 more.
theoddsapi_oddsARead-onlyIdempotent
Odds for a competition across many bookmakers. QUOTA COSTS markets × regions per call — keep both narrow.
Returns: [{id, sport_key, sport_title, commence_time, home_team, away_team, bookmakers:[{key, title, last_update, markets:[{key:'h2h', last_update, outcomes:[{name, price, point}]}]}]}] — outcome name is a TEAM NAME, not home/away; point appears on spreads/totals only
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: EPL head-to-head across AU books {"sport": "soccer_epl", "regions": ["au"], "markets": ["h2h"]}
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: sport (required), markets, regions, eventIds, +3 more.
theoddsapi_scoresARead-onlyIdempotent
Live and recently-completed scores for a competition.
Returns: [{id, sport_key, commence_time, completed, home_team, away_team, scores:[{name, score}], last_update}] — scores is null until the game starts; score values are STRINGS
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Recent EPL scores {"sport": "soccer_epl", "daysFrom": 1}
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: sport (required), daysFrom, dateFormat.
theoddsapi_sportsARead-onlyIdempotent
Every sport/competition with its key. FREE — this call costs no quota. Start here to get the sport_key the other tools need.
Returns: [{key:'americanfootball_nfl', group:'American Football', title, description, active, has_outrights}] (top-level array)
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: In-season competitions
Auth: needs your own key in THE_ODDS_API_KEY.
Inputs: all.
twitter_liking_usersARead-onlyIdempotent
Users who liked a given post.
Returns: {data:[{id, username, name}], meta:{result_count}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), max_results, user_fields.
twitter_quote_tweetsARead-onlyIdempotent
Posts quoting a given post.
Returns: {data:[{id, text, author_id, public_metrics}], meta:{result_count, next_token}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), max_results, tweet_fields, pagination_token.
twitter_retweeted_byARead-onlyIdempotent
Users who reposted a given post.
Returns: {data:[{id, username, name, verified, public_metrics}], meta:{result_count}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), max_results, user_fields.
twitter_search_recentARead-onlyIdempotent
Search posts from the last 7 days with X's query operators (e.g. '"Lakers" lang:en -is:retweet').
Returns: {data:[{id, text, created_at, author_id, lang, public_metrics:{retweet_count, reply_count, like_count, impression_count}}], includes:{users:[…]}, meta:{result_count, newest_id, next_token}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: query (required), end_time, since_id, expansions, +6 more.
twitter_trendsARead-onlyIdempotent
Trending topics for a location by WOEID (1 = worldwide, 23424977 = US, 23424748 = Australia, 23424975 = UK).
Returns: {data:[{trend_name, tweet_count}]}
Example: Worldwide trends {"woeid": 1}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: woeid (required), max_trends, trend_fields.
twitter_tweetARead-onlyIdempotent
One post by id.
Returns: {data:{id, text, created_at, author_id, public_metrics}, includes:{users:[…]}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), expansions, user_fields, tweet_fields.
twitter_tweet_countsARead-onlyIdempotent
Post volume over time for a query (last 7 days) — the cheap way to gauge buzz without reading posts.
Returns: {data:[{start, end, tweet_count}], meta:{total_tweet_count}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: query (required), end_time, start_time, granularity.
twitter_tweetsARead-onlyIdempotent
Batch post lookup by ids (up to 100) with engagement metrics.
Returns: {data:[{id, text, created_at, author_id, public_metrics}], includes:{users:[…]}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: ids (required), expansions, user_fields, tweet_fields.
twitter_usageARead-onlyIdempotent
This project's post-read usage against its monthly cap — check before burning quota.
Returns: {data:{cap_reset_day, project_cap, project_usage, daily_project_usage}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: days, usage_fields.
twitter_userARead-onlyIdempotent
One account by numeric user id.
Returns: {data:{id, username, name, description, public_metrics}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), user_fields.
twitter_user_by_usernameARead-onlyIdempotent
One account's public profile by @handle (without the @).
Returns: {data:{id, username, name, description, verified, public_metrics:{followers_count, following_count, tweet_count}}}
Example: The NBA's official account {"username": "NBA"}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: username (required), user_fields.
twitter_user_mentionsARead-onlyIdempotent
Recent posts mentioning an account.
Returns: {data:[{id, text, created_at, author_id, public_metrics}], meta:{result_count}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), since_id, max_results, tweet_fields, +1 more.
twitter_usersARead-onlyIdempotent
Batch account lookup by numeric ids (up to 100).
Returns: {data:[{id, username, name, public_metrics}]}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: ids (required), user_fields.
twitter_users_by_usernamesARead-onlyIdempotent
Batch profile lookup by handles (up to 100).
Returns: {data:[{id, username, name, public_metrics}]}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: usernames (required), user_fields.
twitter_user_tweetsARead-onlyIdempotent
An account's recent posts (club announcements, insider news). Resolve the id with twitter_user_by_username first.
Returns: {data:[{id, text, created_at, public_metrics}], meta:{result_count, newest_id, next_token}}
Auth: needs your own key in X_BEARER_TOKEN.
Inputs: id (required), exclude, end_time, since_id, +4 more.
ufc_athleteARead-onlyIdempotent
One fighter with FULL career statistics and current ranking attached. The main athlete tool.
Returns: {data:[{attributes:{title, nickname, age, dob, octagon_debut, stats_height, stats_weight, stats_reach_arm, stats_reach_leg, strengths, origin:{country_code}, residence, fightmetric_id, short_description}}], included:[{type:'athlete_stat--athlete_stat', attributes:{…see ufc_athlete_stats for the full field list…}}, {type:'athlete_ranking--athlete_ranking', attributes:{weight_class_rank, weight_class_rank_previous, is_interim}}]} — heights, weights and reaches are INCHES/POUNDS as decimal strings. The statistics live in included, NOT on the athlete.
Example: A champion with stats and ranking {"title": "Ilia Topuria"}
Auth: none needed.
Inputs: title (required), limit, include.
ufc_athlete_statsARead-onlyIdempotent
League-wide FightMetric statistics, sortable — the all-time leaderboards. For ONE fighter's stats use ufc_athlete instead; this collection cannot be filtered.
Returns: {data:[{attributes:{drupal_internal__fightmetric_id, career_fights, career_wins, career_losses, career_draws, career_no_contest, win_ko, win_sub, win_dec, first_rd_fin, title_def, win_streak, former_champion, avg_fight_time (SECONDS), total_bonuses, total_performance_night, total_fight_night, sig_strikes_landed, sig_strikes_attempted, sig_strikes_accuracy, stand_str_land, stand_str_att, clinch_str_land, clinch_str_att, ground_str_land, ground_str_att, head_str_land, head_str_att, body_str_land, body_str_att, leg_str_land, leg_str_att, takedowns_landed, takedowns_attempted, takedown_acuracy, takedown_defense, takedown_average, submission_average, knockdown_average, sig_str_land_min, sig_str_abs_min, sig_str_def}}]} — NOTE takedown_acuracy is spelled that way UPSTREAM (one 'c'); percentages and per-minute rates are STRINGS; avg_fight_time is seconds; the *_average fields are per-15-minutes, which is the standard MMA convention.
WARNING: this collection CANNOT be filtered — filter[fightmetric_id] returns 0 rows rather than an error, even for an id present on page 1 (verified). To get one fighter, call ufc_athlete, which resolves the same record through include and DOES work. Sorting works fine, which is what makes this the leaderboard tool.
Example: All-time significant-strike leaders {"sort": "-sig_strikes_landed", "limit": 10}
Auth: none needed.
Inputs: sort, limit, offset.
ufc_event_cardARead-onlyIdempotent
One event WITH its full fight card attached. Use this rather than ufc_events when you want the bouts.
Returns: {data:[{attributes:{title, fight_card_time_main, event_card_location}, relationships:{fights:{data:[{type:'node--fight', id}]}}}], included:[{type:'node--fight', id, attributes:{title:'Fighter A vs Fighter B'}, relationships:{red_corner, blue_corner, fight_final_winner}}, {type:'node--athlete', …}]} — the CARD IS IN included, matched to data[0].relationships.fights.data[].id. Nothing useful is inline.
Example: A numbered event's full card {"title": "UFC 330"}
Auth: none needed.
Inputs: title (required), limit, include.
ufc_eventsARead-onlyIdempotent
UFC events — past and upcoming — with per-segment card times, venue and location.
Returns: {data:[{type:'node--event', id, attributes:{title:'UFC 330', number:330, subtitle, main_fight_name, fight_card_time_early, fight_card_time_prelims, fight_card_time_main, event_card_location:'Xfinity Mobile Arena, Philadelphia United States', main_card_time_localized, fightmetric_id, path:{alias:'/event/ufc-330'}}, relationships:{fights, venue, event_status, title_fight}}], links:{next, self}} — the three card times are the early prelims, prelims and main card, each with a timezone offset.
Example: The most recent events {"sort": "-fight_card_time_main", "limit": 10}
Auth: none needed.
Inputs: sort, limit, title, offset, +1 more.
ufc_fightsARead-onlyIdempotent
Individual bouts — both corners and the winner — back to UFC 1.
Returns: {data:[{attributes:{title:'Royce Gracie vs Ken Shamrock', created, changed}, relationships:{red_corner:{data:{type:'node--athlete', id}}, blue_corner:{…}, fight_final_winner:{…}, fight_status}}], included:[…athletes…]} — fight_final_winner is null for an upcoming or drawn bout, so do not infer a loser from its absence.
Example: Recent bouts with fighters resolved {"limit": 10}
Auth: none needed.
Inputs: sort, limit, title, offset, +1 more.
ufc_jsonapi_indexARead-onlyIdempotent
The JSON:API resource index — all 291 resource types ufc.com exposes, for discovering surfaces this spec does not wrap yet.
Returns: {jsonapi:{version}, links:{'node--event':{href}, 'node--athlete':{href}, 'athlete_stat--athlete_stat':{href}, …291 entries…}} — each key is a resource type and its href is the collection URL. Useful when you need something this provider does not expose; most of the 291 are CMS plumbing (paragraphs, media, config) rather than sport data.
Example: Every exposed resource type
Auth: none needed.
Inputs: no named parameters.
ufc_rankingsARead-onlyIdempotent
Divisional rankings, including pound-for-pound, with each fighter's previous position.
Returns: [{attributes:{fightmetric_id, weight_class_rank, weight_class_rank_previous, meta_weight_class_rank, meta_weight_class_rank_previous, is_interim, category}}] — category distinguishes the division (0 appears to be pound-for-pound); compare weight_class_rank with weight_class_rank_previous for movement. Resolve fightmetric_id to a name via ufc_search_athletes.
WARNING: like the other custom-entity collections here, this one CANNOT be filtered — filter[fightmetric_id] returns 0 rows rather than an error (verified). Page the whole set (~200 rows) and match client-side; for one fighter's current ranking, ufc_athlete resolves it through include.
Example: Rankings from the top {"limit": 50}
Auth: none needed.
Inputs: sort, limit, offset.
ufc_round_recordsARead-onlyIdempotent
The single-round record book: most significant strikes, total strikes, takedowns and submission attempts in one round, ranked.
Returns: [{attributes:{fightmetric_id, rank, round, statname, value (a STRING), combined}}] — combined: true means BOTH fighters' totals in that round; false is one fighter's. Mixing the two produces a nonsense leaderboard, so filter on it if you care. Resolve fightmetric_id to a name via ufc_search_athletes.
WARNING: filter[round] and filter[statname] return 0 rows rather than an error (verified) — filter the rows yourself. statname is one of: Significant Strikes Landed/Attempted, Total Strikes Landed/Attempted, Takedowns Landed/Attempted, Submission Attempts; round is 1-5.
Example: The round record book {"limit": 50}
Auth: none needed.
Inputs: sort, limit, offset.
ufc_search_athletesARead-onlyIdempotent
Find fighters by partial name. Start here — every other athlete tool needs an exact title or an id.
Returns: {data:[{type:'node--athlete', id:'', attributes:{title:'Israel Adesanya', nickname, fightmetric_id, path:{alias:'/athlete/israel-adesanya'}}}]} — keep BOTH the uuid id (for JSON:API lookups) and fightmetric_id (for joining to stats and round records).
Example: Search by surname {"name": "Adesanya"}
Auth: none needed.
Inputs: name (required), limit, operator.
unibet_kambi_callARead-onlyIdempotent
Fetch a Unibet/Kambi sportsbook resource by operation name (market AU). The lang/market/channel_id defaults are carried, so the caller supplies only the variable path/query params (eventId, sport, groupId). Read unibet://sport/operations for the operation list.
Returns: (JSON object)
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: operation (required), path_params, query_params.
unibet_kambi_live_statsARead-onlyIdempotent
Live in-event statistics (scores, match summary) for one Kambi event.
Returns: {eventId, summary:{...live stats}}
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: eventId (required), lang, market, channel_id.
unibet_kambi_odds_ladderARead-onlyIdempotent
Kambi odds-ladder reference (the decimal-odds increments the book uses).
Returns: [{name, steps:[{odds, converted}]}] (top-level array — fractional + decimal ladders)
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: no named parameters.
unibet_racing_callARead-onlyIdempotent
Call any of Unibet's persisted racing GraphQL operations against
rsa.unibet.com.au/api/v1/graphql by name + variables. The sha256 hash lives
server-side; a PERSISTED_QUERY_NOT_FOUND error means the bundle drifted. Race
identifiers are eventKeys like "202606040200.T.AUS.hawkesbury.1"
(date.raceType.country.track.raceNumber). Read unibet://racing/operations for
the op list + variable signatures.
Returns: (JSON object)
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: operation (required), variables.
unibet_sgm_priceARead-onlyIdempotent
PRICE A SAME GAME MULTI you choose — give it two or more outcome ids from one Unibet/Kambi event and get the correlation-adjusted Bet Builder price, plus the list of outcomes eligible to join it. Prices combinations Unibet has not pre-built (for those, see unibet_kambi_call operation='event_prepack').
Returns: {eventId, selectedOutcomeIds:[…], selectedOdds:{decimal: 3400, american, fractional}, combinableOutcomeIds:[…]} — VERIFIED live 2026-08-27 against AFL Western Bulldogs v Collingwood (event 1028856020), unauthenticated.
ODDS ARE IN THOUSANDTHS. decimal: 3400 MEANS 3.40, not 3400. Kambi does this everywhere — the odds and line on every outcome in the betoffer feed are scaled the same way (1920 = 1.92, line 1500 = +1.5) — and a price reported 1000x too large is the loudest wrong answer available. Divide by 1000.
THE PRICE IS NOT THE PRODUCT OF THE LEGS. Bulldogs head-to-head (1.92) with Over 170.5 (1.88) prices 3.40, against a naive 3.6096.
1001.0 IS A CEILING, NOT A PRICE. Long multis stop moving at decimal: 1001000 — six, eight, ten, twelve and fourteen legs all returned exactly that on the verified event while the naive product kept climbing. Treat 1001.0 as capped, never as a quote and never as an edge.
selectedOutcomeIds IS THE ECHO, AND IT IS WHY THIS IS THE SAFE ONE. Unibet is the only book of the five that says exactly what it priced. Duplicate ids are deduplicated SILENTLY, so compare this list against what you sent before reporting anything.
A SINGLE LEG RETURNS NO PRICE AT ALL — selectedOdds is simply ABSENT rather than an error, and the same happens when duplicates collapse to one leg. A missing key here means not priced, not zero.
combinableOutcomeIds IS ELIGIBILITY, NOT COMPATIBILITY. It lists what can EVER appear in a bet builder on this event — 940 of the event's 1137 outcomes on the verified fixture — and does NOT drop what clashes with your current picks: both the opposite head-to-head side and the line the head-to-head already implies stayed listed, and both then failed with a 400. Its real use is separating a leg that is INELIGIBLE from one that merely CONFLICTS, which the error message does not do.
REFUSALS ARE REAL HTTP STATUS CODES WITH A TYPED BODY — the only book of the five that uses them properly, so no error signal is needed here. Four seen live, and they mean different things: 400 'Combination is not supported by the selected strategy' for legs that clash or imply one another; 400 'Invalid outcomes' with an invalidOutcomes list naming ids that are not BET-BUILDER ELIGIBLE (an ordinary outcome from the betoffer feed can be rejected this way — check it against combinableOutcomeIds first); 409 'Impossible outcome selection', with invalidOutcomes EMPTY, when the combination cannot happen at all (Bulldogs to win with Collingwood by 1-39); and 400 'Unknown event'. The empty list on the 409 is not a bug to route around — the impossibility is in the COMBINATION, so no single id is at fault.
The upstream body also repeats the event's ENTIRE bet-offer book — 626 offers, 647 KB of a 610 KB response — which unibet_kambi_call(operation='event_betoffer') already returns. It is projected away here.
Example: Price Bulldogs to win with over 170.5 points {"eventId": 1028856020, "outcomeIds": "4306981996,4309057043"}
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: eventId (required), outcomeIds (required), lang, market, +1 more.
unibet_validate_couponARead-onlyIdempotent
VALIDATE AND RE-PRICE a bet slip before placing it — the pre-placement go/no-go. Send the exact Kambi coupon you intend to place; it returns the current price and rejects an impossible or clashing combination, the same check Unibet's betslip fires. Anonymous (no login). Call IMMEDIATELY before unibet_place_bet and only place if this comes back clean.
Returns: VERIFIED live 2026-08-27: {status: "SUCCESS", validSession: , rewardInfo:{validRewards, validGroupRewards, implicitGroupRewards}}.
THE ANSWER IS status, and on a good coupon it is the STRING "SUCCESS" — not a number, not an absence. A rejection uses the same envelope with a different status and a message.
IT DOES NOT ECHO A PRICE. There are no couponRows in the reply, so this call CANNOT be used to re-price a bet — an earlier version of the betting plane tried to read couponRows[].odds back from here and would have refused every placement. Use unibet_sgm_price (anonymous, returns selectedOdds.decimal in thousandths) to check drift, and use THIS call for the go/no-go.
validSession reports whether the bearer is still good — the cheapest way to tell a dead token from a bad coupon.
rewardInfo.validGroupRewards[] lists promotions that would apply, e.g. a PROFIT_BOOST with boostPercentage/maxStake/maxExtraWinnings. Ignore it for pricing: the boost changes the payout, not the odds struck.
Rate limits are published in headers: x-ratelimit-remaining and x-ratelimit-reset (seconds).
Auth: works without a key; UNIBET_ACCESS_TOKEN unlocks more if set.
Inputs: body (required), lang, market, channel_id.
wta_playerARead-onlyIdempotent
A single WTA player by id — {id, firstName, lastName, fullName, countryCode, dateOfBirth, metadata}. playerId comes from wta_players / wta_rankings.
Returns: {id, firstName, lastName, fullName, countryCode, dateOfBirth, metadata}
Example: Aryna Sabalenka {"playerId": 320760}
Auth: none needed.
Inputs: playerId (required).
wta_player_matchesARead-onlyIdempotent
One player's match history — {player, matches:[{TournamentName, TournamentLevel, Surface, StartDate, city, Country, PrizeWon, entry_rank_1/2, entry_type_1/2, …}]}. The per-tournament results/log for a player.
Returns: {player:{…}, matches:[{TournamentName, TournamentLevel, TournamentType, Surface, StartDate, city, Country, DrawSizes, PrizeMoney, PrizeWon, entry_rank_1, entry_rank_2, entry_type_1, entry_type_2}]}
Example: Sabalenka's recent matches {"playerId": 320760}
Auth: none needed.
Inputs: playerId (required).
wta_playersARead-onlyIdempotent
The WTA player catalogue — {pageInfo, content:[{id, firstName, lastName, fullName, countryCode, dateOfBirth}]}. Search by name (e.g. 'Swiatek' → Iga Swiatek) or page through all. The player id feeds wta_player / wta_player_matches.
Returns: {pageInfo:{numPages, totalElements}, content:[{id, firstName, lastName, fullName, countryCode, dateOfBirth, metadata}]}
Example: Find Iga Swiatek {"name": "Swiatek"}
Auth: none needed.
Inputs: name, page, pageSize.
wta_rankingsARead-onlyIdempotent
The WTA rankings — each row is {player:{id, fullName, countryCode, dateOfBirth}, ranking, points, tournamentsPlayed, movement, rankedAt}. Returns a bare ARRAY (not the {pageInfo,content} envelope). REQUIRES type + metric, which must agree: rankSingles+singles or rankDoubles+doubles. Page with page/pageSize (e.g. pageSize=100 for the top 100).
Returns: array of {player:{id, firstName, lastName, fullName, countryCode, dateOfBirth}, ranking, points, tournamentsPlayed, movement, rankedAt}
Example: Top 100 WTA singles rankings {"type": "rankSingles", "metric": "singles", "pageSize": 100}
Auth: none needed.
Inputs: type (required), metric (required), page, pageSize.
wta_tournamentARead-onlyIdempotent
One tournament edition by tournamentGroup id + year (e.g. group 901 = Australian Open, /901/2025). Full metadata: dates, surface, draw sizes, prize money, level, status, winners. ids from wta_tournaments (content[].tournamentGroup.id + .year).
Returns: {tournamentGroup:{id, name, level}, year, title, startDate, endDate, surface, inOutdoor, city, country, singlesDrawSize, doublesDrawSize, prizeMoney, level, status, winners}
Example: Australian Open 2025 {"groupId": 901, "year": 2025}
Auth: none needed.
Inputs: year (required), groupId (required).
wta_tournament_matchesARead-onlyIdempotent
All matches/results for one tournament edition (group id + year) — e.g. AO 2025 returns ~302 matches with court, draw level/type, entrant types, match state and ids. Use for draws + results.
Returns: {tournament:{…}, matches:[{MatchID, EventID, EventYear, CourtID, DateSeq, DrawLevelType, DrawMatchType, EntryTypeA, EntryTypeB, GrandSlam, MatchState, LastUpdated}]}
Example: Australian Open 2025 results {"groupId": 901, "year": 2025}
Auth: none needed.
Inputs: year (required), groupId (required).
wta_tournament_playersARead-onlyIdempotent
The entry list / draw for one tournament edition — {events:[{eventTypeCode, eventPlayers:[{players:[{id, firstName, lastName}], seed, entryType, eliminated, winner, runnerUp}]}]}. One event per discipline (eventTypeCode LS = Ladies Singles, LD = Ladies Doubles). Carries seeding, entry type, and final results (winner/runnerUp/eliminated). E.g. AO 2025 singles = 128 entrants.
Returns: {events:[{description, eventTypeCode, eventPlayers:[{players:[{id, firstName, lastName, countryCode}], seed, entryType, eliminated, winner, runnerUp}]}]}
Example: Australian Open 2025 entry list + seeds {"groupId": 901, "year": 2025}
Auth: none needed.
Inputs: year (required), groupId (required).
wta_tournamentsARead-onlyIdempotent
The WTA tournament calendar — {pageInfo, content:[{tournamentGroup:{id, name, level}, year, title, startDate, endDate, surface, inOutdoor, city, country, singlesDrawSize, doublesDrawSize, prizeMoney, level, status, winners}]}. Take a row's tournamentGroup.id + year for wta_tournament / wta_tournament_matches. Page through with page/pageSize (the list spans all years).
Returns: {pageInfo:{numPages, totalElements}, content:[{tournamentGroup:{id, name, level}, year, title, startDate, endDate, surface, inOutdoor, city, country, singlesDrawSize, doublesDrawSize, prizeMoney, prizeMoneyCurrency, level, status, winners, liveScoringId}]}
Example: Browse tournaments {"pageSize": 50}
Auth: none needed.
Inputs: page, pageSize.
yahoo_gameARead-onlyIdempotent
Game metadata for a sport-season: season year, whether it is over, and the game_key other calls need.
Returns: {fantasy_content:{game:[{game_key, game_id, name, code, type:'full', url, season, is_registration_over, is_game_over, is_offseason}]}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Current NFL season {"gameKey": "nfl"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: gameKey (required), format.
yahoo_game_roster_positionsARead-onlyIdempotent
The roster positions a game defines (QB, RB, FLEX, BN, IR…) — needed to build a valid lineup write.
Returns: {fantasy_content:{game:[{game_key}, {roster_positions:[{roster_position:{position:'QB', position_type:'O', is_starting_position}}]}]}} — SHAPE FROM VENDOR DOCS. is_starting_position distinguishes a starting slot from BN/IR, which is exactly what a lineup optimiser needs.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL roster positions {"gameKey": "nfl"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: gameKey (required), format.
yahoo_game_stat_categoriesARead-onlyIdempotent
Every stat category a game scores, with its id — the lookup that makes scoring settings and player stats readable.
Returns: {fantasy_content:{game:[{game_key}, {stat_categories:{stats:[{stat:{stat_id, name:'Passing Yards', display_name:'Pass Yds', sort_order, position_types}}]}}]}} — SHAPE FROM VENDOR DOCS. Player stats and league scoring both refer to bare stat_ids; without this they are unreadable numbers.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL stat categories {"gameKey": "nfl"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: gameKey (required), format.
yahoo_leagueARead-onlyIdempotent
League metadata: name, size, scoring type, current week, and the season's week range.
Returns: {fantasy_content:{league:[{league_key, league_id, name, url, num_teams, scoring_type:'head'|'point'|'roto', league_type, current_week, start_week, end_week, start_date, end_date, is_finished}]}} — SHAPE FROM VENDOR DOCS. current_week drives every week-scoped call below.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One league {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_league_draftARead-onlyIdempotent
Draft results — every pick in order with round, team and player.
Returns: {fantasy_content:{league:[{league_key}, {draft_results:{'0':{draft_result:{pick, round, team_key, player_key}}, count}}]}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Draft results {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_league_playersARead-onlyIdempotent
The player pool filtered by availability — free agents, waivers, or all. The add/drop shortlist.
Returns: {fantasy_content:{league:[{league_key}, {players:{'0':{player:[[{player_key}, {player_id}, {name:{full, first, last}}, {editorial_team_abbr}, {display_position}, {eligible_positions}, {status:'IR'|'O'|'Q'}, {percent_owned}]]}, count}}]}} — SHAPE FROM VENDOR DOCS. HARD-CAPPED AT 25 PER PAGE: walk start to see more, and expect several calls for a full pool.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Available players {"leagueKey": "449.l.12345", "status": "A"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), count, start, format, +1 more.
yahoo_league_scoreboardARead-onlyIdempotent
One week's matchups with both teams' points — live during a week, final after.
Returns: {fantasy_content:{league:[{league_key}, {scoreboard:{'0':{matchups:{'0':{matchup:{week, status, is_playoffs, teams:{'0':{team:[…, {team_points:{total}}, {team_projected_points:{total}}]}, count:2}}}, count}}, week}}]}} — SHAPE FROM VENDOR DOCS. Note team_projected_points alongside actual, which is what an in-week win-probability read needs.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A week's matchups {"leagueKey": "449.l.12345", "week": 1}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: week (required), leagueKey (required), format.
yahoo_league_settingsARead-onlyIdempotent
The rules: roster slots, scoring weights, waiver type, trade deadline, playoff structure. Read this before proposing anything.
Returns: {fantasy_content:{league:[{league_key}, {settings:[{draft_type, scoring_type, uses_playoff, playoff_start_week, uses_faab, waiver_type:'FR'|'CO', waiver_rule, trade_end_date, trade_ratify_type, roster_positions:[{roster_position:{position, count}}], stat_categories:{stats:[…]}, stat_modifiers:{stats:[{stat:{stat_id, value}}]}}]}]}} — SHAPE FROM VENDOR DOCS. uses_faab decides whether waivers are budget bids or priority order — an agent must know which before claiming.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: League rules {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_league_standingsARead-onlyIdempotent
Standings with each team's record, points for/against and playoff seed.
Returns: {fantasy_content:{league:[{league_key}, {standings:[{teams:{'0':{team:[[{team_key}, …], {team_standings:{rank, outcome_totals:{wins, losses, ties, percentage}, points_for, points_against, streak}}]}, count}}]}]}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: League standings {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_league_teamsARead-onlyIdempotent
Every team in the league with its manager — how you map team_key to a person.
Returns: {fantasy_content:{league:[{league_key}, {teams:{'0':{team:[[{team_key}, {team_id}, {name}, {url}, {team_logos}, {waiver_priority}, {faab_balance}, {number_of_moves}, {number_of_trades}, {managers:[{manager:{nickname, guid, is_commissioner}}]}]]}, count}}]}} — SHAPE FROM VENDOR DOCS. faab_balance and waiver_priority are what a waiver strategy is built on.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Teams in a league {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_league_transactionsARead-onlyIdempotent
Adds, drops, waiver claims and trades across the league — who is doing what.
Returns: {fantasy_content:{league:[{league_key}, {transactions:{'0':{transaction:[{transaction_key, transaction_id, type:'add'|'drop'|'add/drop'|'trade'|'commish', status:'successful'|'pending', timestamp, faab_bid}, {players:{…}}]}, count}}]}} — SHAPE FROM VENDOR DOCS. faab_bid on successful claims is the market price of a player in your league — the single most useful input for bidding.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: League transactions {"leagueKey": "449.l.12345"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), format.
yahoo_my_gamesARead-onlyIdempotent
Which fantasy games the authenticated user plays. START HERE — everything else needs a game_key from this.
Returns: {fantasy_content:{users:{'0':{user:[{guid}, {games:{'0':{game:[{game_key:'449', game_id, name:'Football', code:'nfl', season:'2025', is_over}]}, count}}]}, count}}} — SHAPE FROM VENDOR DOCS. Note users and games are OBJECTS keyed '0','1',… with a count sibling, and user is a two-element ARRAY of [meta, {games}].
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: The user's games
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: format.
yahoo_my_leaguesARead-onlyIdempotent
The authenticated user's leagues for one or more games — where you get league_key.
Returns: {fantasy_content:{users:{'0':{user:[{guid}, {games:{'0':{game:[{game_key}, {leagues:{'0':{league:[{league_key:'449.l.12345', league_id, name, num_teams, scoring_type, current_week, start_week, end_week, is_finished}]}, count}}]}}}}]}}} — SHAPE FROM VENDOR DOCS. league_key is what every league tool below needs.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: NFL leagues {"gameKeys": "nfl"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: gameKeys (required), format.
yahoo_my_teamsARead-onlyIdempotent
The authenticated user's own fantasy teams — where you get team_key, which every write needs.
Returns: {fantasy_content:{users:{'0':{user:[{guid}, {games:{'0':{game:[{game_key}, {teams:{'0':{team:[[{team_key:'449.l.12345.t.3'}, {team_id}, {name}, …]]}, count}}]}}}}]}}} — SHAPE FROM VENDOR DOCS. NOTE the team is a NESTED array-of-arrays of single-key objects, which is the most awkward shape in this API.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: The user's NFL teams {"gameKeys": "nfl"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: gameKeys (required), format.
yahoo_player_ownershipARead-onlyIdempotent
Ownership and roster status for players in a league — percent owned and whether they are rostered, on waivers or free.
Returns: {fantasy_content:{league:[{league_key}, {players:{'0':{player:[[{player_key}, {name}], {ownership:{ownership_type:'team'|'waivers'|'freeagents', owner_team_key, waiver_date}}, {percent_owned:{value}}]}, count}}]}} — SHAPE FROM VENDOR DOCS. ownership_type is the difference between 'add them now' and 'you must outbid someone'.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Is this player available? {"leagueKey": "449.l.12345", "playerKeys": "449.p.31883"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: leagueKey (required), playerKeys (required), format.
yahoo_player_statsARead-onlyIdempotent
One or more players' stats for a season or week.
Returns: {fantasy_content:{players:{'0':{player:[[{player_key}, {name}, {editorial_team_abbr}, {display_position}], {player_stats:{coverage_type, season, stats:[{stat:{stat_id, value}}]}}, {player_points:{total}}]}, count}}} — SHAPE FROM VENDOR DOCS. Batching keys is how you stay inside the rate limit.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A player's season {"playerKeys": "449.p.31883", "type": "season"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: playerKeys (required), type, format.
yahoo_teamARead-onlyIdempotent
One team's metadata: name, manager, waiver priority, FAAB balance, moves used.
Returns: {fantasy_content:{team:[[{team_key}, {team_id}, {name}, {waiver_priority}, {faab_balance}, {number_of_moves}, {number_of_trades}, {roster_adds:{coverage_type, value}}, {managers:[…]}]]}} — SHAPE FROM VENDOR DOCS. roster_adds is how many moves have been used against any weekly cap.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: One team {"teamKey": "449.l.12345.t.3"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: teamKey (required), format.
yahoo_team_matchupsARead-onlyIdempotent
A team's whole season of matchups — opponents, results and weekly scores.
Returns: {fantasy_content:{team:[[{team_key}, …], {matchups:{'0':{matchup:{week, week_start, week_end, status, is_playoffs, winner_team_key, teams:{…}}}, count}}]}} — SHAPE FROM VENDOR DOCS.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: A team's season {"teamKey": "449.l.12345.t.3"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: teamKey (required), format.
yahoo_team_rosterARead-onlyIdempotent
A team's roster for a week — who is started, benched, and in which slot. The read that precedes every lineup write.
Returns: {fantasy_content:{team:[[{team_key}, …], {roster:{'0':{players:{'0':{player:[[{player_key}, {name}, {eligible_positions:[{position}]}, {status}], {selected_position:[{coverage_type:'week'}, {position:'QB'|'BN'|'IR'}]}]}, count}}, coverage_type, week, is_editable}}]}} — SHAPE FROM VENDOR DOCS. selected_position.position is the CURRENT slot and eligible_positions the legal ones; is_editable false means the week is locked and a write will fail.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: This week's roster {"teamKey": "449.l.12345.t.3", "week": 1}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: week (required), teamKey (required), format.
yahoo_team_statsARead-onlyIdempotent
A team's aggregated stats for a season or a week.
Returns: {fantasy_content:{team:[[{team_key}, …], {team_stats:{coverage_type, season, stats:[{stat:{stat_id, value}}]}}, {team_points:{total}}]}} — SHAPE FROM VENDOR DOCS. stat_id resolves via yahoo_game_stat_categories.
NOTE: this shape is from the vendor's documentation and has NOT been verified against a live response (we hold no key for this provider). Treat it as approximate — inspect the actual payload before relying on a field name.
Example: Season totals {"teamKey": "449.l.12345.t.3", "type": "season"}
Auth: needs your own key in YAHOO_CLIENT_ID or YAHOO_CLIENT_SECRET or YAHOO_REFRESH_TOKEN.
Inputs: teamKey (required), type, format.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 844 tools
With 844 tools across dozens of providers, many tools target the same resource+action (e.g. racecard, odds, scores) from different vendors. Descriptions differentiate by provider, but the sheer overlap makes misselection highly likely without external discovery tools like list_tools_by_capability.
Nearly all tools follow a provider-prefixed snake_case pattern (e.g. afl_season_get, betr_race), with only a handful of unprefixed administrative tools (list_resources, sportsdata_feedback). Minor inconsistencies like espnfantasy_ lacking an underscore exist but are internally consistent.
844 tools is an extreme mismatch for any single server; the surface is vastly over-scoped and impossible for an agent to navigate efficiently. This alone overwhelms the set and is the primary coherence failure.
The server covers a huge breadth of sports data, odds, fantasy, and racing across many providers, with escape-hatch call tools for deeper operations. While some vendor shapes are unverified and niche gaps may exist, the surface is close to exhaustive for its stated purpose.
Maintenance
Related MCP Connectors
The Odds API MCP — sportsbook odds across 70+ books, 30+ leagues
Sports Game Odds MCP — wraps the Sports Game Odds API (sportsgameodds.com)
BetsAPI MCP — wraps BetsAPI (betsapi.com) sports events + odds.
Hosted MCP for live Pinnacle odds, drops, fair prices and closing lines.
Related MCP Servers
- AlicenseBqualityDmaintenanceMCP-compatible server that gives AI agents access to alternative sports data across 30+ leagues — odds, events, probabilities, settlement, and futures for prediction markets, DFS platforms, and sportsbooks.2929 npmMIT
- AlicenseBqualityBmaintenanceA unified MCP server that aggregates 32 sports API providers into a single service, providing 336 tools for scores, stats, odds, esports, and more across 70+ sports.1416595 npm40MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects Claude Desktop to The Odds API, giving Claude real-time access to sports odds, scores, and schedules across 80+ sports and leagues worldwide.-
- AlicenseNot gradedqualityCmaintenanceProps-first sports odds API with a hosted MCP server. Live odds and player props (moneyline, spreads, totals) across US sportsbooks, normalized to JSON. Tools: get_odds, get_props, get_events, get_books. API-key auth, free tier.MIT No Attribution