ESPN Scraper — Live Sports Scores, Stats & Odds API | $1/1k avatar

ESPN Scraper — Live Sports Scores, Stats & Odds API | $1/1k

Pricing

from $0.80 / 1,000 results

Go to Apify Store
ESPN Scraper — Live Sports Scores, Stats & Odds API | $1/1k

ESPN Scraper — Live Sports Scores, Stats & Odds API | $1/1k

Scrape ESPN box scores and player stats, scores, fixtures, betting odds, teams and standings for the NFL, NBA, MLB, NHL and top soccer leagues. One row per player per game; odds and win probability for upcoming games. No API key needed. Export to CSV, JSON or Excel.

Pricing

from $0.80 / 1,000 results

Rating

0.0

(0)

Developer

Raffy

Raffy

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 hours ago

Last modified

Share

Get live scores, fixtures, box scores with player stats, team lists and league standings for the NFL, NBA, MLB, NHL and the major soccer leagues as clean structured rows — no API key, no browser, no scraper to maintain. It is the quickest way to put an NFL scores API behind your app, NBA player stats into a fantasy model, a full NBA standings feed into a dashboard, or a season of Premier League results into a spreadsheet.

This Actor reads the same public JSON endpoints that espn.com's own web app calls and turns them into one flat row per game, per player per game, per team or per standings entry. Pick a league and a resource, press start, and the rows land in a dataset you can download as JSON, CSV or Excel, or pull straight from the Apify API. Fifteen leagues share one schema, and every row carries a stable teamId, so scores, teams and standings join without fuzzy name matching.

HTTP only. No headless browser, so runs finish in seconds and cost very little platform time — the default run does 24 requests in about 7 seconds.

What does this ESPN sports scraper do?

Each row is one event (a game or fixture), one player's box-score line in one game, one team's box-score totals, one team, or one standings entry. The resource field says which, so a dataset that mixes them stays readable.

  • Five sports, fifteen leagues, one schema. NFL, NBA, MLB, NHL, WNBA, NCAA football and basketball, plus the Premier League, LaLiga, Serie A, Bundesliga, Ligue 1, Champions League, Europa League and MLS. Any other ESPN league works too — paste its endpoint into the URL list.
  • Scores and fixtures. A scoreboard call returns a whole day or an entire calendar year in one request (a date range is fetched day by day), with status, live or final scores, venue, broadcaster and attendance.
  • Box scores and player stats. Pick boxscores and a date (or paste game ids) to get one row per player per finished game — points, rebounds and assists in the NBA; passing, rushing and receiving in the NFL; batting and pitching in MLB; skaters and goalies in the NHL; goals, shots and cards in soccer — with starter, position, team and opponent. teamstats gives each team's totals for the game instead.
  • Betting odds for upcoming games. Where ESPN shows a line (NFL, NBA, MLB, college), each upcoming game carries the sportsbook's spread, over/under and moneyline, current and opening, as plain numbers.
  • Win probability (optional). Switch on winProbability and upcoming games also get ESPN's pre-game win probability for each side, where ESPN publishes one.
  • Standings data. Wins, losses, ties, win percentage, table points, points for and against, games behind, rank and playoff seed for each team in the table.
  • Enriched team rows. Each team is followed up with one extra call, so you get its division, current record and home venue, not just its name.
  • Honest rows. Every row says whether it is real data (ok), a request ESPN had nothing for (not_found) or a request that failed (error). You are only billed for ok.

Result status (tri-state output)

statusMeaningBilled
okData was extracted.Yes
not_foundESPN answered, but there is nothing to report — a day with no games (for box scores: no finished games), a game that has not been played yet, a season with no table.No
errorThe endpoint could not be read after retries (network error, HTTP error, unexpected format), or an input entry was not an ESPN URL. error says why.No

Use cases for ESPN scores, box scores and standings data

  • Sports apps and score widgets. A developer schedules a scoreboard run every 10-15 minutes and renders homeTeam, awayTeam, homeScore, awayScore and eventStatus as a live scoreboard, without paying for a commercial feed or maintaining a scraper.
  • Fantasy league tools. A fantasy platform pulls the weekly fixture list with week and startDate, locks rosters against the real kick-off times, and after the games scores every lineup from the boxscores rows — passingYards, rushingTouchdowns and receptions, or points, rebounds and assists, per athleteId.
  • Player stats databases. An analyst runs boxscores over a season's dates and gets a game log per player (one row per player per game, keyed by athleteId and eventId) to compute averages, streaks and splits.
  • Betting and forecasting models. A quant pulls a whole season of resource: events history plus standings (wins, losses, pointsFor, pointsAgainst, streak) to build the features a win-probability or totals model needs.
  • Media and newsroom dashboards. A sports desk keeps a live table of every league it covers, so an editor sees the current rank and record of any team without opening fifteen browser tabs.
  • Analytics and BI reporting. An analyst loads standings and results into BigQuery or a spreadsheet each morning to track a club's form, attendance and home-away splits over a season.
  • AI agents and chatbots. An assistant answering "who won last night?" calls the Actor for one date, gets flat JSON with an explicit status, and can tell "no games today" apart from "the request failed" without guessing.

What data you get from every row

Fields that do not apply to a row are simply absent — never filled with a placeholder or a zero.

Every row

FieldTypeDescription
urlstringLink to the ESPN page for this row: the game page for an event, the team page for a team or standings row.
statusstringok, not_found or error — see the table above.
errorstringWhy a not_found or error row looks the way it does. Absent on ok rows.
scrapedAtstringISO 8601 timestamp of extraction.
resourcestringevents, boxscores, teamstats, teams or standings.
leaguestringLeague slug as ESPN uses it: nfl, nba, mlb, nhl, eng.1, uefa.champions, ...
leagueNamestringHuman-readable league name, e.g. National Football League.
seasonintegerSeason year as ESPN labels it. A 2025-26 European season is season 2025.

Scores and fixtures (resource: events)

FieldTypeDescription
eventIdstringESPN event (game) id.
eventNamestringFull event name, e.g. New Orleans Saints at Atlanta Falcons.
shortNamestringShort event name, e.g. NO @ ATL.
weekintegerWeek number (NFL, college football) or matchday, when the league publishes one.
startDatestringKick-off / first pitch, ISO 8601 UTC.
eventStatusstringscheduled, in progress, final, postponed, canceled, delayed or other.
statusDetailstringESPN's own wording, e.g. Final, Full Time, 9/9 - 8:20 PM EDT.
homeTeamstringHome team display name.
homeTeamIdstringESPN id of the home team — the join key to team and standings rows.
homeAbbreviationstringHome team abbreviation, e.g. ATL.
homeScorenumberHome score. Absent while the event is still scheduled, so an unplayed game is never reported as 0-0.
awayTeamstringAway team display name.
awayTeamIdstringESPN id of the away team.
awayAbbreviationstringAway team abbreviation, e.g. NO.
awayScorenumberAway score. Absent while the event is still scheduled.
broadcaststringBroadcaster(s) ESPN lists for the event, comma separated.
attendanceintegerReported attendance, when published.
oddsProviderstringSportsbook whose lines ESPN shows, e.g. DraftKings. Upcoming games only.
oddsDetailsstringESPN's one-line summary of the line, e.g. LAR -6.5.
favoritestringWhich side the sportsbook favours: home or away.
homeSpread, awaySpreadnumberPoint spread for each side (run line in MLB, puck line in NHL).
homeSpreadOdds, awaySpreadOddsnumberAmerican odds on each spread.
overUndernumberTotal points, runs or goals line.
overOdds, underOddsnumberAmerican odds on the over and the under.
homeMoneyline, awayMoneylinenumberMoneyline, American odds, current line (e.g. -298, 240).
homeMoneylineOpen, awayMoneylineOpennumberMoneyline when the line opened, so you can see how it moved.
homeWinProbability, awayWinProbabilitynumberESPN's pre-game win probability for each side, in percent (e.g. 74.8). Only with winProbability on, for upcoming games where ESPN publishes a prediction.
tieProbabilitynumberChance of a tie in percent, where ESPN publishes one.
winProbabilityErrorstringPresent only when the optional win-probability call failed; the event row is kept without it.

Box scores and player stats (resource: boxscores)

One row per player per finished game. Where ESPN splits a box score into stat groups (NFL: passing, rushing, receiving, defensive, ...; MLB: batting and pitching; NHL: forwards, defenses and goalies), a player gets one row per group he appears in — a quarterback who also ran has a passing row and a rushing row.

FieldTypeDescription
eventIdstringESPN event (game) id — the join key to the event row of the same game.
gameDatestringGame start, ISO 8601 UTC.
teamIdstringESPN id of the player's team.
teamstringTeam display name, e.g. Oklahoma City Thunder.
teamAbbreviationstringTeam abbreviation, e.g. OKC.
homeAwaystringhome or away.
opponentIdstringESPN id of the opponent.
opponentstringOpponent display name.
opponentAbbreviationstringOpponent abbreviation.
athleteIdstringESPN athlete id — stable across games, use it to build a game log.
playerNamestringPlayer name as ESPN prints it.
positionstringPosition in the box score, e.g. G, LW, DH (MLB game position), SUB (soccer substitute).
jerseystringJersey number, where listed.
starterbooleantrue for starters, where ESPN says so (basketball, MLB, soccer).
didNotPlaybooleantrue when the player was listed but did not play (DNP, scratched, unused substitute); stats is then empty. The reason is never copied.
statGroupstringESPN's stat group: passing, rushing, receiving, defensive, kicking, ... (NFL), batting, pitching (MLB), forwards, defenses, goalies (NHL), players (basketball, soccer).
statsobjectThe stat line keyed by ESPN's stat names, e.g. points, rebounds, passingYards, strikeouts, saves. Clean numbers are numbers. Made-attempted pairs keep ESPN's text ("fieldGoalsMade-fieldGoalsAttempted": "8-27") and are also split into two numbers (fieldGoalsMade: 8, fieldGoalsAttempted: 27). Clock times stay text ("timeOnIce": "15:58"). In CSV and Excel exports every stat becomes its own column, e.g. stats/points.
minutes, points, rebounds, assistsnumberBasketball rows: typed copies of the headline stats, so a table sorts on them without opening stats.
goals, assistsnumberHockey and soccer rows: goals and assists.

Team stats per game (resource: teamstats)

One row per team per finished game with the team totals ESPN prints under the box score (MLB: one row each for batting, pitching and fielding). Carries eventId, gameDate, teamId, team, teamAbbreviation, homeAway, opponentId, opponent, opponentAbbreviation, statGroup (team, or the MLB group) and stats as above, plus:

FieldTypeDescription
teamScorenumberThe team's final score.
opponentScorenumberThe opponent's final score.

Teams (resource: teams)

FieldTypeDescription
teamIdstringESPN team id; the same id links events, teams and standings rows.
namestringTeam display name, e.g. Atlanta Falcons.
abbreviationstringTeam abbreviation, e.g. ATL.
locationstringTeam location or market, e.g. Atlanta.
logoUrlstringTeam logo (PNG) URL.
conferencestringConference or top-level standings group, e.g. American Football Conference.
divisionstringDivision or standings group, e.g. NFC South, League Phase.
recordstringWin-loss record as ESPN prints it, e.g. 14-3 or 26-7-5.
detailErrorstringPresent only when the optional per-team detail call failed; the row is kept without those extra fields.

Venue (events, and the home venue on team rows)

FieldTypeDescription
venuestringVenue name: the stadium of the event, or the team's home ground.
citystringVenue city.
statestringVenue state or region, where ESPN publishes one.
countrystringVenue country.

Standings (resource: standings)

Standings rows also carry teamId, name, abbreviation, location, logoUrl, conference, division and record from the table above.

FieldTypeDescription
rankintegerPosition inside the standings group, 1 = top of that table.
playoffSeedintegerPlayoff seed, for the leagues that publish one.
winsnumberWins in the standings row.
lossesnumberLosses in the standings row.
tiesnumberTies or draws in the standings row.
winPercentnumberWin percentage as ESPN publishes it (0-1).
pointsnumberTable points, for soccer and hockey standings. (On a basketball box-score row: the player's points.)
pointsFornumberPoints, goals or runs scored.
pointsAgainstnumberPoints, goals or runs conceded.
gamesBehindnumberGames behind the group leader.
gamesPlayednumberGames played.
streaknumberCurrent streak as a signed number: 3 = three wins, -2 = two losses.

How to scrape ESPN scores, box scores, teams and standings

  1. Click Try for free (or open the Actor from your Apify console).
  2. Choose a Resource (scoreboard, boxscores, teamstats, teams or standings) and a League. That is enough for most runs; for box scores also set a Date, or paste game ids into Event IDs.
  3. Optionally paste ESPN API URLs instead — the URL list wins over the Resource/League fields when it is not empty.
  4. Set Maximum results to cap both the dataset size and your spend.
  5. Click Start. The default input finishes in about 7 seconds; a season-wide scoreboard with 500 rows takes well under a minute.
  6. Download the dataset as JSON, CSV, Excel or XML, or read it from the Apify API. You can also schedule the Actor to run every hour or every morning.

What you can paste into "ESPN API URLs"

You pasteThe Actor fetches
https://site.web.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard?dates=20260104that endpoint, unchanged
https://site.api.espn.com/...the same path on site.web.api.espn.com, which answers every client
https://www.espn.com/nba/standingsthe NBA standings endpoint
https://www.espn.com/soccer/table/_/league/esp.1the LaLiga standings endpoint
https://www.espn.com/nba/boxscore/_/gameId/401766128 (or any espn.com game page)that game's box score
401766128 (a bare ESPN event id)that game's box score, for the league you selected
nfl, epl, champions-leaguethat league, for the resource you selected
anything that is not an ESPN URLnothing — one free error row explains it was skipped

Input

FieldTypeDefaultWhen to change it
startUrlsarray of stringsone NFL teams URL: https://site.web.api.espn.com/apis/site/v2/sports/football/nfl/teams?limit=1000Paste ESPN endpoints, espn.com pages or bare league slugs when you want an exact endpoint or a league that is not in the dropdown. Clear the list to let resource + league build the URL for you.
resourceselectteamsteams for a league's team list, scoreboard for games and fixtures, boxscores for one row per player per finished game, teamstats for each team's totals per finished game, standings for the league table. Used when the URL list is empty or still holds only the built-in example URL.
leagueselectnflPick the league you want: nfl, nba, mlb, nhl, wnba, college-football, mens-college-basketball, eng.1, esp.1, ita.1, ger.1, fra.1, uefa.champions, uefa.europa, usa.1.
datestringemptyScoreboard, box scores and team stats. Set YYYYMMDD for one day, YYYYMMDD-YYYYMMDD for a range, or YYYY for a whole year of fixtures. Empty means the current calendar year, which always contains games. For box scores, set the days you want: every finished game in them is one extra request.
seasonintegeremptySet it to pull a past season, e.g. 2025. Standings read it as ESPN's season year; the scoreboard uses it as the calendar year when no date is given.
eventIdsarray of stringsemptyESPN game ids (the number after gameId/ in an espn.com game URL), or espn.com game page URLs. Each is read as that game's box score for the selected league (team totals when resource is teamstats); date is then not used for them.
winProbabilitybooleanfalseScoreboard only. Adds homeWinProbability / awayWinProbability to upcoming games where ESPN publishes a prediction (today the NFL, college football and MLB). One extra request per upcoming game; no extra rows, no extra charge.
maxItemsinteger20Raise it for a full league or a season history — this is also your spending cap, since each ok row is one billable result.
proxyConfigurationobjectoffLeave off; these endpoints answer datacenter IPs directly. Enable Apify Proxy (datacenter group) only if your runs start getting blocked.
{
"startUrls": [],
"resource": "standings",
"league": "eng.1",
"season": 2025,
"maxItems": 20,
"proxyConfiguration": { "useApifyProxy": false }
}

Box scores of the 2025 NBA Finals, one row per player per game (Game 7 alone is 30 rows; days without a game are free not_found rows):

{
"resource": "boxscores",
"league": "nba",
"date": "20250605-20250622",
"maxItems": 300
}

Box scores of specific games, by ESPN game id:

{
"resource": "boxscores",
"league": "nfl",
"eventIds": ["401772830", "401772829"],
"maxItems": 200
}

Why the default input is a team list, not today's scoreboard

A scoreboard for one specific day returns nothing when nobody plays that day — off days, off seasons, international breaks. A default like that would produce an empty dataset on a random Tuesday. The prefilled default therefore asks for the NFL team list, which is date-independent and returns 32 teams every day of the year. When you do run a scoreboard without a date, the Actor asks for the whole current calendar year for the same reason, so you always get fixtures back.

Output

One row per event, player box-score line, team or standings entry. Real rows from runs of this Actor:

[
{
"url": "https://www.espn.com/nfl/team/_/name/atl/atlanta-falcons",
"status": "ok",
"scrapedAt": "2026-09-08T12:57:56.180Z",
"resource": "teams",
"league": "nfl",
"leagueName": "National Football League",
"season": 2026,
"teamId": "1",
"name": "Atlanta Falcons",
"abbreviation": "ATL",
"location": "Atlanta",
"logoUrl": "https://a.espncdn.com/i/teamlogos/nfl/500/atl.png",
"division": "NFC South",
"record": "0-0",
"venue": "Mercedes-Benz Stadium",
"city": "Atlanta",
"state": "GA",
"country": "USA"
},
{
"url": "https://www.espn.com/soccer/match/_/gameId/740780/fulham-crystal-palace",
"status": "ok",
"scrapedAt": "2026-09-08T12:58:18.415Z",
"resource": "events",
"league": "eng.1",
"leagueName": "English Premier League",
"season": 2025,
"eventId": "740780",
"eventName": "Fulham at Crystal Palace",
"shortName": "FUL @ CRY",
"startDate": "2026-01-01T17:30:00.000Z",
"eventStatus": "final",
"statusDetail": "FT",
"homeTeam": "Crystal Palace",
"homeTeamId": "384",
"homeAbbreviation": "CRY",
"homeScore": 1,
"awayTeam": "Fulham",
"awayTeamId": "370",
"awayAbbreviation": "FUL",
"awayScore": 1,
"venue": "Selhurst Park",
"city": "London",
"country": "England",
"broadcast": "Peacock",
"attendance": 25111
},
{
"url": "https://www.espn.com/nba/boxscore/_/gameId/401766128",
"status": "ok",
"scrapedAt": "2026-09-26T22:51:53.271Z",
"resource": "boxscores",
"league": "nba",
"leagueName": "National Basketball Association",
"season": 2025,
"eventId": "401766128",
"gameDate": "2025-06-23T00:00:00.000Z",
"teamId": "25",
"team": "Oklahoma City Thunder",
"teamAbbreviation": "OKC",
"homeAway": "home",
"opponentId": "11",
"opponent": "Indiana Pacers",
"opponentAbbreviation": "IND",
"athleteId": "4278073",
"playerName": "Shai Gilgeous-Alexander",
"position": "G",
"jersey": "2",
"starter": true,
"didNotPlay": false,
"statGroup": "players",
"minutes": 40,
"points": 29,
"rebounds": 5,
"assists": 12,
"stats": {
"minutes": 40,
"points": 29,
"fieldGoalsMade-fieldGoalsAttempted": "8-27",
"fieldGoalsMade": 8,
"fieldGoalsAttempted": 27,
"threePointFieldGoalsMade-threePointFieldGoalsAttempted": "2-12",
"threePointFieldGoalsMade": 2,
"threePointFieldGoalsAttempted": 12,
"freeThrowsMade-freeThrowsAttempted": "11-12",
"freeThrowsMade": 11,
"freeThrowsAttempted": 12,
"rebounds": 5,
"assists": 12,
"turnovers": 1,
"steals": 1,
"blocks": 2,
"offensiveRebounds": 0,
"defensiveRebounds": 5,
"fouls": 5,
"plusMinus": 11
}
},
{
"url": "https://www.espn.com/nba/team/_/name/bos/boston-celtics",
"status": "ok",
"scrapedAt": "2026-09-08T13:05:26.529Z",
"resource": "standings",
"league": "nba",
"leagueName": "National Basketball Association",
"season": 2026,
"teamId": "2",
"name": "Boston Celtics",
"abbreviation": "BOS",
"conference": "Eastern Conference",
"division": "Atlantic",
"rank": 1,
"playoffSeed": 2,
"wins": 56,
"losses": 26,
"winPercent": 0.68292683,
"pointsFor": 9418,
"pointsAgainst": 8787,
"gamesBehind": 0,
"streak": 2
},
{
"url": "https://site.web.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard?dates=20260908",
"status": "not_found",
"error": "No results for this page",
"scrapedAt": "2026-09-08T13:07:11.902Z"
}
]

How much does it cost to scrape ESPN data?

This Actor uses pay per event pricing. You pay for the run start and for each saved result; platform compute is included.

EventPriceCharged when
Actor start$0.005Once per run (Apify charges one event per GB of memory, minimum one; the 1 GB default is one event).
Result$0.001Per record with status: ok saved to the dataset — one event, one player box-score line, one team-stats row, one team or one standings row.

That is $1 per 1,000 records plus half a cent per run. A box score is many records: an NBA game is about 25-30 player rows (about $0.03), an NFL game about 70 rows because each stat group is its own row (about $0.07); teamstats is 2 rows per game. Rows with status not_found or error are never charged: a scoreboard for a day with no games costs you nothing but the run start. The free Apify plan's $5 of monthly credit covers about 5,000 records in a single run. You can cap spending per run with Maximum results and with the run's Max total charge option.

How it compares

This Actor is a fast, cheap, no-key way to get the sports data that ESPN already publishes: scores, fixtures, teams and league tables, across fifteen leagues in a single schema. Because it is HTTP-only and one scoreboard call can return an entire season, a large pull is a handful of requests rather than thousands, and you are billed per row you keep rather than per month.

It is not a replacement for a commercial sports data feed. Box scores and player stats cover finished games only — there is no live in-game box score, no play-by-play, no season-to-date player totals, no rosters and no injury reports — and odds come from the one sportsbook ESPN shows, not a comparison across books. Latency is polling-based, so it suits a dashboard refreshed every few minutes rather than a live in-play betting screen. And the endpoints are unofficial, so a team that needs a contractual uptime guarantee should buy a licensed feed instead.

Integrations, API and AI agents

Results export to CSV, JSON, Excel and XML from the Apify console, or flow straight into Google Sheets, Airtable, Slack or a CRM through Apify integrations and webhooks — including Make, Zapier and n8n. Schedule a run every 10-15 minutes for live scores, or every morning for standings.

The Actor can be called from the Apify API, from any Apify client library, from the Apify MCP server, or by any AI agent that can call an HTTP endpoint. Every row carries a status column, so an agent can tell "no games today" apart from "the request failed".

Tips

  • One request, many rows. A scoreboard call returns a whole day or a whole year at once, so a 500-row season history costs one HTTP request, not 500.
  • Use date ranges. 20260101-20260131 gives you a month of fixtures (fetched one day at a time, so a day without games adds one free not_found row); 2026 gives the whole calendar year in a single call.
  • For odds, ask for the coming days. Odds exist only for games that have not started, so set date to today or a range starting today, e.g. 20260922-20260928.
  • Join on teamId. The same id appears on event rows (homeTeamId, awayTeamId), team rows, standings rows and box-score rows.
  • Box scores: choose the days. Every finished game in the date range is one extra request and 20-70 rows, so a week of NFL games is about 1,000 rows; set maxItems to match. Join box-score rows to games on eventId, and follow a player across games on athleteId.
  • Schedule it. For a live scoreboard, schedule a run every 10-15 minutes with date set to today and a small maxItems.
  • Watch eventStatus. Only rows with final are settled results; in progress scores change between runs.

Limitations

  • These endpoints are public but undocumented. ESPN does not publish or support them and can change or remove a field at any time; when that happens rows come back as error and the Actor is updated (report it in the Issues tab with the run ID).
  • Coverage varies by league. Divisions, table points, attendance, broadcast and week numbers only appear where ESPN publishes them — a soccer table has no week, an NBA table has no table points.
  • The scoreboard is date-dependent. A day or search with no games finishes successfully with a free not_found row; a run fails only when ESPN could not be read. Use a date range, a whole year, or the teams / standings resources when you need a guaranteed result.
  • College leagues are large. ESPN lists 700+ college football teams; raise maxItems accordingly, and expect one extra request per team row.
  • Team rows cost two requests each (list plus a detail call for record, division and venue). Box scores cost one request per finished game, which yields 20-70 rows; winProbability adds one request per upcoming game. Everything else is far cheaper than one request per row.
  • Box scores are for finished games only, one extra request per game, and a game that has not finished is a free not_found row. Stat names and groups are ESPN's own and differ by sport and league (see statGroup); soccer player stats come from the match lineups. There is no play-by-play, no live box score and no roster list. Odds appear only for upcoming games in leagues where ESPN prints a line (today NFL, NBA, MLB and college; not soccer or NHL), from one sportsbook, and they disappear once a game starts. sports.core.api.espn.com reference-style URLs are not accepted.
  • Results reflect what ESPN published at the time of the run.
  • eventName and shortName are built from homeTeam/awayTeam, not copied from ESPN's own event name. ESPN's own field doubles a team's name when its city and nickname are the same word (e.g. the Athletics, playing without a home city in 2025-26: ESPN prints "... at Athletics Athletics"); building the name from the two team fields, which are correct, avoids that and any similar ESPN template bug.

FAQ

Is it legal to scrape ESPN data? Scraping publicly available data is generally legal, but you are responsible for how you use the output. Read the legal notice below and ESPN's terms of service, and do not redistribute content in ways those terms forbid.

Do I need an ESPN API key or an account? No. The endpoints this Actor reads need no key and no login. You only pay Apify for the run.

Which leagues and sports are supported? The dropdown covers NFL, NBA, MLB, NHL, WNBA, NCAA football, NCAA men's basketball, the English Premier League, LaLiga, Serie A, Bundesliga, Ligue 1, the Champions League, the Europa League and MLS. Any other ESPN league works too — paste its endpoint into ESPN API URLs.

Can I get live scores, or only finished games? Both. A scoreboard run returns whatever ESPN shows at that moment: eventStatus is scheduled, in progress or final, and homeScore / awayScore update between runs until the game is settled. Schedule a run every 10-15 minutes for a near-live feed.

Can I get box scores and player stats? Yes. Set resource to boxscores, pick a league and a date (a day or a range), and you get one row per player per finished game with the full stat line in stats — or paste ESPN game ids into eventIds. Set resource to teamstats for team totals per game instead.

Can I pull a whole past season? Yes. Set date to a year (2025), which is one request for the whole year, or a range (20250101-20250630), fetched one day at a time; set season for standings.

Can I use this Actor from an AI agent or MCP client? Yes. It is a standard Apify Actor, so it can be called from the Apify API, from the Apify MCP server, or from any agent framework that can call an HTTP API. Every row carries status, so an agent can tell "no games today" apart from "the request failed".

Why did I get fewer rows than maxItems? Either the league has fewer records than you asked for (a table has 20 teams, a matchday has 10 fixtures), or the run reached its charge limit. The run log's final line always reports how many rows were saved and why it stopped.

What if a field is missing? Optional fields are omitted when ESPN does not publish them for that row. If a field that should always be present is missing, open an issue in the Issues tab with the run ID.

  • Google News Scraper - use it alongside scores and stats for the written coverage of a game or team.
  • Discord Server Stats - use it to see activity in a team or league fan community alongside the live stats.
  • Transfermarkt Scraper - use it for football player market values, transfer histories and club squads to go with the match data.

This Actor reads only data that ESPN publishes publicly; it does not log in, does not use credentials, and does not attempt to defeat access controls. Athlete and team names and game statistics in scores, box scores, fixtures and standings are public sports records. The Actor extracts no contact details, no private user data and no precise location data, and it never copies injury reports, the reason a player did not play, or player photos. Your results could still contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with ESPN's terms of service and applicable law when using the extracted data.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by ESPN, its owners, or any league or club named here. All trademarks belong to their respective owners.