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.

Base URL  →  https://api.sportwizzard.com

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/active

Odds

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}/odds

Stats

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/players

Snapshot

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/snapshot

Reference

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/status

Historical

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/arbitrage

Edges & 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/arbitrage

Account

Your current plan, rate limit, and monthly usage against your cap.

/v1/account/usage

The 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

FieldMeaning
marketBroad market family — MONEYLINE, SPREAD, TOTAL, TEAM_TOTAL, PLAYER_TOTAL, PLAYER_MILESTONE, MONEYLINE_3_WAY, CORRECT_SCORE
marketSubtypeSpecific stat/variant within the family (TOTAL_RUNS, PLAYER_TOTAL_SHOTS). Equals market for simple markets; it's the segment used in the id.
periodScope of the wager. FULL is the whole game; sport-specific partials also appear (baseball 1INN, 1INN_5INN; halves/quarters elsewhere).
selectionHuman label of the picked outcome (team name, Over, Under, Draw).
sideNormalized side: HOME / AWAY / DRAW (3-way) or OVER / UNDER (totals & props). Filter on this, not selection.
teamSide / teamNameWhich side of the event the selection belongs to and that team's name. For a player prop, the player's team side.
lineHandicap or total the price is quoted against (spread -1.5, total 8.5, prop 4.5). Absent for pure moneylines.
priceAmerican / priceDecimalSame price in American (+200) and decimal (3.00) forms. DFS pick'em offers may omit price and carry dfsMultiplier instead.
playerId / playerNamePresent only on player-prop rows — the canonical player this line is about. Absent on team/game markets.
dfsMultiplierPayout multiplier on DFS pick'em offers (1.0 for a standard pick).
suspendedtrue when the book has the line temporarily locked — not bettable.
eventStartTime / updatedScheduled 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.

GET/api/v1/events?league=mlb&limit=1
{
  "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"
  }
}
Real response from api.sportwizzard.com · captured 2026-07-09 · trimmed for brevity

Endpoints

All 28 v1 endpoints. Try any of them live in the interactive reference.

MethodEndpointDescriptionAccess
GET/api/v1/eventsEvents (filter by league/team/status/time, cursor)Reference
GET/api/v1/events/activeEvents with live marketsReference
GET/api/v1/events/{id}Enriched event detail — scores, result, venue & context (weather, lineups, probable pitchers)Reference
GET/api/v1/events/{id}/statsFull box score — team totals + per-player stat blobsAPI Key
GET/api/v1/events/{id}/oddsFull odds board for one eventAPI Key
GET/api/v1/oddsNormalized odds feed (entity-scoped)API Key
GET/api/v1/odds/updatedOdds delta feed since a timestampAPI Key
GET/api/v1/players/{id}/oddsAll odds for one playerAPI Key
GET/api/v1/teams/{id}/oddsAll odds for one teamAPI Key
GET/api/v1/players/{id}/statsPlayer box stats (by season)API Key
GET/api/v1/teams/{id}/statsTeam box stats (by season)API Key
GET/api/v1/stats/playersBulk player box stats (filter by event/team/player)API Key
GET/api/v1/snapshotEntire live board as one gzip blob (ETag / 304)Growth+
GET/api/v1/statusPlatform status — total markets & sportsbook countReference
GET/api/v1/leaguesActive leagues (seasonal — call this first)Reference
GET/api/v1/seasonsSeasons for a given year, across all leaguesReference
GET/api/v1/sportsbooksSportsbooks & DFS platforms with market countsReference
GET/api/v1/marketsMarket-type catalogReference
GET/api/v1/markets/activeMarket types with live marketsReference
GET/api/v1/teamsTeams (filter by league, cursor)Reference
GET/api/v1/teams/{id}Get a teamReference
GET/api/v1/playersPlayers (filter by league/team, cursor)Reference
GET/api/v1/players/{id}Get a playerReference
GET/api/v1/historical/oddsPoint-in-time odds (×5 credits)Pro+
GET/api/v1/historical/arbitrageSettled arbitrage history (×5 credits)Pro+
GET/api/v1/edgesDFS edge opportunities (derived signal)API Key
GET/api/v1/arbitrageArbitrage opportunities (derived signal, two-way / three-way)API Key
GET/api/v1/account/usageYour plan, rate limit & monthly usageReference

Rate limits & tiers

TierPriceRate limitCredits / monthHistoricalSnapshot
Free$02 / min5,000 (hard stop)
Pro$25 / mo ($250 / yr)10 / min500,000 (hard stop)×5 credits
Growth$50 / mo ($500 / yr)30 / min1,500,000 (hard stop)×5 credits5-min refresh
Enterprise$100 / mo ($1,000 / yr)60 / minSoft-unlimited (5M fair-use)×5 creditsReal-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

Model Context Protocol

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.

github.com/adamruehle/sportwizzard-mcp →

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.

claude_desktop_config.json
{
  "mcpServers": {
    "sportwizzard": {
      "command": "npx",
      "args": ["-y", "sportwizzard-mcp"],
      "env": { "SPORTWIZZARD_API_KEY": "sw_live_…" }
    }
  }
}

Start building with SportWizzard

Free tier includes 5,000 credits/month (1 credit = 1 event served). Upgrade for full real-time access.