Skip to main content
Glama
sportsdata-mcp

sportsdata-mcp

sportsdata-mcp

CI Release PyPI PyPI downloads License: MIT sportsdata-mcp MCP server Support on Ko-fi

Add to Cursor

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-groups shows 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 coverage

It 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.

Sports board

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

Racing board

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-mcp

Prebuilt 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 toolchain

Related 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 reverts

Provider 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 serve

See 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):

  1. --config <path> flag

  2. $SPORTSDATA_MCP_CONFIG

  3. ./sportsdata-mcp.yaml

  4. ~/.config/sportsdata-mcp/config.yaml

  5. built-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 prod

A 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

SPORTSDATA_MCP_GROUPS

Group selector; overrides enabled_groups. Accepts presets (free, au-books, racing, arb, fantasy, chess, official-stats, aus, odds, motorsport, all), a provider id (espn) or glob (espn.*), literal groups, and exclusions (*,-twitter). Run list-groups to see every preset with its tool count.

SPORTSDATA_MCP_CONFIG

Path to a config file (see resolution order above).

SPORTSDATA_MCP_MAX_BYTES

Global response-size cap in bytes for every provider that doesn't set its own max_response_bytes. 0 (the default) means no cap.

SPORTSDATA_MCP_CACHE_TTL

Seconds to cache identical GET responses (default 60, 0 disables). Absorbs the duplicate calls a model makes while reasoning, without staling live prices. Per provider: providers.<id>.cache_ttl_seconds.

SPORTSDATA_MCP_HTTP / SPORTSDATA_MCP_HOST / SPORTSDATA_MCP_PORT

Serve over HTTP instead of stdio (same as serve --http --host --port). Binds 127.0.0.1 by default — the endpoint is unauthenticated, so anything wider exposes every enabled tool and any provider credential in the process to that network.

SPORTSDATA_LICENSE

Dormant — the product is free; nothing requires a licence. The signed-entitlement machinery remains for anyone self-hosting gated premium feeds (see below).

SPORTSDATA_ENTITLEMENT_URL / SPORTSDATA_ENTITLEMENT_PUBKEY

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

afl.public.core

22

Competitions, seasons, rounds, fixtures, ladders, match stats

afl.public.broadcasting

9

Broadcast regions, guides, providers

afl.public.content

8

News/articles, videos, photos

afl.premium.cfs

1

CFS premium ops — needs the anonymous x-media-mis-token

afl.premium.statspro

1

StatsPro ops — needs the x-media-mis-token

afl.premium.keyserver

1

HLS video URL signing

Sportsbet — sportsbet.com.au

Group

Tools

Notes

sportsbet.racing

15

Race meetings, racecards, results, futures, SRMs

sportsbet.sports

14

Sport events, markets, prices, SGMs

sportsbet.cross

12

Live status, commentary, ladders, promos, video

sportsbet.results

2

Resulted events by date

sportsbet.graphql

1

Persisted GraphQL gateway (apigw/sportsbook/graph)

Entain / Ladbrokes — ladbrokes.com.au

Group

Tools

Notes

entain.rest

13

Navigation quick-links and REST surfaces

entain.graphql

1

127 persisted GraphQL ops (gql/router)

entain.cdn

1

Contentful CMS entries (promotions, major-event nav)

PointsBet — pointsbet.com.au

Group

Tools

Notes

pointsbet.sports

10

Sports catalogue, competition/event feeds, full event markets, in-play, search

pointsbet.racing

11

Meetings, racecards, results, futures, SRMs, tips, form

pointsbet.content

3

Promotions, promo-code splash, + pointsbet_content_call over the static CMS/nav assets

TAB — tab.com.au

Group

Tools

Notes

tab.racing

9

Dates, meetings, racecards (fixed + parimutuel), form, next-to-go, jackpots, futures

tab.sports

9

Sports/competitions tree, full match markets + SGM, focused match markets, next-to-go, results, multi-builder

tab.discovery

4

Featured/live recommendations + tab_cms_call over the CMS content feeds

Unibet — unibet.com.au

Group

Tools

Notes

unibet.racing

1

unibet_racing_call — persisted-GraphQL: meetings, race cards, form, futures, specials

unibet.sport

3

unibet_kambi_call over the Kambi offering API (groups, events, bet offers, in-play, bet-builder) + live stats + odds ladder

BetR — betr.com.au (BlueBet platform)

Group

Tools

Notes

betr.racing

8

Next-to-jump, today's/grouped racecards, race card, form, fluctuations, movers

betr.sport

7

Event types, competition categories, event markets, match detail, popular SGMs

betr.content

4

Promotions + featured racing + popular market links

Pinnacle — pinnacle.com (sharp odds)

Group

Tools

Notes

pinnacle.sports

13

Sports/leagues, full + highlighted + live + per-league matchups, carousel, matchup detail, straight + parlay markets (American-odds prices)

pinnacle.reference

4

Enums, market-label dictionary, teaser definitions, API status

Betfair Exchange — betfair.com.au (exchange odds)

Group

Tools

Notes

betfair.exchange

3

bymarket + byevent back/lay price feeds (the sharpest odds) + cash-out availability

betfair.navigation

1

bynode catalogue graph (sport → meeting → event → market)

betfair.inplay

5

Live scores, event details, timeline (single + batch), scores+broadcast

Dabble — dabble.com.au (iOS app backend)

Group

Tools

Notes

dabble.sport

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

supercoach.fantasy

6

One uniform surface across all 7 games (afl/nrl/epl/nba/nbl/nfl/bbl) × 2 modes (classic + draft): competition state, the full per-player feed (price + ppts1 projection + ownership + matchup; draft adds predraft_rank), fixtures (with H2H odds), club + single-player catalogues, leagues

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

nbl.basketball

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

wta.tennis

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

racingandsports.racing

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

puntersedge.demo

3

No key — next-to-go racing, best odds + arb flag, one book's prices for one sport

puntersedge.racing

7

Every book's price per race, best win/place/tote per runner, the card, results, movers, venues, closing-line archive

puntersedge.sport

3

Sports catalogue, per-book prices by sport_key, best price per selection + arb flag

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

datagolf.general

3

Player list, tour schedule, current event field

datagolf.predictions

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

datagolf.betting

3

Outright + matchup + all-pairings odds across ~13 books (incl. model line)

datagolf.historical

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

fanduel.racing

4

fanduel_racing_call (full-query GraphQL: featured/today races + odds, single-race card, tracks, pools, talent picks) + messages/quick-links/promotions

fanduel.sportsbook

2

fanduel_sb_call (REST: event pages + markets, in-play, promos, configs via the _ak key) + live scores

NRL — mc.championdata.com

Group

Tools

Notes

nrl.public.core

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

nba.public.cdn

5

Open CDN JSON: today's scoreboard, full schedule, live box score + play-by-play, odds

nba.stats

2

nba_daily_lineups + nba_stats_call, the dispatcher over the 138-endpoint /stats/ API

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

espn.scores

5

Site API convenience endpoints: scoreboard, teams, standings, game summary, news

espn.site

1

espn_site_call — team detail, rosters, schedules, injuries, depth charts, transactions, history, athlete news, groups, rankings (10 ops)

espn.core

1

espn_core_call — the canonical $ref-linked model: events/competitions, odds, win-probability, plays, venues, drafts, coaches, calendar, transactions (37 ops)

espn.web

1

espn_web_call — site-wide search + common/v3 athlete views (7 ops)

espn.cdn

1

espn_cdn_call — the CDN live core feed: scoreboard/game/boxscore/playbyplay (4 ops)

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

opendota.reference

4

Heroes, hero meta by skill bracket, pro teams, leagues

opendota.matches

3

Pro matches, full match detail, public ladder matches

opendota.players

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

openligadb.football

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

euroleague.basketball

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

ncaa.college

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

fpl.players

2

Every player with price, form, ownership, xG/xA; one player in full depth

fpl.reference

3

Clubs with strength ratings, all 38 gameweeks with deadlines, scoring rules

fpl.fixtures

5

Fixtures with difficulty 1-5, live per-player scoring, dream team, set-piece takers

fpl.managers

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

ufc.events

3

Events with per-segment card times and venue, full fight cards, bouts back to UFC 1

ufc.athletes

2

Fighter search and profiles with statistics attached

ufc.stats

2

The FightMetric career statistics table and divisional rankings

ufc.records

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

footballdatauk.history

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

motogp.racing

6

MotoGP/Moto2/Moto3/MotoE back to 1949: events, sessions with track conditions, classifications, championships

formulae.racing

5

Formula E from 2014-15: calendar, driver and team championships with per-race points

nascar.racing

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

jolpicaf1.reference

4

Seasons, drivers, constructors, circuits

jolpicaf1.schedule

1

Race calendars with per-session times

jolpicaf1.results

5

Race, qualifying and sprint results, lap timings, pit stops

jolpicaf1.standings

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

lichess.chess

6

Per-time-control ratings, leaderboards, user status, daily puzzle, arenas

chesscom.chess

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

squiggle.afl

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

nhl.reference

3

Seasons, club rosters by position group, player bio/draft/career

nhl.schedule

2

League schedule by week, and a club's full season game log

nhl.game

3

Live scoreboard, box scores with per-player ice time, scoring summaries

nhl.stats

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

sleeper.reference

3

Season/week state, username → user id, platform-wide trending adds/drops

sleeper.league

8

Settings, rosters, managers, weekly matchups, transactions, playoff bracket, traded picks

sleeper.draft

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

espnfantasy.reference

6

Games catalogue (resolves the current season + week), season status, pro teams + bye weeks, player universe, scoring presets, player news

espnfantasy.league

14

Settings, teams, rosters, standings, matchups, draft board, transactions, message board, league history, plus the undocumented allon mega-view

espnfantasy.scoring

5

Box scores (lineups with actual and projected points), matchup scores, scoreboard, live scoring, positional ratings

espnfantasy.players

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

openf1.reference

3

Grand Prix weekends (meetings), sessions (the fixtures feed), driver roster

openf1.results

5

Session classification, starting grid, drivers'/constructors' championship standings, overtakes

openf1.timing

5

Per-lap sector + speed-trap timing, pit stops, tyre stints, live gaps/intervals, track position

openf1.telemetry

2

Car telemetry (speed/throttle/brake/gear/RPM/DRS) + (x,y,z) location at ~3.7 Hz

openf1.live

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

cricketaustralia.core

7

Fixtures (the /matches feed), competitions, tours/series, teams, player profiles (batch), venue lookup, competition ladder

cricketaustralia.match

3

Full scorecard (innings batting/bowling/wickets), run-graph series, live video streams

cricketaustralia.content

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

mlb.reference

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)

mlb.schedule

5

Games by date / range / team, plus postseason (schedule, series, tune-in) and tied games

mlb.game

10

Boxscore, linescore, play-by-play, v1.1 feed/live firehose, win-probability, context metrics, content, per-player game line, changes, uniforms

mlb.stats

9

Standings, season stats, one-player stats, league + team leaders, team-season stats, game pace, high/low records

mlb.extra

15

Draft (+ prospects), awards (catalogue + recipients), attendance, transactions, free agents, jobs (umpires/datacasters/scorers), Home Run Derby, All-Star ballots

mlb.meta

1

mlb_meta — the /{type} lookup for every enum (positions, statTypes, gameTypes, pitchCodes, …)

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

premierleague.core

7

Competitions, season structure, awards, the league table, current gameweek, geo

premierleague.teams

10

Teams (+ batch), squads, form (single + all-teams), team stats, next fixture, club metadata

premierleague.matches

8

Fixtures/results feed + match centre: detail, events, lineups, team stats (~200 Opta metrics), officials, commentary

premierleague.players

8

Player directory, profiles (basic/career/season), batch lookup, season + competition stats, metadata

premierleague.stats

2

Player + team stat leaderboards (sort by any Opta metric)

premierleague.content

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

laliga.core

6

Competitions, season instances (subscriptions), league table, rounds/matchweeks

laliga.teams

3

Season team list, single team, club squad

laliga.players

3

Every-player season stats (≈749, full Opta metrics), player profile + stats

laliga.matches

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

seriea.core

3

All competitions, the 41-season catalogue, single-season detail

seriea.season

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

kalshi.markets

6

Market catalogue + detail, order book, public trades, OHLC candlesticks (single + batch)

kalshi.events

9

Events, series catalogue (by category), single series, milestones, MVE combo collections, entity registry

kalshi.exchange

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

polymarket.gamma

9

Markets/events/series/sports/tags catalogue + site search (the discovery plane)

polymarket.clob

6

Order book, best price, midpoint, spread, price history, CLOB catalogue

polymarket.data

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

twitter.tweets

7

7-day search, volume counts, post lookup (batch + single), quote/repost/like engagement

twitter.users

6

Profile lookup (handle/id, batch), user timelines, mentions

twitter.trends

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

apisports

API_SPORTS_KEY

20

Ten sports on one key — and the only rugby-union coverage here

theoddsapi

THE_ODDS_API_KEY

6

Odds from ~40 international books, with historical snapshots for CLV work

oddsapiio

ODDS_API_IO_KEY

5

274 bookmakers across 34 sports, down to padel, bandy and gaelic football

sportsgameodds

SPORTSGAMEODDS_API_KEY

7

Player props with stable market ids you can join across books and time

sportsdataio

SPORTSDATAIO_*_KEY

9

DFS salaries and projections (DraftKings/FanDuel), which no official feed publishes

sportmonks

SPORTMONKS_TOKEN

8

Football lineups, events and per-player stats on a genuinely free tier

cfbd

CFBD_API_KEY

10

College-football analytics: SP+, Elo, advanced box scores, historical lines

footballdataorg

FOOTBALL_DATA_ORG_KEY

10

European competitions with no official feed here — UCL, Eredivisie, Championship

balldontlie

BALLDONTLIE_API_KEY

10

One consistent shape across NBA, NFL, MLB and EPL

pandascore

PANDASCORE_TOKEN

8

Esports beyond Dota 2 — CS2, LoL, Valorant, R6

apitennis

API_TENNIS_KEY

7

ATP and ITF draws, H2H and rankings (wta is women's-tour only)

cricketdata

CRICKETDATA_API_KEY

8

International and franchise cricket (cricketaustralia is AU-only)

highlightly

HIGHLIGHTLY_API_KEY

7

Highlight video across five sports — the only video surface here that isn't single-league

mysportsfeeds

MYSPORTSFEEDS_API_KEY

5

US majors on a free non-commercial tier, with clean per-game player logs

isportsapi

ISPORTS_API_KEY

5

Asian-handicap odds across Asian books

entitysport

ENTITYSPORT_TOKEN

5

Cricket ball-by-ball commentary (deeper than cricketdata)

golfcourseapi

GOLFCOURSE_API_KEY

2

30k+ golf courses with per-hole par, yardage and stroke index

firecrawl_alexandria

FIRECRAWL_API_KEY

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 stats

Per-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/collector

Tool 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-payload

prints 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:

  1. list_tools_by_capability("sport.event_markets") → every enabled tool exposing it

  2. Call each provider's tool concurrently with the resolved event ids

  3. 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 via sportsbet_graphql_call (browse sportsbet://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 with sportsdata-mcp refresh-hashes entain.

  • AFL — afl.public.* is anonymous. afl.premium.* mints an anonymous x-media-mis-token automatically; 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 a competitionId from nrl_competitions (e.g. 12999 = 2026 NRL Premiership), a matchId from nrl_fixture, then pull per-player match stats from nrl_match; decode stat codes via nrl://stats/definitions.

  • NBA — two surfaces, no secrets. cdn.nba.com is wide open (it even serves JSON as text/plain, which the client accepts). stats.nba.com sits behind Akamai, which black-holes any request missing a full browser header bundle — the spec ships that bundle in provider.default_headers, so it just works. Akamai also rate-limits hard, so the spec's defaults block throttles NBA to ~1 req/2.5 s, sets a 45 s timeout, and retries transient 429/5xx with exponential backoff (all overridable via providers.nba.*). The /stats/ family is one dispatcher (nba_stats_call): pick an operation (the path segment, e.g. leaguedashplayerstats) and pass query_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) and cdn.espn.com (the live core feed, needs ?xhr=1). Nearly every URL is .../sports/{sport}/{league}/{resource}, so the tools take sport + league as 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) → an event id → espn_game_summary or the deep espn_core_call(event_*) ops. The spec throttles to ~5 req/s and retries transient 429/5xx (overridable via providers.espn.*). Note the core API path uses leagues/{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.com serves the sportsbook (sports + racing); pointsbet.com.au serves static CMS/nav assets via the pointsbet_content_call dispatcher. Sports discovery: pointsbet_sport_competitions(sportKey) → a competition key → pointsbet_event(eventKey) for the full market book. Racing: pointsbet_racing_meetings(startDate, endDate) → a raceId → pointsbet_racing_race. Many feeds return a top-level JSON array.

  • TAB (Tabcorp) — anonymous public data, no secrets. api.beta.tab.com.au sits behind Akamai (the spec ships a browser header bundle + ~2.5 rps throttle, like NBA); cmsapi.tab.com.au serves CMS feeds via tab_cms_call. Every endpoint needs a jurisdiction (defaults to NSW). 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_match for the full market book.

  • Unibet — anonymous AU data, no secrets, two surfaces. Racing is persisted-GraphQL (unibet_racing_call, the graphql_persisted dispatcher) at rsa.unibet.com.au — race ids are eventKeys like 202606040200.T.AUS.hawkesbury.1; the endpoint enforces Apollo CSRF so a Content-Type: application/json header is sent. Sport is the Kambi offering API (unibet_kambi_call over *.kambicdn.com, market AU): group tree, events, bet offers, in-play, bet-builder. Browse ops in unibet://{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). The betr.com.au Next.js _next/data/{buildHash} blobs are skipped (fragile per-deploy hash; the API serves the same data).

  • Racing and Sports — www.racingandsports.com.au racing/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, and GetOdds needs a per-race token, so only the JSON feeds are modelled.

  • Betfair Exchange — anonymous, the open read-only web APIs keyed by the public _ak query param. The crown jewel is betfair_market_prices (ero …/bymarket) — exchange back/lay prices, the sharpest reference odds. Discover market ids by walking betfair_navigation (scan …/bynode, e.g. EVENT_TYPE:7 = Horse Racing) down to MARKET nodes; live scores/details come from the ips in-play service. string_csv id params take a list. (The apieds racing widgets are Cloudflare-gated from datacenter IPs and the appsync GraphQL 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-client X-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_call POSTs the literal query text (the graphql_query dispatcher kind, sibling to the persisted-hash graphql_persisted), with boilerplate variables (brand/product/device/profile) baked as per-op default_variables — most calls need none, override only what varies ({results: 12}, {trackCode, raceNumber}). Sportsbook is REST (fanduel_sb_call) keyed by the static public _ak web key, region NJ. The two halves need different Origin headers, so the sportsbook dispatcher overrides Origin + x-sportsbook-region over the racing-origin provider default. Browse ops in fanduel://{racing,sportsbook}/operations. (US data — composes with other US sources via capability tags.)

CLI reference

Command

Purpose

serve

Start the MCP stdio server (default when no subcommand)

list-groups

Print every group with tool count + description

lint

Validate specs against the schema + capability catalogue (nonzero on failure)

coverage

What works from your location: reachable providers, what your region blocks, what needs a key

doctor

Per-provider reachability + auth + REST-contract probe (nonzero on failure)

refresh-hashes <provider>

Refresh persisted-query hashes from the live front-end bundle (--dry-run to preview)

version

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:

  1. Write src/sportsdata_mcp/specs/<provider>.yaml (copy an existing spec).

  2. 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).

  3. sportsdata-mcp lint — must pass.

  4. sportsdata-mcp doctor (with the new groups enabled) — probes it live.

  5. pytest -m "not live" — offline suite; drop the marker filter to run live tests.

  6. Add a row to tests/contract/test_api_contracts.py so 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 missing DATAGOLF_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 tools
afl_broadcast_channelsA
Read-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_listA
Read-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_getA
Read-onlyIdempotent

Get a single broadcast event by id.

Returns: {id, name, startDateTime, channels:[...], contentReference}

Auth: none needed.

Inputs: eventId (required).

afl_broadcast_eventsB
Read-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_eventsB
Read-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_getA
Read-onlyIdempotent

Get a single broadcast region by id.

Returns: {id, name, timezone}

Auth: none needed.

Inputs: regionId (required).

afl_broadcast_regionsA
Read-onlyIdempotent

List broadcast regions (26) with timezones.

Returns: {pageInfo, content:[{id, name, timezone}]}

Auth: none needed.

Inputs: page, pageSize.

afl_cfs_callA
Read-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_getA
Read-onlyIdempotent

Get a single club by id.

Returns: {clubs:[{id, providerId, name}]}

Auth: none needed.

Inputs: clubId (required).

afl_clubs_listA
Read-onlyIdempotent

List AFL/AFLW clubs (32).

Returns: {clubs:[{id, providerId, name, abbreviation, nickname}]}

Auth: none needed.

Inputs: page, pageSize.

afl_competition_compseasonsA
Read-onlyIdempotent

List comp seasons within one competition.

Returns: {meta, compSeasons:[...]}

Auth: none needed.

Inputs: competitionId (required), pageSize.

afl_competition_getA
Read-onlyIdempotent

Get a single competition by integer id.

Returns: {meta, competitions:[{id, providerId, code, name}]}

Auth: none needed.

Inputs: competitionId (required).

afl_competitions_listA
Read-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_getA
Read-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_listA
Read-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_getA
Read-onlyIdempotent

Get a single photo content item by id.

Returns: {id, type:'photo', title}

Auth: none needed.

Inputs: id (required).

afl_content_photo_listA
Read-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_getA
Read-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_listA
Read-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_getA
Read-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_listA
Read-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_getA
Read-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_listA
Read-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_signingA
Read-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_getA
Read-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_audioA
Read-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_videoA
Read-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_idmapA
Read-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_listA
Read-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_getA
Read-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_getA
Read-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_idmapA
Read-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_listA
Read-onlyIdempotent

List players (17k+ all-time catalogue).

Returns: {players:[{id, providerId, firstName, surname, dateOfBirth, draftYear, heightInCm}]}

Auth: none needed.

Inputs: page, pageSize.

afl_rounds_listA
Read-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_getA
Read-onlyIdempotent

Get a single calendar-year season by id.

Returns: {meta, seasons:[{id, year}]}

Auth: none needed.

Inputs: seasonId (required).

afl_seasons_listB
Read-onlyIdempotent

List calendar-year season records.

Returns: {meta, seasons:[{id, year}]}

Auth: none needed.

Inputs: page, pageSize.

afl_statspro_callA
Read-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_getA
Read-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_idmapA
Read-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_listA
Read-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_getA
Read-onlyIdempotent

Get a single venue by id.

Returns: {venues:[{id, providerId, name, location, state, timezone}]}

Auth: none needed.

Inputs: venueId (required).

afl_venues_listA
Read-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_gamesA
Read-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_gamesA
Read-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_standingsA
Read-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_fixturesA
Read-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_statisticsA
Read-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_h2hA
Read-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_leaguesA
Read-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_oddsA
Read-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_playersA
Read-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_predictionsA
Read-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_standingsA
Read-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_teamsA
Read-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_racesA
Read-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_gamesA
Read-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_gamesA
Read-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_fightsA
Read-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_gamesA
Read-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_gamesA
Read-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_statusA
Read-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_gamesA
Read-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_eventsA
Read-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_fixturesA
Read-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_h2hA
Read-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_livescoreA
Read-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_playersA
Read-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_standingsA
Read-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_tournamentsA
Read-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_gamesA
Read-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_teamsA
Read-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_gamesA
Read-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_gamesA
Read-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_playersA
Read-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_averagesA
Read-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_standingsA
Read-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_statsA
Read-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_teamsA
Read-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_gamesA
Read-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_cashoutB
Read-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_detailsB
Read-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_timelineA
Read-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_timelinesA
Read-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_pricesB
Read-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_eventA
Read-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_navigationA
Read-onlyIdempotent

Navigation graph by node — traverse sport → group → event → market. Feed market ids into betfair_market_prices.

Returns: {nodes:[{nodeId, name, nodeType: EVENT_TYPE|MENU|EVENT|MARKET, navInfo, ...}]}

Example: Top of the Horse Racing tree {"nodeIds": "EVENT_TYPE:7"}

Auth: none needed.

Inputs: nodeIds (required), _ak, alt, locale, +5 more.

betfair_scoresA
Read-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_broadcastA
Read-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_promotionsA
Read-onlyIdempotent

All visible promotions (name, description, dates).

Returns: {Promotions:[{Id, PromotionId, Name, Description, PromotionStartDate}]}

Auth: none needed.

Inputs: no named parameters.

betr_event_typesA
Read-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_fav4A
Read-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_grouped_racecardA
Read-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_moversA
Read-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_categoryA
Read-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_eventA
Read-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_racesA
Read-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_dataA
Read-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_categoryA
Read-onlyIdempotent

Categories that currently have Popular Same Game Multis.

Returns: {PopSGMCategoryItems:[{EventTypeId, MasterCategoryName, CategoryId, CategoryName}]}

Auth: none needed.

Inputs: no named parameters.

betr_promotionsA
Read-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_raceA
Read-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_flucsA
Read-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_formA
Read-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_priceA
Read-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_categoryA
Read-onlyIdempotent

Events + markets for one sport category (competition).

Returns: {EventTypeDesc, EventTypeId, MasterCategories:[{Categories:[{CategoryId, CategoryName, Events:[...]}]}]}

Auth: none needed.

Inputs: CategoryId (required).

betr_statwars_eventsA
Read-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_racesA
Read-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_scoreA
Read-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_linesA
Read-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_gamesA
Read-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_portalA
Read-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_rankingsA
Read-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_eloA
Read-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_spA
Read-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_recruitingA
Read-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_teamsA
Read-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_statsA
Read-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_archivesA
Read-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_clubA
Read-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_leaderboardsA
Read-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_gamesA
Read-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_playerA
Read-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_statsA
Read-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_playersA
Read-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_competitionsA
Read-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_contentA
Read-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_fixturesA
Read-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_playersA
Read-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_playlistA
Read-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_graphA
Read-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_scorecardA
Read-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_standingsA
Read-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_streamsA
Read-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_teamsA
Read-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_toursA
Read-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_venueA
Read-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_matchesA
Read-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_matchesA
Read-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_infoA
Read-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_infoA
Read-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_playersA
Read-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_scorecardA
Read-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_seriesA
Read-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_infoA
Read-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_competitionsA
Read-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_fixturesA
Read-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_competitionsA
Read-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_detailsA
Read-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_sportsA
Read-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_skillA
Read-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_projectionsA
Read-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_updatesA
Read-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_listA
Read-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_pointsA
Read-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_listA
Read-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_matchupsA
Read-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_listA
Read-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_outrightsA
Read-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_resultsA
Read-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_listA
Read-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_roundsA
Read-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_playA
Read-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_statsA
Read-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_gainedA
Read-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_statsA
Read-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_matchupsB
Read-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_pairingsA
Read-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_outrightsA
Read-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_decompositionsA
Read-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_listA
Read-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_tournamentC
Read-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_archiveC
Read-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_rankingsA
Read-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_scheduleA
Read-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_ratingsA
Read-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_entriesA
Read-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_rulesA
Read-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_mapsA
Read-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_groupsA
Read-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_graphql_callA
Read-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_urlA
Read-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_racing_future_marketsA
Read-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_meetingA
Read-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_racesA
Read-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_racecardA
Read-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_sgm_priceA
Read-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_cardA
Read-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_requestA
Read-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_channelsA
Read-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_competitionsB
Read-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_commentaryA
Read-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_matchesA
Read-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_infoA
Read-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_scorecardA
Read-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_callA
Read-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_callA
Read-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_boxscoreA
Read-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_communicationA
Read-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_draftA
Read-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_everythingA
Read-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_gamesA
Read-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_leagueA
Read-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_defaultsA
Read-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_historyA
Read-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_settingsA
Read-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_scoringA
Read-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_matchupsA
Read-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_scoreA
Read-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_navA
Read-onlyIdempotent

Lightweight nav payload — league name, size and the current user's team, for cheap orientation before a heavy call.

Returns: {id, settings:{name, size}, status:{…}, teams:[{id, abbrev}], members:[…]}

Example: Cheap league header {"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_pending_transactionsA
Read-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_cardA
Read-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_infoA
Read-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_newsA
Read-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_playersA
Read-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_ratingsA
Read-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_teamsA
Read-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_rostersA
Read-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_scoreboardA
Read-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_seasonA
Read-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_standingsA
Read-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_statusA
Read-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_teamsA
Read-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_transactionsA
Read-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_summaryA
Read-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_newsA
Read-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_scoreboardA
Read-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_callA
Read-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_standingsA
Read-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_teamsA
Read-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_callA
Read-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_clubsA
Read-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_gameA
Read-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_gamesA
Read-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_statsA
Read-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_peopleA
Read-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_roundsA
Read-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_seasonsA
Read-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_callA
Read-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_messagesA
Read-onlyIdempotent

Site message strings (disclaimers, informational copy) for a namespace.

Returns: {response:{:{: }}}

Auth: none needed.

Inputs: brand, device, product, namespace.

fanduel_racing_promotionsA
Read-onlyIdempotent

Structured racing promotions / placements (POST; empty body returns all).

Returns: {success, promoPlacements:[{...}]}

Auth: none needed.

Inputs: body.

fanduel_sb_callA
Read-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_scoreA
Read-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_priceA
Read-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_areasB
Read-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_competitionA
Read-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_matchesA
Read-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_competitionsA
Read-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_matchA
Read-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_matchesA
Read-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_scorersA
Read-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_standingsA
Read-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_teamA
Read-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_teamsA
Read-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_seasonA
Read-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_championshipsA
Read-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_standingsA
Read-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_raceA
Read-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_racesA
Read-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_standingsA
Read-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_leagueA
Read-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_teamA
Read-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_statusA
Read-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_fixturesA
Read-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_rulesA
Read-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_gameweeksA
Read-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_leagueA
Read-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_gameweekA
Read-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_managerA
Read-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_historyA
Read-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_picksA
Read-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_teamA
Read-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_detailA
Read-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_playersA
Read-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_notesA
Read-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_teamsA
Read-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_courseA
Read-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).

highlightly_baseball_highlightsA
Read-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_highlightsA
Read-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_highlightsA
Read-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_highlightsA
Read-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_highlightsA
Read-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_leaguesC
Read-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_matchesA
Read-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_scheduleA
Read-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_competitionsA
Read-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_liveA
Read-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_asianA
Read-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_scheduleA
Read-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_circuitsB
Read-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_constructorsB
Read-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_standingsA
Read-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_driversA
Read-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_standingsA
Read-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_lapsA
Read-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_pitstopsA
Read-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_qualifyingA
Read-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_racesA
Read-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_resultsA
Read-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_seasonsA
Read-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_sprintA
Read-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_candlesticksA
Read-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_batchA
Read-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_eventA
Read-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_eventsA
Read-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_announcementsA
Read-onlyIdempotent

Active exchange-wide announcements.

Returns: {announcements:[{type, message, delivery_time, status}]}

Auth: none needed.

Inputs: no named parameters.

kalshi_exchange_scheduleA
Read-onlyIdempotent

Standard trading hours + maintenance windows.

Returns: {schedule:{standard_hours, maintenance_windows}}

Auth: none needed.

Inputs: no named parameters.

kalshi_exchange_statusA
Read-onlyIdempotent

Is the exchange up and trading right now.

Returns: {exchange_active, trading_active}

Auth: none needed.

Inputs: no named parameters.

kalshi_marketA
Read-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_marketsA
Read-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_milestonesA
Read-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_collectionA
Read-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_collectionsA
Read-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_orderbookA
Read-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_seriesA
Read-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_listA
Read-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_targetA
Read-onlyIdempotent

One structured target (entity) by id.

Returns: {structured_target:{id, name, type, details, source_ids}}

Auth: none needed.

Inputs: id (required).

kalshi_structured_targetsA
Read-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_tradesA
Read-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_competitionA
Read-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_competitionsA
Read-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_matchA
Read-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_matchesA
Read-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_playerA
Read-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_statsA
Read-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_statsA
Read-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_roundsA
Read-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_squadA
Read-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_standingA
Read-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_subscriptionA
Read-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_subscriptionsA
Read-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_teamA
Read-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_teamsA
Read-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_puzzleA
Read-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_leaderboardA
Read-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_allA
Read-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_tournamentsA
Read-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_userA
Read-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_statusA
Read-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_groupsA
Read-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_resourcesA
Read-onlyIdempotent

List all registered MCP resources (capability map, dispatcher catalogues, reference data).

Inputs: no named parameters. Returns: object

list_tools_by_capabilityA
Read-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_agentsA
Read-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_injuriesB
Read-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_leagueA
Read-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_standingsA
Read-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_scoringA
Read-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_leaguesA
Read-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_scheduleA
Read-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_tradesB
Read-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_playersA
Read-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_scoresA
Read-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_scoresA
Read-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_rostersA
Read-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_scheduleA
Read-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_transactionsA
Read-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_ballotA
Read-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_voteA
Read-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_writeinsA
Read-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_attendanceA
Read-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_awardsA
Read-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_listA
Read-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_boxscoreA
Read-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_conferencesB
Read-onlyIdempotent

Conference catalogue (used by some leagues / amateur levels).

Returns: {conferences:[{id, name, abbreviation, league, hasWildcard}]}

Auth: none needed.

Inputs: season, conferenceId.

mlb_datacastersB
Read-onlyIdempotent

Datacaster (official scorer-adjacent stringer) assignments.

Returns: {roster:[{person, job}]}

Auth: none needed.

Also answers this: pl_match_officials.

Inputs: date, sportId.

mlb_divisionsA
Read-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_draftA
Read-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_prospectsB
Read-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_agentsA
Read-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_changesA
Read-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_contentA
Read-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_metricsA
Read-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_paceA
Read-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_uniformsA
Read-onlyIdempotent

Uniforms worn in one or more games.

Returns: {uniforms:[{gamePk, home:{...}, away:{...}}]}

Auth: none needed.

Inputs: gamePks (required).

mlb_game_win_probabilityA
Read-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_lowA
Read-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_derbyA
Read-onlyIdempotent

Home Run Derby bracket + results for a derby gamePk.

Returns: {info, status, rounds:[{matchups:[{topSeed, bottomSeed, ...}]}]}

Auth: none needed.

Inputs: gamePk (required).

mlb_jobsA
Read-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_leadersB
Read-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_leaguesA
Read-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_linescoreA
Read-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_feedA
Read-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_metaA
Read-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_scorersB
Read-onlyIdempotent

Official scorer assignments.

Returns: {roster:[{person, job}]}

Auth: none needed.

Also answers this: pl_match_officials.

Inputs: date, sportId.

mlb_peopleA
Read-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_changesA
Read-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_playbyplayA
Read-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_playerA
Read-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_statsA
Read-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_statsA
Read-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_scheduleA
Read-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_postseasonA
Read-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_seriesA
Read-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_tuneinA
Read-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_tiedB
Read-onlyIdempotent

Tie-breaker / tied games for a season.

Returns: {totalGames, dates:[{games:[...]}]}

Auth: none needed.

Inputs: season (required), hydrate, gameTypes.

mlb_seasonA
Read-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_seasonsA
Read-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_allA
Read-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_sportsA
Read-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_playersA
Read-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_standingsA
Read-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_statsA
Read-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_teamA
Read-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_alumniA
Read-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_coachesB
Read-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_leadersA
Read-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_personnelB
Read-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_rosterA
Read-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_teamsA
Read-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_affiliatesA
Read-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_historyA
Read-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_statsA
Read-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_statsA
Read-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_uniformsA
Read-onlyIdempotent

Uniform assets / descriptions for one or more teams.

Returns: {uniforms:[{teamId, uniformAssets:[{uniformAssetText, uniformAssetType, ...}]}]}

Auth: none needed.

Inputs: teamIds (required), season.

mlb_transactionsA
Read-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_umpiresA
Read-onlyIdempotent

Current umpire crew list.

Returns: {roster:[{person, jobType, job}]}

Auth: none needed.

Also answers this: pl_match_officials.

Inputs: date, sportId.

mlb_venuesA
Read-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_categoriesA
Read-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_eventsA
Read-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_seasonsA
Read-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_classificationA
Read-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_sessionsA
Read-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_standingsA
Read-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_boxscoreA
Read-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_gamesA
Read-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_injuriesA
Read-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_gamelogsA
Read-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_standingsA
Read-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_listA
Read-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_feedA
Read-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_boxscoreA
Read-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_lineupsA
Read-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_todayA
Read-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_playbyplayA
Read-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_scheduleA
Read-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_todayA
Read-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_callA
Read-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_ladderA
Read-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_boxscoreA
Read-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_outcomesA
Read-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_playbyplayA
Read-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_newsA
Read-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_matchesA
Read-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_boxscoresA
Read-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_playersA
Read-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_statsA
Read-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_scheduleA
Read-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_currentA
Read-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_seasonsA
Read-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_leadersA
Read-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_rosterA
Read-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_teamsA
Read-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_statsA
Read-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_rankingsA
Read-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_scoreboardA
Read-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_standingsA
Read-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_boxscoreA
Read-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_scheduleA
Read-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_landingA
Read-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_leadersA
Read-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_playerA
Read-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_rosterA
Read-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_scheduleA
Read-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_scoresA
Read-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_seasonsA
Read-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_leadersA
Read-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_standingsA
Read-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_settingsA
Read-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_competitionsA
Read-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_fixtureA
Read-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_matchA
Read-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_bookmakersB
Read-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_eventsA
Read-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_leaguesA
Read-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_oddsA
Read-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_sportsA
Read-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_heroesA
Read-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_statsA
Read-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_leaguesA
Read-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_matchA
Read-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_playerA
Read-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_heroesA
Read-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_matchesA
Read-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_winlossA
Read-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_matchesA
Read-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_matchesA
Read-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_teamsA
Read-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_dataA
Read-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_driversA
Read-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_teamsA
Read-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_driversA
Read-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_intervalsA
Read-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_lapsA
Read-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_locationA
Read-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_meetingsA
Read-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_overtakesA
Read-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_pitA
Read-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_positionA
Read-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_controlA
Read-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_resultA
Read-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_sessionsA
Read-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_gridA
Read-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_stintsA
Read-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_radioB
Read-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_weatherA
Read-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_matchdayA
Read-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_leaguesA
Read-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_matchA
Read-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_matchesA
Read-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_matchdaysA
Read-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_matchesA
Read-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_tableA
Read-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_teamsA
Read-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_leaguesA
Read-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_matchesA
Read-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_oddsA
Read-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_playersA
Read-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_seriesA
Read-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_teamsA
Read-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_tournamentsA
Read-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_videogamesA
Read-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_enumsA
Read-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_labelsA
Read-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_matchupsA
Read-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_liveA
Read-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_matchupA
Read-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_marketsA
Read-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_marketsA
Read-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_leaguesA
Read-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_matchupsA
Read-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_allA
Read-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_liveA
Read-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_sportsA
Read-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_liveA
Read-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_statusA
Read-onlyIdempotent

API system status (online/offline + per-service health).

Returns: {code, description, services:[{name, status}]}

Auth: none needed.

Inputs: no named parameters.

pinnacle_teasersA
Read-onlyIdempotent

Teaser bet definitions (point teasers by sport group and team count).

Returns: [{id, description, groupId, groupName, leagues:[{league:{...}}]}] (top-level array)

Auth: none needed.

Inputs: no named parameters.

pl_awardsA
Read-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_eventsA
Read-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_eventsA
Read-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_metadataA
Read-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_competitionA
Read-onlyIdempotent

One competition by id (8 = Premier League).

Returns: {id, code, name}

Auth: none needed.

Inputs: cid (required).

pl_competitionsA
Read-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_contentA
Read-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_itemA
Read-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_countryA
Read-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_gameweekA
Read-onlyIdempotent

The current matchweek number (static config blob).

Returns: {matchweek}

Auth: none needed.

Inputs: no named parameters.

pl_matchA
Read-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_commentaryA
Read-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_matchesA
Read-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_eventsA
Read-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_lineupsA
Read-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_officialsA
Read-onlyIdempotent

Match officials — referee, assistants, fourth official, VAR.

Returns: {matchId, matchOfficials:[{role, name, …}]}

Auth: none needed.

Inputs: id (required).

pl_match_statsA
Read-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_matchesA
Read-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_metadataA
Read-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_latestA
Read-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_playerA
Read-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_basicA
Read-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_statsA
Read-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_infoA
Read-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_leaderboardA
Read-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_playersA
Read-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_idA
Read-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_statsB
Read-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_teamsA
Read-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_squadA
Read-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_standingsA
Read-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_structureA
Read-onlyIdempotent

Season structure — current phase + phase/matchweek layout for one season.

Returns: {currentPhase, structure}

Auth: none needed.

Inputs: cid (required), sid (required).

pl_teamA
Read-onlyIdempotent

One team within a competition by id.

Returns: {name, shortName, abbreviation, player_id}

Auth: none needed.

Inputs: cid (required), tid (required).

pl_team_formA
Read-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_teamformA
Read-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_leaderboardA
Read-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_fixtureA
Read-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_teamsA
Read-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_idA
Read-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_statsA
Read-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_latestA
Read-onlyIdempotent

Latest video, smart-ranked.

Returns: [{title, canonicalUrl, date, duration, …}] (top-level array)

Example: Latest video {"limit": 5}

Auth: none needed.

Inputs: tags, limit.

pointsbet_competition_eventsA
Read-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_callA
Read-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_eventA
Read-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_events_nextupA
Read-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_streamingA
Read-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_multisA
Read-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_codeA
Read-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_promotionsA
Read-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_formA
Read-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_futuresA
Read-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_quaddieA
Read-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_insightsA
Read-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_meetingA
Read-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_meetingsA
Read-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_raceA
Read-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_racesA
Read-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_srmA
Read-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_tipsA
Read-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_priceA
Read-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_competitionsA
Read-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_sports_inplayA
Read-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_listA
Read-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_bookA
Read-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_marketsA
Read-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_eventA
Read-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_eventsA
Read-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_holdersB
Read-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_marketA
Read-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_marketsA
Read-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_midpointA
Read-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_priceB
Read-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_historyA
Read-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_seriesA
Read-onlyIdempotent

One series by Gamma id, with its events.

Returns: {id, title, slug, seriesType, recurrence, events:[…]}

Auth: none needed.

Inputs: id (required).

polymarket_series_listA
Read-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_sportsA
Read-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_spreadB
Read-onlyIdempotent

Bid-ask spread for one outcome token.

Returns: {spread}

Auth: none needed.

Also answers this: kalshi_orderbook.

Inputs: token_id (required).

polymarket_tagsA
Read-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_tradesA
Read-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_oddsA
Read-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_sportA
Read-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_goA
Read-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_oddsA
Read-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_linesA
Read-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_eventsA
Read-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_moversA
Read-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_goA
Read-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_resultsA
Read-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_venuesA
Read-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_oddsA
Read-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_oddsA
Read-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_sportsA
Read-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_listA
Read-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_oddsA
Read-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_racingA
Read-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_competitionsA
Read-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_matchesA
Read-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_lineupsA
Read-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_playersA
Read-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_seasonA
Read-onlyIdempotent

One season's detail by seasonId.

Returns: {season:{seasonId, seasonName, startDateUtc, endDateUtc, competitionId, imagery}}

Auth: none needed.

Inputs: seasonId (required), locale.

seriea_seasonsA
Read-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_standingsA
Read-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_teamsA
Read-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_statsA
Read-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_draftB
Read-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_picksA
Read-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_leagueA
Read-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_draftsA
Read-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_rostersA
Read-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_usersA
Read-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_matchupsA
Read-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_playersA
Read-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_bracketA
Read-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_stateA
Read-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_picksA
Read-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_transactionsA
Read-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_userA
Read-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_leaguesA
Read-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_fixtureA
Read-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_dateA
Read-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_leaguesA
Read-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_livescoresA
Read-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_playersA
Read-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_standingsA
Read-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_teamsA
Read-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_typesA
Read-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_historyA
Read-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_liveA
Read-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_couponA
Read-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_messagesA
Read-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_pageA
Read-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_settingsA
Read-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_matchesA
Read-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_outrightsA
Read-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_commentaryA
Read-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_marketsA
Read-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_resultsA
Read-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_statusA
Read-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_callA
Read-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_ladderA
Read-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_previewA
Read-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_racecardsA
Read-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_nav_hierarchyA
Read-onlyIdempotent

Sports navigation hierarchy (class → competition tree for menus).

Returns: {nav:[{classId, name, competitions:[{competitionId, name}]}]}

Auth: works without a key; SPORTSBET_REFRESH_TOKEN unlocks more if set.

Inputs: no named parameters.

sportsbet_page_contentA
Read-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_price_slipA
Read-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_racecardB
Read-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_contextA
Read-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_previewA
Read-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_allracingA
Read-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_betsA
Read-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_eventsA
Read-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_challengesA
Read-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_competitionA
Read-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_meetingA
Read-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_futuresA
Read-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_megabetsA
Read-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_eventsA
Read-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_resulted_eventsA
Read-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_jockeysA
Read-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_classesA
Read-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_competitionsA
Read-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_messageA
Read-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_priceA
Read-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_legacyA
Read-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_competitionA
Read-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_eventsA
Read-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_cardA
Read-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_classesA
Read-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_reportA
Read-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_upcoming_eventsA
Read-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_dateA
Read-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_slatesA
Read-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_dateA
Read-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_slatesA
Read-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_injuriesA
Read-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_projectionsA
Read-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_scoresA
Read-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_teamsA
Read-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_dateA
Read-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_statsA
Read-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_bookmakersA
Read-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_eventsA
Read-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_leaguesA
Read-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_playersA
Read-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_sportsA
Read-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_statsA
Read-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_teamsA
Read-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_gamesA
Read-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_ladderA
Read-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_sourcesA
Read-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_standingsA
Read-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_teamsA
Read-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_tipsA
Read-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_leaguesA
Read-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_playerA
Read-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_playersA
Read-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_fixtureA
Read-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_settingsA
Read-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_teamsA
Read-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_callA
Read-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_competitionA
Read-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_live_events_summaryA
Read-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_matchA
Read-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_marketsA
Read-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_builderA
Read-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_slipA
Read-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_datesA
Read-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_meetingsA
Read-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_raceA
Read-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_jackpotsA
Read-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_racesA
Read-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_meetingsA
Read-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_goA
Read-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_raceA
Read-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_formA
Read-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_formA
Read-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_sgm_priceA
Read-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_sportA
Read-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_sportsA
Read-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_goA
Read-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_resultsA
Read-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_tournamentA
Read-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.

theoddsapi_event_oddsA
Read-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_eventsA
Read-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_oddsA
Read-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_oddsA
Read-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_scoresA
Read-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_sportsA
Read-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_usersA
Read-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_tweetsA
Read-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_byA
Read-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_recentA
Read-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_tweetA
Read-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_countsA
Read-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_tweetsA
Read-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_usageA
Read-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_userA
Read-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_usernameA
Read-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_mentionsA
Read-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_usersA
Read-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_usernamesA
Read-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_tweetsA
Read-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_athleteA
Read-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_statsA
Read-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_cardA
Read-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_eventsA
Read-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_fightsA
Read-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_indexA
Read-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_rankingsA
Read-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_recordsA
Read-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_athletesA
Read-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_callA
Read-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_statsA
Read-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_ladderA
Read-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_callA
Read-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_priceA
Read-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_couponA
Read-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_playerA
Read-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_matchesA
Read-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_playersA
Read-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_rankingsA
Read-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_tournamentA
Read-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_matchesA
Read-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_playersA
Read-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_tournamentsA
Read-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_gameA
Read-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_positionsA
Read-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_categoriesA
Read-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_leagueA
Read-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_draftA
Read-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_playersA
Read-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_scoreboardA
Read-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_settingsA
Read-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_standingsA
Read-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_teamsA
Read-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_transactionsA
Read-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_gamesA
Read-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_leaguesA
Read-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_teamsA
Read-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_ownershipA
Read-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_statsA
Read-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_teamA
Read-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_matchupsA
Read-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_rosterA
Read-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_statsA
Read-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

    B3.3/5.0

    Scored across 844 tools

    Disambiguation2/5

    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.

    Naming Consistency4/5

    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.

    Tool Count1/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      MCP-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.
      29
      29 npm
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      A 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.
      14
      165
      95 npm
      40
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      An 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.
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Props-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