ESPN Sports Odds Scraper
Pricing
Pay per event
ESPN Sports Odds Scraper
Extract current ESPN betting lines across NFL, NBA, MLB, and English soccer for comparison and movement analysis.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Collect current ESPN sports odds for NFL, NBA, MLB, and English Premier League events in one normalized dataset.
The Actor extracts event schedules, teams, moneylines, spreads, totals, sportsbook provider details, and ESPN's opening and current values. Run it once for a comparison export or schedule it to build snapshots for line-movement analysis.
No ESPN login, betting account, browser, or user-supplied API key is required.
What can you do with ESPN Sports Odds Scraper?
- Compare upcoming lines across NFL, NBA, MLB, and English soccer.
- Export ESPN MLB moneylines, run lines, and totals to a spreadsheet.
- Record opening and current prices on a schedule.
- Flag records where an available line or price changed.
- Join odds snapshots to internal event, team, or forecasting data.
- Feed normalized records into dashboards, databases, and alerts.
Each dataset item represents one ESPN event and odds provider. Events without published odds are skipped rather than returned as empty betting records.
Who is this Actor for?
Sports analysts can collect a consistent cross-league feed without maintaining four league-specific parsers.
Betting-data teams can store scheduled snapshots and compare opening values with current values.
Data engineers can send typed JSON, CSV, or Excel output into a warehouse or BI workflow.
Researchers can create reproducible event-level datasets with ESPN IDs and source URLs.
Automation builders can schedule runs and trigger downstream processing from Apify webhooks or integrations.
Supported leagues
| Input value | League | ESPN sport path |
|---|---|---|
nfl | National Football League | football |
nba | National Basketball Association | basketball |
mlb | Major League Baseball | baseball |
epl | English Premier League | soccer |
Odds are seasonal. A supported league can legitimately return no records when no events are scheduled or when ESPN has not published lines for the selected dates.
What data is extracted?
| Field group | Examples |
|---|---|
| Event identity | eventId, eventName, shortName, eventUrl |
| League and season | sport, league, leagueName, seasonYear, seasonType |
| Schedule and status | startTime, status, statusDetail |
| Venue | venueName, venueCity |
| Teams | home/away ESPN ID, display name, and abbreviation |
| Provider | provider, details |
| Headline lines | spread, overUnder, favorite flags |
| Moneyline | home/away opening and current American odds |
| Spread | home/away opening/current line and price |
| Total | over/under opening/current line and price |
| Movement | hasLineMovement |
| Provenance | apiUrl, scrapedAt |
Nullable values remain null. The Actor does not invent prices when ESPN omits a market.
How to scrape ESPN sports odds
- Open the Actor in Apify Console.
- Select one or more leagues.
- Optionally enter a start and end date.
- Choose the maximum number of records.
- Click Start.
- Open the Dataset tab to inspect or export results.
If dates are omitted, the Actor scans today through 30 days ahead. Date ranges can cover at most 60 days.
Input parameters
leagues
An array containing one or more of nfl, nba, mlb, and epl.
Default: all four supported leagues.
startDate
Optional first event date in YYYY-MM-DD format.
Default: today in UTC.
endDate
Optional final event date in YYYY-MM-DD format.
Default: 30 days after the effective start date.
The end date must not precede the start date and the range cannot exceed 60 days.
maxItems
Maximum event/provider odds records written to the dataset.
Default: 250.
Allowed range: 1 to 5000.
Example input
{"leagues": ["mlb", "epl"],"startDate": "2026-08-07","endDate": "2026-08-31","maxItems": 100}
For a small recurring snapshot, narrow the date range and league list instead of fetching events you will discard downstream.
Example output
{"source": "ESPN","sport": "baseball","league": "mlb","leagueName": "MLB","eventId": "401816428","eventName": "New York Mets at Pittsburgh Pirates","startTime": "2026-08-07T22:40Z","status": "STATUS_SCHEDULED","venueName": "PNC Park","homeTeamName": "Pittsburgh Pirates","awayTeamName": "New York Mets","provider": "DraftKings","details": "PIT -145","overUnder": 8,"spread": -1.5,"moneylineHomeOpen": "-149","moneylineHomeCurrent": "-145","moneylineAwayOpen": "+123","moneylineAwayCurrent": "+120","spreadHomeOpen": "-1.5","spreadHomeCurrent": "-1.5","totalOverLineOpen": "o8","totalOverLineCurrent": "o8","hasLineMovement": true,"eventUrl": "https://www.espn.com/mlb/game/_/gameId/401816428","scrapedAt": "2026-08-07T12:00:00.000Z"}
The schema contains the complete opening/current fields for both sides of moneyline, spread, and total markets.
How line movement is represented
ESPN's nested odds payload can expose open and close values. This Actor names close fields as Current because they represent the latest value available at extraction time for scheduled events.
hasLineMovement is true when at least one comparable opening/current line or price differs.
It does not calculate implied probability, vigorish, or movement direction. Keep the raw American-odds strings for exact source fidelity and perform domain-specific calculations downstream.
When an opening value is unavailable, its field is null and it does not independently trigger the movement flag.
How much does it cost to extract ESPN sports odds?
Pricing uses one start event per run plus one item event per saved odds record.
The current start price is $0.003 per run. On the BRONZE tier, each saved item is $0.0024; other Apify plan tiers use the live discounted curve shown in Console.
Approximate BRONZE examples:
| Saved records | Estimated Actor charge |
|---|---|
| 1 | $0.0054 |
| 10 | $0.027 |
| 25 | $0.063 |
| 100 | $0.243 |
Events without odds, rejected rows, and duplicate event/provider records are not charged as items. Apify displays the authoritative charge estimate for your plan before and after each run.
Schedule odds snapshots
Create an Apify Schedule for a repeatable movement dataset:
- Save an input with the leagues and date horizon you monitor.
- Run hourly, daily, or at another cadence appropriate for your analysis.
- Send each run's dataset to a database or webhook target.
- Match snapshots by
league,eventId, andprovider. - Compare
scrapedAtand current market fields over time.
The Actor returns current source state; it does not retain history between runs. Your scheduled datasets or downstream store provide the history.
Export to CSV, Excel, or a data pipeline
The default Apify dataset supports JSON, JSONL, CSV, XML, RSS, and Excel exports.
Useful pipeline keys are:
eventIdfor ESPN event joins;startTimefor time windows;leaguefor partitioning;providerfor event/provider uniqueness;scrapedAtfor snapshot ordering.
Use the Overview view for human review and the full dataset API when you need every opening/current field.
Run with the Apify API
Replace YOUR_TOKEN with an Apify API token.
cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~espn-multi-league-odds-scraper/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"leagues":["nfl"],"maxItems":50}'
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/espn-multi-league-odds-scraper').call({leagues: ['mlb', 'epl'],maxItems: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientclient = ApifyClient(token="YOUR_TOKEN")run = client.actor("automation-lab/espn-multi-league-odds-scraper").call(run_input={"leagues": ["mlb"], "maxItems": 50})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
Use with MCP and AI agents
Claude Code
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/espn-multi-league-odds-scraper"
Claude Desktop
Add this server object to the Claude Desktop MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/espn-multi-league-odds-scraper"}}}
Cursor
Open Settings → Tools & MCP → Add custom MCP and use the same Apify MCP URL shown above.
VS Code
Add the same HTTP MCP server URL through your MCP-compatible VS Code extension or workspace MCP configuration.
Example prompts:
- "Collect upcoming ESPN MLB odds and return the current moneylines as a table."
- "Run the ESPN odds Actor for NFL and identify records where opening and current fields differ."
- "Export the next 30 days of English Premier League ESPN odds for my data pipeline."
Reliability and retries
The Actor uses ESPN's public structured scoreboard data instead of rendering web pages.
Each league request has a 30-second timeout and up to three bounded attempts for transient failures.
Deterministic client errors are surfaced as failed runs instead of silently returning fabricated or partial values.
A successful zero-item run is possible when:
- the league is between seasons;
- the selected dates contain no events;
- ESPN has events but has not posted odds;
- posted odds were removed or unavailable in the selected region.
Try a currently active league or a wider upcoming range before treating zero output as an error.
Limits and data freshness
- Coverage is limited to NFL, NBA, MLB, and English Premier League scoreboard data.
- The feed reflects what ESPN exposes at run time; it is not a bookmaker guarantee.
- ESPN may expose one provider rather than a full multi-book comparison.
- Historical snapshots are not reconstructed.
- The Actor does not place bets or access betting accounts.
- Postponed, cancelled, or rescheduled events follow ESPN's status and timing.
- A 60-day maximum keeps each run bounded and predictable.
Legality
ESPN names, event data, and odds may be protected by terms, database rights, or other applicable rules. Use the Actor only for lawful purposes and review ESPN's terms and the rules that apply in your jurisdiction.
Betting regulations vary by location. This Actor provides data extraction, not betting advice, wagering services, or a representation that any market is available to you.
Avoid republishing data in a way that violates source rights. Do not use the output to target vulnerable people or evade local restrictions.
Troubleshooting
Why did the run return no records?
Check that the league is in season and that ESPN has posted odds for the selected event dates. MLB is usually a useful in-season smoke test; NBA may be empty during the off-season.
Why are some fields null?
ESPN does not expose every market for every event. Nulls preserve missing source values rather than replacing them with zero or inferred prices.
Why did my input fail before fetching?
Use exact YYYY-MM-DD dates, keep the end date on or after the start date, limit the range to 60 days, and set maxItems from 1 to 5000.
Can I request a team instead of a league?
Not currently. Filter the normalized dataset by team ID, name, or abbreviation after extraction.
Related Automation Lab Actors
- Covers Sports Odds and Consensus Scraper for Covers-specific odds and consensus signals.
- FanDuel Sportsbook Odds Scraper for sportsbook-specific FanDuel coverage.
- ESPN News Scraper for league news and article metadata that can complement odds monitoring.
Choose this Actor when you need a compact ESPN event/provider odds record with explicit opening/current fields across supported leagues.
FAQ
Does the Actor need a proxy?
No. The current implementation uses a public ESPN JSON surface directly and does not enable an automatic proxy or browser fallback.
Are the values live in-play odds?
The Actor returns the latest values present in ESPN's scoreboard response at extraction time. It does not promise tick-level or in-play market streaming.
Does it return all sportsbooks?
It returns each provider object ESPN includes for an event. In current responses, ESPN often exposes a single provider.
How do I detect changes between scheduled runs?
Store each dataset, join records on league, eventId, and provider, then compare the current market fields and scrapedAt. The per-record hasLineMovement flag compares ESPN's available opening/current values within a single snapshot.
Can I increase the limit?
Yes, up to 5000 records. Increase the date range only when you need that scope; narrower snapshots are faster and easier to compare.