SofaScore API endpoint
Returns a football player's aggregated touch locations over one competition season: `points` with an `x`, `y` and touch `count` on SofaScore's 0-100 pitch scale, the number of `matches` behind it and the matched `events`. Get `tournament_id` and `season` from player-statistics-seasons. The response is large for a full league season. Returns 404 when SofaScore has no heatmap for that player, competition and season, which includes sports other than football and seasons the player did not play.
/sofascore/player-season-heatmapQuery parameters:
id: required. Numeric SofaScore player id, e.g. 839956.tournament_id: required. Numeric SofaScore unique-tournament (competition) id from the player-statistics-seasons endpoint, e.g. 17.season: required. Numeric SofaScore season id from the player-statistics-seasons endpoint, e.g. 76986.Notable response behavior:
points are touch locations (x, y on SofaScore's 0-100 pitch scale) with the count of touches there; matches is the number of matches behind it and events lists them as event summaries. A full league season holds several hundred points and a large response.404 when SofaScore has no heatmap for that player, competition and season: a season the player did not play, a season id that does not belong to the competition, or a sport other than football (the NBA was 404 when checked).| Field | Filled in, of 35 checked | Values in the sample |
|---|---|---|
| id | 35 | |
| slug | 35 | |
| start_timestamp | 35 | 2025-08-16 to 2026-05-19 |
| start_time | 35 | 2025-08-16 to 2026-05-19 |
| status | 35 | |
| winner_code | 35 | |
| tournament | 35 | |
| home_team | 35 | |
| away_team | 35 | |
| home_score | 35 | |
| away_score | 35 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| id | string | Yes | Numeric SofaScore player id | 839956 | |
| tournament_id | string | Yes | Numeric SofaScore unique-tournament (competition) id | 17 | |
| season | string | Yes | Numeric SofaScore season id | 76986 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/sofascore/player-season-heatmap?id=839956&tournament_id=17&season=76986" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"player_id": 839956,
"tournament_id": 17,
"season": 76986,
"source_url": "https://api.sofascore.com/api/v1/player/839956/unique-tournament/17/season/76986/heatmap/overall",
"fetched_at": "2026-07-08T00:00:00Z",
"matches": 35,
"count": 6,
"points": [
{
"x": 71,
"y": 42,
"count": 1
},
{
"x": 71,
"y": 21,
"count": 1
},
{
"x": 71,
"y": 81,
"count": 2
}
],
"events": [
{
"id": 14025050,
"slug": "manchester-city-wolverhampton",
"start_timestamp": 1755361800,
"start_time": "2025-08-16T16:30:00Z",
"status": {
"code": 100,
"description": "Ended",
"type": "finished"
},
"winner_code": 2,
"tournament": {
"id": 1,
"name": "Premier League",
"slug": "premier-league",
"category": "England",
"unique_tournament_id": 17,
"unique_tournament_name": "Premier League"
},
"home_team": {
"id": 3,
"name": "Wolverhampton",
"short_name": "Wolves",
"slug": "wolverhampton"
},
"away_team": {
"id": 17,
"name": "Manchester City",
"short_name": "Man City",
"slug": "manchester-city"
},
"home_score": {
"current": 0
},
"away_score": {
"current": 4,
"period1": 2,
"period2": 2
}
}
]
}
}Request schema
No body schema
Response schema
#/definitions/sofascore.playerSeasonHeatmapResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | sofascore.PlayerSeasonHeatmapResponse | No | ||||
| data.count | integer | No | ||||
| data.events | array | No | Events are the matches the heatmap aggregates. EventSummary record, 38 fields: away_score, away_team, home_score, home_team, id, slug, start_time, start_timestamp, status, tournament, winner_code. Described under SofaScore live events API. | |||
| data.fetched_at | string | No | ||||
| data.matches | integer | No | 35 | |||
| data.player_id | integer | No | 839956 | |||
| data.points | array | No | ||||
| data.points[].count | integer | No | 1 | |||
| data.points[].x | number | No | 71 | |||
| data.points[].y | number | No | 42 | |||
| data.season | integer | No | 76986 | |||
| data.source_url | string | No | ||||
| data.tournament_id | integer | No | 17 | |||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 404 | Not Found | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/sofascore/player-season-heatmap?id=839956&tournament_id=17&season=76986" \
-H "x-api-key: $CRAWLORA_API_KEY"