SportWizzard API
The sports betting data API — real-time odds from 35+ books, plus players, teams, box-score stats, historical prices, and game context (weather, lineups, probable pitchers) in one canonical schema. Build your own models on it. Edges & arbitrage signals included.
Getting started
The SportWizzard REST API is served from a single base URL. Every endpoint lives under /api/v1 and returns JSON.
Authentication
Authenticate by sending your API key in the X-Api-Key request header. Keys are issued through your account — sign up, open your account, and create a key under the API Keys tab. Reference endpoints (leagues, sportsbooks, teams, players, markets) are free and require no key.
curl "https://api.sportwizzard.com/api/v1/events?league=mlb" \
-H "X-Api-Key: sw_live_your_api_key_here"Response envelope
Every response uses the same envelope. Results are in data; list endpoints add an opaque nextCursor and a meta object with count and an updated timestamp.
{
"success": true,
"data": [ /* … */ ],
"nextCursor": "opaque-cursor-string-or-null",
"meta": { "count": 50, "updated": "2026-07-09T16:41:27Z" }
}Pagination
List endpoints are cursor-paginated. Pass limit to size a page, then take the nextCursor from the response and send it back as ?cursor=… for the next page. Cursors are opaque — treat them as blackbox tokens. When nextCursor is null, you have reached the end.
Freshness & caching
Live-odds responses carry an ETag. Send it back on the next call via If-None-Match to get a cheap 304 Not Modified when nothing has changed. To sync efficiently, poll /api/v1/odds/updated?since={timestamp} for just the rows that changed.
The resource model
It's a data API first. Pull odds, stats, and per-game context around any event — or grab the whole board in one snapshot. Edges & arbitrage are derived signals on top of the same data.
Events
Games and matches, the spine of the platform. List and filter by league/team/time, or fetch one for the enriched detail — scores, result, venue, and a context object with weather, lineups, and probable pitchers — plus the full box score and odds board.
/v1/events/v1/events/{id}/v1/events/{id}/stats/v1/events/{id}/odds/v1/events/activeOdds
A flat, normalized odds feed with entity scoping. Filter by league, sportsbook, market, event, player, or team. A delta feed returns only what changed since a timestamp.
/v1/odds/v1/odds/updated/v1/players/{id}/odds/v1/teams/{id}/oddsStats
Per-event box-score stats for players and teams, keyed by season, plus a bulk feed you can scope to an event, team, or player. JSON stat blobs matched to our canonical entity IDs — the raw material for your models.
/v1/players/{id}/stats/v1/teams/{id}/stats/v1/stats/playersSnapshot
The entire live board across every book and league as one pre-built gzip blob. Bootstrap a full local copy in a single request, then keep it fresh with the odds delta feed. ETag / If-None-Match 304 support. (Growth and up; 1 credit per pull — Growth refreshes every 5 min, Enterprise is real-time.)
/v1/snapshotReference
Free, uncounted catalog data. Leagues, seasons, sportsbooks, teams, players, and the market-type catalog we normalize into. Leagues are seasonal — call /leagues first to see what’s currently live.
/v1/leagues/v1/seasons/v1/sportsbooks/v1/teams/v1/players/v1/markets/v1/statusHistorical
Point-in-time odds and settled arbitrage history for backtesting and model training. (All paid plans; 5 credits per event.)
/v1/historical/odds/v1/historical/arbitrageEdges & Arbitrage
Derived signals computed from the same data — handy defaults, yours to outdo. Pre-computed DFS edges (soft line vs. sharp book) and cross-book arbitrage (two-way and three-way), refreshed continuously. Edges are screening signals against the most favorable book’s no-vig price — a starting point for your own verification, not guaranteed +EV.
/v1/edges/v1/arbitrageAccount
Your current plan, rate limit, and monthly usage against your cap.
/v1/account/usageThe odds data model
Understand this and the rest of the API falls into place.
Events are the spine
Everything hangs off an event — a single game or match, with homeTeamId/awayTeamId, startTime, league, and status. Odds, box-score stats, and per-game context are all keyed by eventId. The normal path: list events, take an id, then pull that event's board via /v1/events/{id}/odds.
Odds are a flat array
The odds feed is not nested. It's a flat list with one row per (sportsbook × market × selection), and every row is fully self-describing — it repeats its eventId, sportsbook, market, selection, side, line, and price, so you never walk a tree to know what a row means. One shape describes a baseball run line, an NBA player-points prop, a soccer 3-way moneyline, and a golf outright — which makes odds trivial to filter, join, and load into a table or dataframe.
The composite id
Each row's id is a stable composite key of the form {eventId}:{sportsbook}:{marketSubtype}:{selectionId} (the selectionId is a time-ordered UUIDv7). It stays the same across polls for the same line, so use it as your primary key to upsert/dedupe: a price or line move keeps the same id and only changes priceAmerican/priceDecimal/line/updated.
A real, trimmed odds row:
{
"id": "31cd6744-…-c4a7d1fce547:ballybet:SPREAD:019f495d-8558-7324-…",
"sportsbook": "ballybet",
"league": "mlb",
"eventId": "31cd6744-9444-4fbd-b25c-c4a7d1fce547",
"market": "SPREAD",
"marketSubtype": "SPREAD",
"period": "FULL",
"selection": "KC Royals",
"side": "AWAY",
"teamSide": "AWAY",
"teamName": "KC Royals",
"line": -1.5,
"priceAmerican": 200,
"priceDecimal": 3.00,
"suspended": false,
"eventStartTime": "2026-07-10T23:05",
"updated": "2026-07-10T14:53:35Z"
}Field glossary
| Field | Meaning |
|---|---|
market | Broad market family — MONEYLINE, SPREAD, TOTAL, TEAM_TOTAL, PLAYER_TOTAL, PLAYER_MILESTONE, MONEYLINE_3_WAY, CORRECT_SCORE… |
marketSubtype | Specific stat/variant within the family (TOTAL_RUNS, PLAYER_TOTAL_SHOTS). Equals market for simple markets; it's the segment used in the id. |
period | Scope of the wager. FULL is the whole game; sport-specific partials also appear (baseball 1INN, 1INN_5INN; halves/quarters elsewhere). |
selection | Human label of the picked outcome (team name, Over, Under, Draw). |
side | Normalized side: HOME / AWAY / DRAW (3-way) or OVER / UNDER (totals & props). Filter on this, not selection. |
teamSide / teamName | Which side of the event the selection belongs to and that team's name. For a player prop, the player's team side. |
line | Handicap or total the price is quoted against (spread -1.5, total 8.5, prop 4.5). Absent for pure moneylines. |
priceAmerican / priceDecimal | Same price in American (+200) and decimal (3.00) forms. DFS pick'em offers may omit price and carry dfsMultiplier instead. |
playerId / playerName | Present only on player-prop rows — the canonical player this line is about. Absent on team/game markets. |
dfsMultiplier | Payout multiplier on DFS pick'em offers (1.0 for a standard pick). |
suspended | true when the book has the line temporarily locked — not bettable. |
eventStartTime / updated | Scheduled event start (denormalized) and when this line was last refreshed (UTC). updated is what the delta feed's since= compares against. |
Raw odds rows carry book prices only — there is no fairOdds/devigged field on an odds row. No-vig fair value and cross-book comparison live on the derived /v1/edges and /v1/arbitrage signals, computed from these same rows.
Reading /v1/edges honestly: the edge value is the gap between a DFS line and the most favorable sportsbook's vig-removed implied probability — so it's optimistic by construction, and an edge resting on a single book's quote can just be a stale line. Treat it as a screen for soft DFS lines to verify yourself, not a proven +EV bet. /v1/arbitrage margins hold only if every leg fills at the quoted price before it moves.
Four ways to read odds
Live board — /v1/odds (and /v1/events/{id}/odds, /v1/players/{id}/odds, /v1/teams/{id}/odds): cache-served, seconds-fresh — a point-in-time read of what's bettable now. Delta feed — /v1/odds/updated?since={ts}: only rows changed since your last sync, for cheap continuous polling — scopeable with the same league / sportsbook / market filters as /odds. Snapshot — /v1/snapshot: the entire live board across every book and league as one gzip pull, to bootstrap a full local copy. Historical — /v1/historical/odds: point-in-time replay of a past event for backtesting (paid plans, ×5 credits).
Rule of thumb: snapshot to bootstrap → /odds/updated to stay in sync → /odds (scoped) for targeted reads → /historical/odds to replay the past.
Scoping odds
Unscoped, /v1/odds spans every league and book and paginates hard — always scope it: by event (/v1/events/{id}/odds), by entity (/v1/players/{id}/odds, /v1/teams/{id}/odds), or by filter on /v1/odds with league, sportsbook, market, event_id, player_id, and team_id (combine freely), plus cursor and limit. league, sportsbook, and market each take up to 20 comma-separated values, matched any-of (e.g. sportsbook=draftkings,fanduel). Two shaping params apply on every live-odds read: odds_format (american | decimal | probability | all, default both price fields; probability returns implied probability instead) and is_main=true (keep only each market's primary line per book, collapsing alt over/under ladders to the main number; not on the delta feed).
Example responses by league
Real, trimmed responses across every live league — baseball, basketball, soccer, and golf. Pick a league, then flip between the event, its odds board, a settled box score, and a derived edge or arbitrage signal.
{
"success": true,
"data": [
{
"id": "3a4170cb-0064-48b6-933d-4c4a6ce27283",
"homeTeamId": "7d0a7f60-138a-11f1-aba1-de512ebea802",
"homeTeamName": "Miami Marlins",
"awayTeamId": "7d0a8055-138a-11f1-aba1-de512ebea802",
"awayTeamName": "Seattle Mariners",
"startTime": "2026-07-09T22:40Z",
"status": "scheduled",
"league": "mlb",
"hasOdds": true,
"venueId": "b948390b-3a35-4fc3-a00b-08d8b6959ade",
"seasonYear": 2026,
"context": {
"probable_pitchers": {
"home_id": "7ebc2295-138a-11f1-aba1-de512ebea802",
"away_id": "7ebc6aeb-138a-11f1-aba1-de512ebea802"
}
}
}
],
"meta": {
"count": 1,
"updated": "2026-07-09T18:24:55Z"
}
}api.sportwizzard.com · captured 2026-07-09 · trimmed for brevityEndpoints
All 28 v1 endpoints. Try any of them live in the interactive reference.
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/v1/events | Events (filter by league/team/status/time, cursor) | Reference |
| GET | /api/v1/events/active | Events with live markets | Reference |
| GET | /api/v1/events/{id} | Enriched event detail — scores, result, venue & context (weather, lineups, probable pitchers) | Reference |
| GET | /api/v1/events/{id}/stats | Full box score — team totals + per-player stat blobs | API Key |
| GET | /api/v1/events/{id}/odds | Full odds board for one event | API Key |
| GET | /api/v1/odds | Normalized odds feed (entity-scoped) | API Key |
| GET | /api/v1/odds/updated | Odds delta feed since a timestamp | API Key |
| GET | /api/v1/players/{id}/odds | All odds for one player | API Key |
| GET | /api/v1/teams/{id}/odds | All odds for one team | API Key |
| GET | /api/v1/players/{id}/stats | Player box stats (by season) | API Key |
| GET | /api/v1/teams/{id}/stats | Team box stats (by season) | API Key |
| GET | /api/v1/stats/players | Bulk player box stats (filter by event/team/player) | API Key |
| GET | /api/v1/snapshot | Entire live board as one gzip blob (ETag / 304) | Growth+ |
| GET | /api/v1/status | Platform status — total markets & sportsbook count | Reference |
| GET | /api/v1/leagues | Active leagues (seasonal — call this first) | Reference |
| GET | /api/v1/seasons | Seasons for a given year, across all leagues | Reference |
| GET | /api/v1/sportsbooks | Sportsbooks & DFS platforms with market counts | Reference |
| GET | /api/v1/markets | Market-type catalog | Reference |
| GET | /api/v1/markets/active | Market types with live markets | Reference |
| GET | /api/v1/teams | Teams (filter by league, cursor) | Reference |
| GET | /api/v1/teams/{id} | Get a team | Reference |
| GET | /api/v1/players | Players (filter by league/team, cursor) | Reference |
| GET | /api/v1/players/{id} | Get a player | Reference |
| GET | /api/v1/historical/odds | Point-in-time odds (×5 credits) | Pro+ |
| GET | /api/v1/historical/arbitrage | Settled arbitrage history (×5 credits) | Pro+ |
| GET | /api/v1/edges | DFS edge opportunities (derived signal) | API Key |
| GET | /api/v1/arbitrage | Arbitrage opportunities (derived signal, two-way / three-way) | API Key |
| GET | /api/v1/account/usage | Your plan, rate limit & monthly usage | Reference |
Rate limits & tiers
| Tier | Price | Rate limit | Credits / month | Historical | Snapshot |
|---|---|---|---|---|---|
| Free | $0 | 2 / min | 5,000 (hard stop) | — | — |
| Pro | $25 / mo ($250 / yr) | 10 / min | 500,000 (hard stop) | ×5 credits | — |
| Growth | $50 / mo ($500 / yr) | 30 / min | 1,500,000 (hard stop) | ×5 credits | 5-min refresh |
| Enterprise | $100 / mo ($1,000 / yr) | 60 / min | Soft-unlimited (5M fair-use) | ×5 credits | Real-time |
1 credit = 1 event served — empty responses and 304s are free, and reference endpoints never consume credits. Annual billing = 2 months free. See full plan details on the pricing page. Usage is returned in response headers so you can track consumption programmatically.
Built for developers
35+ Sources
PrizePicks, Underdog, FanDuel, BetMGM, Pinnacle, DraftKings, and 30 more — all normalized into a single canonical schema.
Real-Time Updates
Markets are ingested every few seconds. Use the /odds/updated delta feed with ETag / If-None-Match to sync cheaply.
Data for Model Builders
Odds, box-score stats, historical prices, and per-game context (weather, lineups, probable pitchers) in one schema — or the whole board in a single gzip snapshot.
Simple REST + JSON
One consistent response envelope, X-Api-Key header auth, opaque cursor pagination. No SDK required — works from any language.
MCP server
Wire SportWizzard into Claude & any MCP client
An open-source, npx-installable stdio server exposing 20 tools over the same v1 API — live odds, edges, arbitrage, events, box scores, and reference data. Includes a download_snapshot tool that streams the entire board to disk, plus a mock mode so you can develop with zero API calls.
Using Claude Code, Codex, or another coding agent? See the agent quickstart for copy-paste curl, the .mcp.json snippet, and setup for a hosted remote MCP server.
{
"mcpServers": {
"sportwizzard": {
"command": "npx",
"args": ["-y", "sportwizzard-mcp"],
"env": { "SPORTWIZZARD_API_KEY": "sw_live_…" }
}
}
}