Skip to content

theScore API: Free Endpoints from the Scores App Feed, Not theScore Bet

The undocumented JSON feed at api.thescore.com behind theScore media app: no key, tested 2 November 2026.

Last updated:

What Is theScore API?

theScore API is the JSON feed at api.thescore.com that runs theScore sports media app: scores, schedules, box scores, play-by-play, standings and player pages. It is unofficial and undocumented. theScore publishes no developer docs for it, asks for no key and charges nothing. Developers who search for the score api usually mean this feed, which belongs to the scores app. theScore Bet, the sportsbook, is a separate product. Looking for odds APIs that carry theScore Bet lines? See theScore Bet odds API guide.

We called every endpoint on this page with plain curl on 2 November 2026 and ran the code samples as written in Python (requests) and Node (fetch). The feed behaves a lot like the ESPN API. Both are undocumented, both cover the same major leagues, and either one can change without notice. theScore's terms allow personal, non-commercial use, so read Limitations and Terms before you build on it.

Base URLs

One host serves the data. A second serves the images that responses point to.

HostWhat it serves
api.thescore.comEvery JSON endpoint on this page. Paths start with a league slug: /nba, /nfl, /epl
assets-sports-gcp.thescore.comTeam logos and player headshots, linked from fields such as logos.large (HTTP 200 in our test)
feeds.thescore.comThe RSS feeds named in rss_url fields. Both feed URLs we tried answered 404

Objects link to each other through api_uri. Event 2462797 carries "api_uri": "/nba/events/2462797", its box score carries /nba/box_scores/247125, and each team carries a path such as /nba/teams/18. Put the host in front of one and you have the next URL.

What It Covers

https://api.thescore.com/leagues returned 100 leagues, each with the slug that opens every path. These are the ones developers ask about most, with the season size from /{league}/schedule (tested November 2026).

LeagueSlugSeason in /schedule
NBAnba1,267 games
NFLnfl334 games, HOF game to Super Bowl
NHLnhl1,409 games
MLBmlb2,990 games, through the World Series
NCAA basketball, footballncaab, ncaaf6,011 and 1,692 games
Premier Leagueepl380 matches
La Liga, Serie Aliga, seri380 matches each
Bundesliga, Champions Leaguebund, chlg306 and 234 matches
MLS, WNBA, CFLmls, wnba, cfl510, 374 and 94 games
ATP, PGA Touratp, pga78 and 55 tournaments

Serie A is seri: /seria/events/current answered 404. The list also carries the KHL, IPL cricket, Formula 1, NASCAR, MMA and the World Cup. Tennis and golf use a different shape. Their events/current returns one tournament object with start_date and end_date in place of a list of games: /atp/events/current returned the Rolex Paris Masters.

Key Endpoints

Paths follow /{league}/{resource} or /{league}/{resource}/{id}. Every row below answered HTTP 200 on 2 November 2026, and the examples use the ids we tested.

EndpointWhat it returnsExample
/{league}/events/currentGames theScore treats as current. 5 rows unless you add rpp/nba/events/current?rpp=20
/{league}/events/{id}One game: teams, score, venue, TV, betting line/nba/events/2462797
/{league}/events?id.in=Several games by id, as a list/nba/events?id.in=2462799,2462800,2462801
/{league}/scheduleThe season in groups, each with event_ids/nfl/schedule
/{league}/box_scores/{id}Score by period, team totals, clock, attendance/nba/box_scores/247125
/{league}/box_scores/{id}/player_recordsOne stat line per player/nba/box_scores/247125/player_records
/{league}/events/{id}/play_by_play_recordsEvery play of the game/nba/events/2462797/play_by_play_records
/{league}/teamsEvery team in the league/nhl/teams
/{league}/teams/{id}One team with its standing/nhl/teams/1 (Boston Bruins)
/{league}/teams/{id}/events/upcomingThe team's next 5 games/nba/teams/11/events/upcoming
/{league}/teams/{id}/events/previousThe team's last 5 games/nba/teams/11/events/previous
/{league}/teams/{id}/playersThe roster, with season stats/nba/teams/11/players
/{league}/teams/{id}/injuriesThe team's injury report/nba/teams/11/injuries
/{league}/players/{id}One player: position, number, team, injury/nba/players/182546
/{league}/standingsOne standings row per team/nba/standings
/{league}/leadersStat leaders, 50 rows across categories/nba/leaders
/leagues100 leagues, each with its slug and season/leagues

Some paths that look right do not exist. /nba/events/2462799/play_by_play, /nba/teams/11/roster and /nba/odds/12853680 answered 404. League-wide /nba/injuries answered 200 with an empty list while /nba/teams/11/injuries listed five Atlanta Hawks players, and /nhl/injuries answered 404. Read injuries team by team.

The Events Endpoint

URL
https://api.thescore.com/{league}/events/{id}

An event is one game, and everything else hangs off it: the box score link, the play-by-play flag and a betting line. Our test game was event 2462797, the Toronto Raptors at the Los Angeles Lakers, a 131 to 125 Lakers win (43 KB).

FieldTypeWhat it holds
idintegerThe event id: 2462797
game_datestringStart time with a UTC offset: Mon, 02 Nov 2026 02:00:00 -0000
statusstringpre_game, in_progress, half_over or final
away_team, home_teamobjectfull_name, abbreviation, id and api_uri (/nba/teams/18)
box_scoreobject or nullIts api_uri, score.home.score and progress.clock_label ("Final")
has_play_by_play_recordsbooleanTrue when the play-by-play path has plays
oddobjectline "LAL -3.5", over_under "224.5", closing "LAL -3.5, o/u 224.5"
timestamped_oddsarrayLine history: 46 snapshots, each with money_line_home, point_spread_home and total
game_descriptionstringTop performers: "L. Dončić (LAL): 45 PTS, 15 REB, 5 STL"
stadium, locationstring"Crypto.com Arena", "Los Angeles, CA, USA"

Games further out can have no box score: all five of Atlanta's upcoming games had box_score set to null. The feed names no sportsbook for odd or timestamped_odds, so treat them as a reference line. For theScore Bet's own prices, see theScore Bet API.

Box score, player lines and play-by-play

/nba/box_scores/247125 returned line_scores by quarter (Lakers 36, 30, 38, 27), team_records with team totals and attendance "19,057". /nba/box_scores/247125/player_records returned 35 player lines, led by Luka Dončić with 45 points and 15 rebounds. /nba/events/2462797/play_by_play_records returned 521 plays, each with description, event_type, progress.clock_label and the score after it. Live games work too: Atlanta at Indiana (2462799) had 126 plays at 10:06 of the second quarter.

Other sports change the play fields. NFL plays add down and distance (166 plays, 1.3 MB, for event 140696). MLB gave one record per half-inning, 18 for World Series game 100780, and Premier League records carry a category such as Goal or Corner.

Parameters and Date Filters

ParameterWhat it doesExample
id.inComma-separated event ids. Returns those games as a list/nba/events?id.in=2462799,2462800,2462801 (3 games)
game_date.inTwo ISO 8601 times. Returns the games whose game_date falls between them/nba/events?game_date.in=2026-11-01T08:00:00Z,2026-11-02T08:00:00Z (4 games)
rppRows per response. Raises or lowers the default/nba/leaders?rpp=5 (5 rows in place of 50)
pageNo effect in our test: page 1 and page 2 returned the same rows/nba/events?rpp=5&page=2

rpp matters most on events/current: without it, /nba/events/current returned 5 games while 9 were in progress, and ?rpp=20 returned all 9. Leave every filter off /nba/events and you get the whole season, 1,267 games in one 8.9 MB response.

For one US day, run game_date.in from 08:00 UTC to 08:00 UTC the next day. That window returned the four NBA games of Sunday 1 November. Midnight to midnight UTC returned six: four from Saturday night in the US and two from Sunday afternoon. A bad value such as game_date.in=yesterday,today returns 400.

The schedule as an index

/nfl/schedule returned current_season, 26 groups from "HOF" to "Super Bowl", and current_group, Week 8 with 14 event ids. Daily leagues group by date and tennis and golf by month. Pass a group's event_ids to id.in to get the games.

Group labels follow each game's UTC date. At 01:11 UTC on 3 November (Monday evening in the US), current_group was "Nov 2" and held two games from the night before, while that evening's games sat in "Nov 3". Trust game_date and status over the label.

Code Examples

Games on a date in Python

Python
import requests

# NBA games of Sunday 1 November 2026, US time (08:00 UTC to 08:00 UTC)
url = ('https://api.thescore.com/nba/events'
       '?game_date.in=2026-11-01T08:00:00Z,2026-11-02T08:00:00Z')
for game in requests.get(url, timeout=10).json():
    score = (game.get('box_score') or {}).get('score', {})
    print(game['away_team']['full_name'], score.get('away', {}).get('score'), 'at',
          game['home_team']['full_name'], score.get('home', {}).get('score'),
          game['status'])

It printed four lines, the last one "Toronto Raptors 125 at Los Angeles Lakers 131 final". The box_score guard covers dates far ahead, where games have no box score yet.

Live games and one event with cURL

cURL
# Every NBA game theScore treats as current, up to 20
curl 'https://api.thescore.com/nba/events/current?rpp=20'

# One finished game, with its line and box score link
curl 'https://api.thescore.com/nba/events/2462797'

Play-by-play in JavaScript

JavaScript
// Run as an .mjs file in Node 18+
const url = 'https://api.thescore.com/nba/events/2462797/play_by_play_records';
const plays = await fetch(url).then(r => r.json());
const last = plays[plays.length - 1];
console.log(plays.length, 'plays');
console.log(last.progress.clock_label, last.description);
console.log(`Final: ${last.away_score_after} to ${last.home_score_after}`);

It printed 521 plays and the last one, a Jamison Battle dunk at 0:01 of the fourth. Responses carry access-control-allow-origin: *, the header a browser needs before it lets a page read a cross-origin fetch.

Errors You Will See

404 Not Found

A bad league slug, a bad id and an unknown path all return 404 with this body (from /seria/events/current):

JSON
{"api_uri":"/error/events/404","error":{"request":"https://api.thescore.com/seria/events/current","code":404,"reason":"Not Found"}}

The same shape came back for /xyz/events/current, /nba/events/999999999, /nba/events/abc, /nba/teams/99999 and /nba/players/0.

400 Bad Request

/nba/events?game_date.in=yesterday,today returned 400. The filter wants two ISO 8601 times such as 2026-11-01T08:00:00Z.

200 with an empty list

We saw three causes. No games in the window: /mlb/events/current was empty after the World Series, while /mlb/schedule still listed the season. A bad id.in value: /nba/events?id.in=abc returned [] in place of an error. And the league-wide injuries path, covered above.

No 403 and no 429

None of our 128 calls to api.thescore.com was blocked or throttled. Each one sent the client's default headers (curl, Python requests or Node fetch), with no key, cookie or browser header.

Limitations and Terms

Unofficial, undocumented, personal use only

theScore's Terms of Use (last revised January 1, 2023, from Score Media and Gaming Inc.) grant users "a limited, non-exclusive, non-transferable, non-sublicensable, revocable license to: (i) access and view Content (as defined below) from the Service for your personal, non-commercial use only". In its list of things you shall not do, section 7 includes: "use spiders, crawlers, robots or any other similar means to access the Service or substantially download, reproduce or archive any portion of the Service".

The licence covers a personal script that follows your own teams. A public app, a paid product or a bulk archive falls outside it, and section 7 also rules out heavy load and commercial use. The terms are at thescore.com/pages/terms, which redirects to theScore's help centre.

  • No docs, no promise: theScore can change or close any path on this page without notice.
  • robots.txt says no crawlers: api.thescore.com/robots.txt disallows every path for every user agent.
  • No published rate limit: our calls ran at about one a second with no 429 and no X-RateLimit header. Cache-Control said max-age=10 on live games, 300 on a finished game and 7200 on past dates, so polling a live game faster than every 10 seconds gains nothing.
  • Licensed text inside: the recap_data on our test game was a wire-service story, one more reason not to republish the feed.

A product built on this feed needs a licence from theScore. For production apps with an SLA, compare licensed sports data providers. For odds, browse the directory.

Browse API Providers →

Client Libraries and Related Guides

We link no client library for this feed. A GitHub search on 2 November 2026 turned up one maintained Python wrapper, and it sends a copied Chrome User-Agent plus Origin and Referer headers on every call. You do not need them: every call in our tests answered 200 with the default headers of curl, Python requests and Node fetch. Section 7 of theScore's terms also bars forged headers that disguise where a request comes from, so a plain client is the one to write.

For the same leagues from a second undocumented source, see the ESPN API guide. For open historical data, see free sports datasets and free sports APIs.

Frequently Asked Questions

Yes. api.thescore.com charges nothing and needs no sign-up. theScore's Terms of Use grant a licence for personal, non-commercial use only and forbid robots, crawlers and bulk downloads. A hobby script fits that licence. A commercial product does not.
No. It is the undocumented feed behind theScore sports media app. theScore publishes no developer docs, no changelog and no support channel for it, so any endpoint can change or disappear without notice. Everything on this page comes from our own calls on 2 November 2026.
No. Every call in our tests answered with the client's default headers and no key, token or cookie. You also do not need a browser User-Agent, Origin or Referer header. Send your HTTP client's defaults, as the code samples on this page do.
No. This feed belongs to theScore media app, and theScore Bet is the sportsbook. Events here carry one reference line in odd and a history in timestamped_odds, with no sportsbook named. For odds APIs that carry theScore Bet prices, see theScore Bet API.
https://api.thescore.com/leagues returned 100 leagues. They include the NFL (nfl), NBA (nba), MLB, NHL, WNBA, CFL, NCAA football and basketball, the Premier League (epl), La Liga (liga), Serie A (seri), the Bundesliga (bund), the Champions League (chlg), MLS, ATP tennis and PGA Tour golf.
theScore publishes none. Our 128 calls, about one a second, got no 429 and no rate-limit header. The terms still forbid heavy load, and the Cache-Control header caches live games for 10 seconds, so poll no faster than that and cache what you fetch.
Call https://api.thescore.com/nba/events/current?rpp=20. Without rpp it returned only 5 games while 9 were live. Each game has away_team.full_name, home_team.full_name, box_score.score and status. For a past date, use game_date.in with two ISO 8601 times.
Not for a commercial product. The terms limit use to personal, non-commercial purposes, and the feed has no SLA. Production apps need a licence from theScore or a licensed provider: compare sports data APIs, or browse the API directory for odds.

Need More Reliable Sports Data?

theScore API suits personal projects. A product needs a licence, an SLA and support. Compare licensed providers in our directory.