Skip to main content
Use this page to get season totals and per-match stats for players and teams, including xG, shots and heatmaps.
Fastest way: ask your AI. Set up your coding tool once with Build with AI, then paste:
Prompt

Which endpoint to use

For matches in progress, use the live endpoints instead. See Live matches. The JavaScript examples run on your server and read your key from the THESTATSAPI_API_KEY environment variable.

Player season stats

season_id is required. Add competition_id to count one competition only, and stage=regular or stage=playoff to split league matches from play-offs.
Response (Bukayo Saka, Premier League 25/26, trimmed):
Response
Leave out season_id and you get:

Team season stats

Response
You get 404 when the team has no stats for that season.

One match: team and player stats with xG

The examples use Brighton 3-0 Arsenal (mt_155834755). Team stats come split into all, first_half and second_half.
Team stats (trimmed):
Response
The response also has shots, attack, passes, duels, defending, goalkeeping and np_expected_goals groups. expected_goals is null when the match has no xG. Player stats (trimmed):
Response

Shotmap

Every shot with its xG, result, body part, situation and pitch position. Add player_id for one player’s shots. Every shot is drawn as if attacking the same goal. x runs from 0 at that goal line to 100 at the shooter’s own goal line (the edge of the box is 16.5). y runs across the pitch, with 50 at the centre of the goal.
One shot (trimmed):
Response

Heatmaps

Heatmap points use x and y from 0 to 100.
One point per touch (46 in this match).
Both return 404 when there’s no heatmap, for example for an unused substitute, or a match or competition without positional data.

Check what’s available first

Not every competition or match has every kind of stat. Check these flags before you call an optional endpoint: To find competitions with player stats or xG, use List coverage by competition with data_type=player_stats or data_type=xg. To see which seasons of one competition have them, use Get coverage for a competition. See Coverage. /stats and /player-stats return 404 in two cases. STATS_NOT_AVAILABLE_AT_SOURCE means the match was only covered at score and lineup level, so detailed stats will never exist. NOT_FOUND means the match doesn’t exist or its stats aren’t in yet.

API reference