ESPN Sports Odds Scraper avatar

ESPN Sports Odds Scraper

Pricing

Pay per event

Go to Apify Store
ESPN Sports Odds Scraper

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

Stas Persiianenko

Maintained by Community

Actor 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 valueLeagueESPN sport path
nflNational Football Leaguefootball
nbaNational Basketball Associationbasketball
mlbMajor League Baseballbaseball
eplEnglish Premier Leaguesoccer

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 groupExamples
Event identityeventId, eventName, shortName, eventUrl
League and seasonsport, league, leagueName, seasonYear, seasonType
Schedule and statusstartTime, status, statusDetail
VenuevenueName, venueCity
Teamshome/away ESPN ID, display name, and abbreviation
Providerprovider, details
Headline linesspread, overUnder, favorite flags
Moneylinehome/away opening and current American odds
Spreadhome/away opening/current line and price
Totalover/under opening/current line and price
MovementhasLineMovement
ProvenanceapiUrl, scrapedAt

Nullable values remain null. The Actor does not invent prices when ESPN omits a market.

How to scrape ESPN sports odds

  1. Open the Actor in Apify Console.
  2. Select one or more leagues.
  3. Optionally enter a start and end date.
  4. Choose the maximum number of records.
  5. Click Start.
  6. 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 recordsEstimated 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:

  1. Save an input with the leagues and date horizon you monitor.
  2. Run hourly, daily, or at another cadence appropriate for your analysis.
  3. Send each run's dataset to a database or webhook target.
  4. Match snapshots by league, eventId, and provider.
  5. Compare scrapedAt and 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:

  • eventId for ESPN event joins;
  • startTime for time windows;
  • league for partitioning;
  • provider for event/provider uniqueness;
  • scrapedAt for 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 ApifyClient
client = 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().items
print(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.

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.