ESPN Scraper: Scores, Standings, Stats, Odds
Pricing
from $0.80 / 1,000 games
ESPN Scraper: Scores, Standings, Stats, Odds
Scrape ESPN for game scores, fixtures, standings, team rosters, box scores, league news and the posted betting line, across the NFL, NBA, MLB, NHL, college sports and 350 more leagues with no API key. Rows carry teams, score, status, venue, broadcast and ids. JSON, CSV, Excel or API, billed per row.
Pricing
from $0.80 / 1,000 games
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
ESPN Scraper: Scores, Standings, Stats, Odds
This ESPN scraper turns ESPN's public sports data into clean rows: scores and fixtures, standings tables, team directories, rosters, box scores, league news and the betting line ESPN posts before a game. No API key, no login, no browser. 44 leagues sit in the dropdown and all 356 leagues ESPN publishes are reachable by code, from the NFL and the NBA to Serie A, the Copa Libertadores, the UFC, Formula 1 and NCAA basketball.
You pay for the rows you receive. Name a memory and a scheduled run pays for a game once, then only pays again if the score or the line actually moved.
Quick start
- Click Try for free.
- Choose What to scrape: scores, odds, standings, teams, rosters, box scores or news.
- Pick your Leagues from the dropdown, or type any ESPN league code (
ger.2,usa.nwsl) into Other leagues. - For scores, odds and box scores, set the date window: Days back and Days ahead, or an explicit Date from and Date to.
- Set Maximum rows while you are experimenting, then click Start. Results appear in the dataset and export as JSON, CSV, Excel or XML, or come back through the API.
What you get
Scores and fixtures (one row per game)
| Field | What it is | Fill rate |
|---|---|---|
gameId | ESPN's event id, always a string | 100% |
date | Start time, ISO 8601 UTC | 100% |
name, shortName | Matchup as ESPN prints it | 100% |
state, status | pre, in or post, plus the readable status such as Final | 100% |
homeTeam, awayTeam, homeScore, awayScore | Teams and score (team sports) | 100% |
participants | Everyone in the competition with score, order and winner flag (how MMA, golf and racing arrive) | 100% |
homeRecord, awayRecord | Season record as shown on the card | 99.1% |
venueName, venueCity | Stadium and city | 99.3% |
broadcast | Networks and streams carrying the game | 99.9% |
attendance | Crowd, once the game is played | 80.9% |
leaders | Top performer per statistic category | 84.6% |
home.linescores, away.linescores | Period by period scores | 76.6% |
oddsDetails, oddsSpread, oddsOverUnder, oddsHomeMoneyline, oddsAwayMoneyline | The line ESPN posts | see below |
gameUrl | Link to the game on espn.com | 100% |
Fill rates measured over 1,081 live events across the NFL, NBA, MLB, NHL, Premier League, college football, MLS and the WNBA on 2026-09-15.
Odds
Odds mode returns one row per bookmaker line, with the matchup, kick-off time, provider, spread, overUnder,
both money lines and which side is the favourite. ESPN posts a single provider's line, close to kick-off, and
drops it from most games once they are final. Measured on 2026-09-15 over a ten day forward window: NFL 17 of 17
upcoming games carried a line, Premier League 10 of 10, LaLiga 15 of 15, college football 28 of 30, MLS 15 of 16,
MLB 15 of 130, and a league that was out of season carried none. Across all completed games in the fill-rate
sample, only 1.4 percent still had a line attached.
Standings, teams, rosters and news
- Standings: one row per team per group, with
position,wins,losses,ties,points,pointsFor,pointsAgainst,gamesBehind,streakand astatsobject holding every number ESPN publishes for that league. - Teams: the league directory, with team id, abbreviation, location, colours, logo and the clubhouse link.
- Rosters: every player with jersey number, position, age, height, weight, birthplace, college, experience and injury status. NFL rosters also carry the position group (offense, defense, special teams).
- News: league headlines with byline, publish time, the teams and athletes mentioned, and the article link.
Box scores
One row per game with team totals, both line scores, venue, attendance, officials and, unless you turn them off, every player stat line from the box score. Give it game ids, pasted ESPN game URLs, or a date window and let it find the games itself; the games it reads to find them are not charged.
Leagues covered
44 leagues in the dropdown: NFL, NCAA football, CFL, UFL, NBA, WNBA, NCAA men's and women's basketball, MLB, NCAA baseball, NHL, NCAA men's hockey, 22 soccer competitions including the Premier League, LaLiga, Bundesliga, Serie A, Ligue 1, Eredivisie, Liga MX, MLS, NWSL, the Champions League and both World Cups, plus the UFC, Bellator, PGA, LPGA, Formula 1, NASCAR, ATP, WTA, the AFL and the Premier Lacrosse League. Any of ESPN's other published leagues works as free text: 356 across 17 sports.
Team sports have teams, standings and rosters. Individual sports have no team data on ESPN, so they behave
differently: an MMA card, a golf tournament, a race session or a tennis event returns one row per competition with
a participants list (fighter, golfer or driver, with score, finishing order and winner flag) instead of home and
away columns. ESPN's tennis scoreboard is tournament level, so tennis returns the event, not individual matches.
How much does it cost to scrape ESPN?
Pay per event, in US dollars:
| Event | What triggers it | Price |
|---|---|---|
| Game (primary) | One delivered game or odds row | $0.001 per row, $1.00 per 1,000 |
| Record | One delivered standings, team, roster or news row | $0.001 per row, $1.00 per 1,000 |
| Box score | One delivered box score for a single game | $0.003 per row, $3.00 per 1,000 |
| Actor start | Apify's standard per-run start fee, per gigabyte of memory | $0.00005 per run |
Store discounts apply to the result events: Silver pays 10 percent less and Gold 20 percent less than the prices above. The Actor start event carries no discount.
Worked example: 1,000 Premier League fixtures with scores, venue and the posted line cost $1.00 plus $0.00005 for the run start. The same scheduled run a day later, using the same memory name, pays only for the games whose score or line changed.
Nothing else is charged. Rows your memory has already delivered unchanged are free, the run summary and status rows are free, the requests used only to discover game ids or team ids are free, and a run that finds no data charges no result events at all.
Input
| Field | Meaning |
|---|---|
dataType | scores, odds, standings, teams, rosters, boxscores or news |
leagues | League codes from the dropdown, such as football/nfl or soccer/eng.1 |
customLeagues | Any other ESPN league: a code (ger.2), an abbreviation (epl, ucl, nascar) or a pasted ESPN URL |
lastNDays, nextNDays | Date window around today for scores, odds and box scores |
dateFrom, dateTo | Explicit window as YYYY-MM-DD, overriding the days settings |
gameState | any, scheduled, in-progress or final |
teamIds | Team ids or abbreviations: filters games, or picks which rosters to fetch |
eventIds | Game ids or pasted game URLs for box scores |
groups | College conference or division id, for example 80 for FBS |
season | Season year for standings |
maxItems | Hard cap on delivered rows, shared fairly across the leagues you picked |
includePlayerStats | Keep or drop the player lines inside box scores |
includeRawJson | Attach ESPN's untouched event object to each game row |
dedupMemoryName | Name a cross-run memory so repeat runs pay only for new or changed rows |
resetDedupMemory, emitDuplicates | Clear the memory, or return unchanged rows free of charge |
maxRequestsPerSecond, proxyConfiguration | Pace and network settings; the defaults work |
A run with an empty input {} returns the last day and the next day of NFL, NBA, MLB and Premier League games.
That default has no row cap: it delivers and charges for every game in that three day window (yesterday,
today and tomorrow), which is a few dozen rows in season. Set maxItems if you want a hard ceiling. If you set only customLeagues, only those leagues are
scraped, and if none of the leagues, teams or game ids you give can be read the run delivers nothing and charges
nothing rather than widening the scope.
Honest limits
News returns the latest 50 articles per league, and the team directory and rosters are a single page each: ESPN
does not paginate those feeds. ESPN serves at most 1,000 events in one scoreboard page. A window longer than a week is read one month per
request, and if a month comes back at that cap the Actor re-reads it day by day so nothing is lost; any page that
still hits the cap is listed in truncatedPages in the run summary and called out in a free status row. The run
summary also reports every request made, every league's row count, the fill rates of the run and any warning.
What this Actor does NOT do
- No play by play, drive charts, win probability, injury reports or fantasy projections.
- No bookmaker comparison and no arbitrage: ESPN publishes one provider's line per game, and only for part of the schedule. This is a sports data product; the odds fields are one part of a game row, not betting advice.
- No team, standings or roster data for individual sports such as MMA, golf and tennis, because ESPN has none.
- No data from before a league existed, and no seasons ESPN no longer serves on its public scoreboard.
- No match-level tennis: ESPN's tennis scoreboard is tournament level, so that is what you get.
- No results for a league code ESPN does not recognise. If every league you name is unusable the run delivers nothing and charges nothing, rather than quietly scraping something else.
- No login, no cookies, no personal ESPN Fantasy data.
API examples
Run the Actor and wait for the dataset, with your token from the Apify Console.
curl -X POST "https://api.apify.com/v2/acts/automation_craft~espn-sports-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"dataType":"scores","leagues":["football/nfl"],"lastNDays":1,"nextNDays":7,"maxItems":50}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation_craft/espn-sports-scraper').call({dataType: 'standings',leagues: ['soccer/eng.1'],});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((i) => i.dataType === 'standing'));
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("automation_craft/espn-sports-scraper").call(run_input={"dataType": "odds","leagues": ["football/nfl"],"nextNDays": 7,"gameState": "scheduled",})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item.get("name"), item.get("spread"), item.get("overUnder"))
FAQ
Is the ESPN API free, and do I need an API key?
ESPN publishes these JSON endpoints for its own site and does not sell keys or document them, so there is nothing to sign up for and no key to paste. This Actor calls those public endpoints politely, at a rate you control, and turns the responses into flat rows.
Which sports and leagues can I scrape?
17 sports and 356 leagues, of which 44 are in the dropdown. Team sports return scores, odds, standings, teams, rosters, box scores and news; individual sports such as MMA, golf and tennis return scores and news only.
Does it include betting odds?
Yes, as data. Every game row carries the spread, over under and money lines that ESPN posts, and odds mode gives
one row per bookmaker line. ESPN shows one provider's line and posts it close to kick-off, so upcoming games in
the current week are well covered while completed games mostly are not. It is not a bookmaker comparison and it is
not betting advice.
How far back can I pull scores?
As far back as ESPN's public scoreboard serves for that league, which for the major US leagues and the big soccer competitions is many seasons. Windows longer than a week are read one month per request, so a full season is a few dozen requests rather than hundreds.
How do I get a full box score for one game?
Set What to scrape to box scores and paste the game id or the ESPN game URL into Game ids. You get team totals, both line scores, venue, attendance, officials and every player stat line. Leave the ids empty and the Actor takes the games from your date window instead.
Can two schedules share one memory name?
Run one schedule at a time per memory name. The memory is a key-value store the Actor reads when a run starts and writes at each checkpoint and at the end, merging in whatever another run saved meanwhile. That merge reduces lost updates but cannot remove them: two runs sharing one name can both see the same game as new and both charge for it. Give each schedule its own name and they never collide.
Do I pay for a run that returns nothing?
No result events are charged when nothing is delivered, and rows your memory has already seen unchanged are free. Apify's standard Actor start fee of $0.00005 per run applies to every run of every Actor on the platform.
Why does this Actor run with limited permissions?
Least privilege. It only reads and writes its own storages on your account, nothing else. The cross-run memory is a named key-value store the Actor creates itself on its first run, so limited permissions are enough for it.
Changelog
- 0.1 First release: seven data types, 356 leagues, cross-run memory, pay per delivered row.