MLB
MLB API for Scores, Stats, Odds & AI Agents
One event graph for Major League Baseball — first-pitch schedules, inning-aware live scores, nine-book moneyline/run line/totals, settleable player props, public splits, baseball-native stats, and a market-anchored intelligence Price plane agents can reason over.
Available data
Everything below filters on the stable slug sport=mlb (league mlb). Discover seasons with GET /v1/seasons?sport=mlb and teams with GET /v1/teams?sport=mlb.
| Layer | Endpoint | MLB notes |
|---|---|---|
| Schedule / board | GET /v1/events | sport=mlb; status, date, include_odds / include_scores |
| Live score | GET /v1/events/{id}/score · SSE | Top 7th / Bot 9th; clock is null |
| Odds | GET …/odds · …/odds/history | Two-way h2h, run line (spreads), totals · 17 books |
| Player props | GET …/player-props | Settleable batting/pitching mains + live box progress |
| Team totals | GET …/team-props | Each team's full-game runs Over/Under + this-event score |
| Period odds | GET …/period-odds | First-five innings spreads/totals |
| Splits | GET …/splits | Pre-game ticket% vs handle% (in-season) |
| Stats (Data) | GET …/stats | Baseball-native Path A — post-final box aggregates |
| Intelligence | GET …/intelligence | Customer surface: fair probability + Price overlay; forecasts[] |
| Forecasts | GET /v1/intelligence/forecasts | Daily board of forecasted prop wagers. MCP list_forecasts |
Schedules
List the slate with GET /v1/events?sport=mlb. Narrow by status (scheduled / inprogress / final), date or from/to (max 90 days per request), and paginate with after_id / limit.
Daily MLB volume is high — use date windows and include_odds=true / include_scores=true to keep a night’s board to one round trip. Rain delays / postponements surface via event status fields.
Scores
MLB score payloads use baseball period labels — e.g. "Top 7th", "Bot 9th". Game clock is null (not in source for MLB).
- GET /v1/events?sport=mlb&status=inprogress&include_scores=true — live board
- GET /v1/events/{id}/score — lightweight poll (~15s cache while live)
- GET /v1/events/{id}/stream — SSE event: score or signed webhooks
Cloneable pattern: live scoreboard use case (keep keys server-side).
Odds
MLB markets are two-way: moneyline (h2h), run line (spreads, typically ±1.5), and game totals. American odds integers; point is null on moneyline sides. Default single-book call is Pinnacle; bookmaker=all is the same 1 credit.
GET /v1/events/{id}/odds/history returns recorded price/point moves between ingest cycles. Player props live on GET /player-props — not on /odds.
Full bookmaker list: Sports Odds API.
Player props
GET /v1/events/{id}/player-props (1 credit when lines exist; available:false is free) joins persisted player-prop mains to this-event player box counts and grades over / under / push once the game is final. MLB batting: hits, runs, RBIs, home runs, stolen bases, batter Ks, total bases (H + 2B + 2·3B + 3·HR), hits+runs+RBIs. Pitching: pitcher Ks, hits allowed, earned runs, outs recorded. walks is not catalogued (batter vs pitcher ambiguity).
Market keys and which ones grade: player props catalog. Endpoint fields: API reference.
Stats (Data layer)
GET /v1/events/{id}/stats returns a baseball-native payload shaped for MLB box-score aggregates. Path A reads ingested box scores for completed games:
- Season W/L record · recent form (W/L + runs scored/allowed)
- Head-to-head · team batting/pitching rates
- Starting pitcher season rates · lineup from the completed box
No confidence, narrative, or odds inside /stats. Expect useful aggregates primarily post-final; always check available. Pair with /intelligence when you want the market Price plane on the same ID. Fields: API reference — stats.
Intelligence
MLB /intelligence returns a customer surface — fair probability + Price overlay only. Framework plumbing (phase, blend_w, p_model, p_market, sufficiency, drivers, alignment, model_version) is omitted. probability / fair_price are a vig-stripped market reference — not a model pick — and edge / tier / has_recommend stay null/false until Edge clears.
Read the Price surface for cross-book line-shopping:
- fair — sharp-consensus fair (Pinnacle + Circa when both quote)
- edges_by_book — price gap vs fair.probability per soft book
- best — highest-gap book/price for line-shopping (Tier C informational)
- ev (Beta, main-line) — the same positive gap packaged as ev_pct + Kelly. Scan a sport with GET /v1/intelligence/ev.
Price ≠ Edge. A positive gap is not a bet recommendation. For pitcher/lineup Data use /stats. Always check available before reading bets.
Splits
GET /v1/events/{id}/splits — public ticket% vs handle% on moneyline, run line, and total, with consensus + per-book breakdown. Pre-game only; frozen after first pitch. 1 credit when available.
Sportsbooks
Odds keys: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada. Availability varies by event — check each bookmaker entry. MLB sharp fair for intelligence uses Pinnacle and Circa when both quote.
Splits use the same bookmaker slugs as odds under bookmakers[].bookmaker (e.g. draftkings, fanduel).
Examples
Today’s MLB schedule with odds inlined:
curl "https://lumify.ai/v1/events?sport=mlb&status=scheduled&include_odds=true&limit=5" \
-H "Authorization: Bearer YOUR_API_KEY"
from lumify import Lumify client = Lumify(api_key="YOUR_API_KEY") page = client.events.list( sport="mlb", status="scheduled", include_odds=True, limit=5, ) for event in page["events"]: print(event["id"], event["name"], event.get("odds"))
import { Lumify } from "@lumifyai/sdk"; const client = new Lumify({ apiKey: "YOUR_API_KEY" }); const { events } = await client.events.list({ sport: "mlb", status: "scheduled", includeOdds: true, limit: 5, }); events.forEach(e => console.log(e.id, e.name, e.odds));
Intelligence Price surface (1 credit when available):
curl "https://lumify.ai/v1/events/8815/intelligence" \
-H "Authorization: Bearer YOUR_API_KEY"
intel = client.events.intelligence(8815) if intel.get("available"): for bet in intel.get("bets") or []: print( bet.get("bet_type"), bet.get("probability"), bet.get("fair"), bet.get("best"), )
const intel = await client.events.intelligence(8815); if (intel.available) { for (const bet of intel.bets ?? []) { console.log(bet.bet_type, bet.probability, bet.fair, bet.best); } }
Post-final Data-layer stats:
curl "https://lumify.ai/v1/events/8815/stats" \
-H "Authorization: Bearer YOUR_API_KEY"
stats = client.events.stats(8815) if stats.get("available"): print(stats.get("league_slug"), stats.get("teams"))
const stats = await client.events.stats(8815); if (stats.available) { console.log(stats.league_slug, stats.teams); }
Sample odds shape (abridged MLB run line):
{
"event_id": 8815,
"available": true,
"bookmakers": [
{
"bookmaker": "pinnacle",
"markets": [
{
"key": "spreads",
"label": "spread",
"outcomes": [
{ "outcome": "New York Yankees", "price": -120, "point": -1.5 },
{ "outcome": "Boston Red Sox", "price": 100, "point": 1.5 }
]
}
],
"captured_at": "2026-08-10T17:05:00Z"
}
]
}
Freshness
| Feed | Cadence | Fit |
|---|---|---|
| Live scores | ~1 minute (+ SSE/webhooks) | Scoreboards, in-game agents |
| Odds ingest | ~10 minutes (2-min response cache) | Research, line shop, alerts — not HFT |
| Player props | Lines ~10 min; live box ~1 min while in progress | Settleable mains + this-event box progress |
| Splits | Pre-game ingest | Stops updating after first pitch |
| Stats | After box scores ingest (post-final) | Data layer for completed games |
| Intelligence | After publish runs | Check available; Price quotes age-capped |
Pricing
| Call | Credits |
|---|---|
| Most successful GETs (events, score, stats, intelligence, splits, …) | 1 |
| Multi-book odds (bookmaker=all or a list) | 1 |
| available: false / errors | 0 |
Free Tier: 1,000 credits that never expire. Instant trial: 100 credits / 14 days, no signup. Details: /pricing.
For agents: machine-readable twin at /sports/mlb-api.md. MCP tools: list_events, get_odds, get_player_props, get_splits, get_stats, get_intelligence, list_ev, list_forecasts — setup at /sports-mcp-server.
FAQ
Filter with sport=mlb for schedules, live scores (Top/Bot innings), teams/players, multi-book moneyline / run line / totals, settleable player props, public betting splits, baseball-native /stats (Data layer), and predictive /intelligence with a sharp fair + cross-book Price surface. Same event IDs across every layer.
MLB returns a customer surface: probability, interval, fair_price, market, edge/tier (null today), plus Price fair / edges_by_book / best and main-line ev (Beta). Framework plumbing (phase, blend_w, p_model, etc.) is omitted. best.edge is a line-shopping price gap vs sharp consensus. Tokens: ML_P1/ML_P2, SPREAD_* (run line), OVER/UNDER.
/stats is the raw Data layer — season W/L, form, H2H, batting/pitching rates (AVG/OBP/SLG/OPS + RBI/TB/triples), starting pitcher season rates once the post-final box lands (pregame probable SP stays on /intelligence), lineup from completed box scores, and this event's player_box (per-player batting/pitching counting stats). No scoring or narrative. /intelligence is the customer-facing fair-probability + Price surface on the same event IDs. Fetch both when you want aggregates alongside the market plane.
Yes — batting and pitching mains on GET /player-props. Batting: hits, runs, RBIs, home runs, stolen bases, batter Ks, total bases, hits+runs+RBIs. Pitching: pitcher Ks, hits allowed, earned runs, outs recorded. walks is not catalogued (our source uses one key for batter BB vs pitcher BB allowed). GET /odds stays moneyline/run line/totals. /stats player_box is this event's raw batting/pitching lines. Catalog: /docs/player-props.
GET /v1/events/{id}/splits returns public ticket% vs handle% for MLB pre-game — same coverage class as NBA/NHL/NFL. Splits stop updating once first pitch goes live. Pair with /odds and the intelligence Price surface for sharp-vs-public and cross-book context.
Start with the MLB API
Create a free key — or use an instant trial key with no signup — and pull today’s MLB slate with odds in under a minute.