Skip to content

ESPN API: Free Sports Data for Scores, Stats & News

Access ESPN's hidden API endpoints for comprehensive sports data - no API key required

What is the ESPN API?

The ESPN API refers to a collection of undocumented endpoints that developers have discovered by reverse-engineering ESPN's web and mobile applications. While ESPN doesn't offer an official public API, these hidden endpoints provide free access to a wealth of sports data:

  • Real-time Scores: Live scoreboards across all major sports
  • Team & Player Stats: Comprehensive statistics and performance data
  • News & Headlines: Latest sports news articles
  • Standings & Rankings: League standings and power rankings
  • Game Summaries: Play-by-play data, box scores, and game details
  • Schedules: Upcoming games and event calendars

Key Benefits

  • Free Access: No subscription or payment required
  • No Authentication: No API key or token needed
  • JSON Responses: Clean, structured data format
  • Comprehensive Coverage: All major US sports plus international soccer

API Base URLs

ESPN's hidden API uses several base domains, each serving different types of data:

Domain Purpose
site.api.espn.com General site data - scores, news, teams, standings
sports.core.api.espn.com Core sports data - athletes, detailed stats, odds, venues
site.web.api.espn.com Web-specific APIs - search, game summaries, athlete overviews
fantasy.espn.com Fantasy sports data (may require authentication for private leagues)
cdn.espn.com Content delivery - optimized for speed and caching

Supported Sports & Leagues

The ESPN API covers a wide range of sports and leagues. Here are the most commonly used:

Football

  • NFL (football/nfl)
  • College Football (football/college-football)

Basketball

  • NBA (basketball/nba)
  • WNBA (basketball/wnba)
  • Men's CBB (basketball/mens-college-basketball)
  • Women's CBB (basketball/womens-college-basketball)

Baseball

  • MLB (baseball/mlb)
  • College Baseball (baseball/college-baseball)

Hockey

  • NHL (hockey/nhl)

Soccer

  • MLS (soccer/usa.1)
  • Premier League (soccer/eng.1)
  • La Liga (soccer/esp.1)
  • And many more...

Other Sports

  • Golf
  • Tennis
  • MMA/UFC
  • Racing

Key Endpoints

Most endpoints follow a consistent pattern: /apis/site/v2/sports/{sport}/{league}/{endpoint}

Endpoint Description Example
/scoreboard Live scores and game status /sports/football/nfl/scoreboard
/news Latest news articles /sports/basketball/nba/news
/teams All teams in a league /sports/baseball/mlb/teams
/teams/{id} Specific team details /sports/football/nfl/teams/12
/summary Game details with box score /sports/basketball/nba/summary?event=401234567
/standings League standings /sports/hockey/nhl/standings
/rankings Power rankings (college) /sports/football/college-football/rankings

Common Query Parameters

Parameter Description Example
dates One day (YYYYMMDD) or a whole month (YYYYMM). Ranges return HTTP 400, see date filters ?dates=20251201
limit Maximum number of results ?limit=50
season Specific season year ?season=2025
seasontype Season type (1=preseason, 2=regular, 3=postseason) ?seasontype=2
week Specific week (football) ?week=10
groups Conference/division filter ?groups=80 (FBS)

ESPN Game Summary Endpoint (summary?event=)

The summary endpoint returns everything ESPN has on one game: box score, play-by-play, win probability, betting lines, injuries and news. It is the ESPN endpoint developers search for most, and it has the least documentation.

URL
https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/summary?event={eventId}
https://site.web.api.espn.com/apis/site/v2/sports/{sport}/{league}/summary?event={eventId}

Both hosts returned the same JSON for the same game in our tests. Pick either one.

Where the event ID comes from

Every scoreboard response has an events array, and each event has an id. That id is your event value. For example, basketball/nba/scoreboard?dates=20250605 returns Game 1 of the 2025 NBA Finals (Pacers at Thunder) with id 401766122, so the summary URL is basketball/nba/summary?event=401766122. A missing or wrong ID returns HTTP 400.

What the summary response contains

Key What it holds
header Teams, score, date, status and which side is home
boxscore Team stats (teams) and player stat lines (players)
plays Play-by-play. Our NBA Finals test game had 503 plays, each with an id, text, period and clock
winprobability Home win probability after every play (see below)
leaders Top performer per stat category for each team
odds, pickcenter, againstTheSpread Betting lines and against-the-spread records. Often empty for finished games: both were empty for our NBA test game
injuries Injury report for both teams
gameInfo Venue, attendance and officials
standings, seasonseries League table and the season head-to-head
news, article, videos Recap and highlight content

Other sports use the same path with their own sport and league. Football responses add drives and scoringPlays. Soccer responses add keyEvents (a match timeline), commentary and rosters. A 2026 World Cup match looks like soccer/fifa.world/summary?event=760506 (Portugal vs Spain).

ESPN Win Probability Data

ESPN publishes a win probability for every play, and there are two ways to get it. Use the summary endpoint unless you have a reason not to.

From the summary endpoint

The winprobability array has one row per play:

JSON
{"homeWinPercentage": 0.665, "tiePercentage": 0.0, "playId": "4017661224"}

Values are fractions, not percents. The away side's chance is 1 - homeWinPercentage - tiePercentage. To see which play moved the number, match playId to the id of an entry in plays:

Python
import requests

event_id = '401766122'  # 2025 NBA Finals, Game 1
url = f'https://site.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event={event_id}'
data = requests.get(url).json()

plays = {p['id']: p for p in data['plays']}
for row in data['winprobability'][-5:]:
    play = plays.get(row['playId'], {})
    clock = play.get('clock', {}).get('displayValue', '')
    print(f"{row['homeWinPercentage']:.1%}  Q{play.get('period', {}).get('number')} {clock}  {play.get('text', '')}")

From the core API

URL
https://sports.core.api.espn.com/v2/sports/basketball/leagues/nba/events/{eventId}/competitions/{eventId}/probabilities

For NBA games the competition ID is the same as the event ID. This version is paginated (?limit= and ?page=) and each item is a $ref link, so every play costs one more request. The records do carry extra fields: awayWinPercentage, spreadCoverProbHome and totalOverProb. The spread and total fields were all 0 in our test, so the summary array gives you the same useful numbers in one call.

ESPN Scoreboard URLs by League

Every URL below returned HTTP 200 when we tested it. With no dates parameter you get today's games, or the current week for football.

League Scoreboard URL
NBA https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard
NFL https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard
College football https://site.api.espn.com/apis/site/v2/sports/football/college-football/scoreboard
MLB https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard
NHL https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard
Premier League https://site.api.espn.com/apis/site/v2/sports/soccer/eng.1/scoreboard
La Liga https://site.api.espn.com/apis/site/v2/sports/soccer/esp.1/scoreboard
FIFA World Cup https://site.api.espn.com/apis/site/v2/sports/soccer/fifa.world/scoreboard
Every soccer league https://site.api.espn.com/apis/site/v2/sports/soccer/all/scoreboard
PGA Tour https://site.api.espn.com/apis/site/v2/sports/golf/pga/scoreboard

Cricket is the odd one out. It takes a numeric league ID in place of a slug: cricket/8048/scoreboard returned a match, while cricket/scoreboard returned 404.

Date filters

Format Example What we got back
YYYYMMDD basketball/nba/scoreboard?dates=20250605 One day: Game 1 of the 2025 NBA Finals
YYYYMM basketball/nba/scoreboard?dates=202506 A whole month: all 7 games of the 2025 NBA Finals
YYYYMM soccer/fifa.world/scoreboard?dates=202606 79 World Cup matches from June 2026
Season + week football/nfl/scoreboard?dates=2025&seasontype=2&week=1 Week 1 of the 2025 NFL regular season (16 games)
YYYYMMDD-YYYYMMDD basketball/nba/scoreboard?dates=20250601-20250630 HTTP 400. Ranges failed for every league we tried

Need a range? Request it month by month and filter the dates yourself.

Code Examples

Here are practical examples for fetching data from the ESPN API:

Get NFL Scores

JavaScript
// Fetch today's NFL scores
fetch('https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard')
  .then(response => response.json())
  .then(data => {
    data.events.forEach(game => {
      console.log(game.name, game.status.type.description);
    });
  });
Python
import requests

# Fetch today's NFL scores
url = 'https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard'
response = requests.get(url)
data = response.json()

for game in data['events']:
    print(game['name'], game['status']['type']['description'])
cURL
# Fetch today's NFL scores
curl 'https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard'

Get NBA Game Summary

JavaScript
// Fetch detailed game data (replace eventId with actual game ID)
const eventId = '401584793';
const url = `https://site.web.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=${eventId}`;

fetch(url)
  .then(response => response.json())
  .then(data => {
    console.log('Boxscore:', data.boxscore);
    console.log('Play-by-play:', data.plays);
  });
Python
import requests

# Fetch detailed game data
event_id = '401584793'
url = f'https://site.web.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event={event_id}'

response = requests.get(url)
data = response.json()

print('Boxscore:', data.get('boxscore'))
print('Play-by-play:', data.get('plays'))

Get Scores for Specific Date

JavaScript
// Fetch MLB scores for a specific date
const date = '20251001'; // YYYYMMDD format
fetch(`https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard?dates=${date}`)
  .then(response => response.json())
  .then(data => console.log(data));

ESPN API 403 and 400 Errors

403 Forbidden

ESPN serves these endpoints through a CDN that blocks some scripted traffic. In our tests, a script that sent a copied Chrome User-Agent header got 403 on every request. The same URLs returned 200 with the default headers of curl, Python requests and Node fetch. If your script sets a browser User-Agent, delete that header first.

If the 403 continues after that, slow down and cache what you fetch. ESPN publishes no rate limit, so there is no safe number to aim for.

400 Bad Request

  • No valid event ID: summary needs ?event= with an id from a scoreboard response
  • A date range: ?dates=20250601-20250630 fails. Use one day or one month

200 with an empty events array

That means no games on that date, not a broken endpoint. Try a date you know had games.

Limitations & Considerations

Important: Unofficial API

The ESPN API is not officially supported. Keep these limitations in mind:

  • No Official Documentation: These endpoints are undocumented and discovered through reverse engineering
  • No Stability Guarantee: ESPN can modify or remove endpoints at any time without notice
  • Unknown Rate Limits: There's no published information about rate limiting or usage quotas
  • No Support: ESPN does not provide developer support for these endpoints
  • Terms of Service: Heavy automated usage may violate ESPN's terms of service

Recommendations

  • For Hobby Projects: The ESPN API works great for personal projects, learning, and experimentation
  • For Production Apps: Consider official sports data providers for applications requiring guaranteed uptime and support
  • Error Handling: Implement robust error handling since endpoints may change unexpectedly
  • Caching: Cache responses to reduce API calls and improve reliability

Browse Official API Providers →

Community Resources

Frequently Asked Questions

ESPN does not offer an official public API, but developers have discovered undocumented endpoints that provide free access to scores, stats, news, and standings data. These hidden APIs require no authentication or API key, making them accessible for personal projects and experimentation.
No. The ESPN API endpoints discussed here are unofficial and undocumented. They were discovered by reverse-engineering ESPN's web and mobile applications. ESPN does not provide official API documentation, support, or any service level agreements for these endpoints.
The ESPN API covers NFL, NBA, MLB, NHL, WNBA, college football, men's and women's college basketball, college baseball, MLS, international soccer leagues (Premier League, La Liga, Bundesliga, Serie A, etc.), golf, tennis, MMA/UFC, racing, and many other sports.
No. The ESPN hidden API endpoints are publicly accessible and do not require authentication, API keys, or tokens. You can make simple HTTP GET requests to retrieve data. However, private fantasy league data may require authentication cookies.
The ESPN API is not recommended for production applications that require guaranteed stability and uptime. Since these are unofficial endpoints, ESPN can modify or remove them at any time without notice. For production applications, consider using official sports data providers that offer documentation, support, and SLAs.
To get NBA scores, make a GET request to: https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard. The response includes all games for the current day with scores, team info, and game status. Add ?dates=YYYYMMDD to get scores for a specific date.
For the game summary endpoint, nothing that matters. Both hosts returned the same JSON for the same event in our tests. site.web.api.espn.com also serves some web-only data, such as search and athlete overviews.
Call the summary endpoint for a game, for example https://site.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=401766122, and read the winprobability array. Each row has homeWinPercentage, tiePercentage and a playId that matches a play in the plays array. Full example above.
In our tests, ESPN returned 403 when a script sent a copied browser User-Agent header. Remove that header and let your HTTP client send its default. The same requests then returned 200. More on 403 and 400 errors.
ESPN does not publish one. We did not hit a limit during our tests, but heavy traffic can get blocked without warning. Cache responses and do not poll faster than your app needs.

Need More Reliable Sports Data?

While the ESPN API is great for hobby projects, production applications often need guaranteed uptime and official support. Compare professional sports data providers in our directory.