SofaScore API endpoint
Returns one resource of one esports game from SofaScore, chosen with `part`: `statistics` (team totals such as kills, towers and barracks for Dota 2, gold and drakes for League of Legends), `lineups` (every player with hero or champion and per-player statistics such as net worth, gold or ADR), `bans` (banned heroes or champions per side) and `rounds` (Counter-Strike round history with outcome, winner and side per round, including overtime). Only the requested block is returned. Get the game id from sofascore-event-esports-games. Statistics and bans exist for Dota 2 and League of Legends only (404 for Counter-Strike), rounds fill for Counter-Strike only (an empty list otherwise) and lineups work for all three. Returns 404 when SofaScore has no such data for the game.
/sofascore/esports-gameQuery parameters:
id: required. Numeric SofaScore esports game id from sofascore/event-esports-games, e.g. 588883.part: required enum. Allowed values: statistics, lineups, bans, rounds. Any other value is rejected with 400 before SofaScore is contacted.Notable response behavior:
part is returned (statistics, lineups, bans or rounds).statistics holds home and away team totals as snake_case maps: numbers in statistics and true/false markers in flags. The keys depend on the title: Dota 2 has kills, towers_destroyed, towers_remaining, barracks_destroyed, barracks_remaining and faction with the first_blood flag; League of Legends has kills, gold_earned, tower_kills, inhibitor_kills, nashor_kills, dragon_kills, the drake kills per type and color.lineups holds home_players and away_players. Each line has the player, the hero or champion as character (Dota 2 and League of Legends), a role where SofaScore gives one, and a statistics map whose keys depend on the title (Dota 2: kills, deaths, assists, last_hits, denies, gold_per_min, xp_per_min, net_worth, hero_level; League of Legends: kills, deaths, assists, gold_earned, minions_killed, level; Counter-Strike: kills, deaths, assists, adr, kast, headshots, flash_assists, kd_diff, first_kills_diff, and the alive flag in flags).bans holds the banned heroes or champions per side (home, away); empty lists are valid for a game still in the draft.rounds holds the Counter-Strike round history: normaltime and overtime lists with, per round, outcome_code/outcome (elimination 0, bomb_defused 1, bomb_exploded 2, time_expired 3), winner_code (1 home, 2 away) and home_team_side_code/home_team_side (4 terrorist, 5 counter_terrorist). The decoding comes from the data itself: across 54 rounds a defuse and a timeout were always won by the counter-terrorist side and an exploded bomb by the terrorist side. rounds_in_a_half and overtime_chunk_size describe the format. Dota 2 and League of Legends games return empty lists.statistics and bans answer for Dota 2 and League of Legends and return 404 for Counter-Strike; rounds fill for Counter-Strike only; lineups answer for all three. A game that has just started can return 404 for statistics and lineups.404 when SofaScore has no such data for the game and 400 for an unknown part.Example response for part=lineups (Dota 2, shortened):
{
"code": 200,
"msg": "OK",
"data": {
"game_id": 588883,
"part": "lineups",
"source_url": "https://api.sofascore.com/api/v1/esports-game/588883/lineups",
"fetched_at": "2026-10-07T17:00:00Z",
"lineups": {
"home_players": [
{
"player": {
"id": 1078099,
"name": "Oli",
"short_name": "Oli",
"slug": "oli",
"position": "hs"
},
"character": {
"id": 1638,
"name": "Witch Doctor",
"slug": "witch-doctor"
},
"statistics": {
"assists": 17,
"deaths": 6,
"denies": 3,
"gold_per_min": 340,
"hero_level": 20,
"kills": 2,
"last_hits": 37,
"net_worth": 15120,
"xp_per_min": 505
}
}
],
"away_players": [
{
"player": {
"id": 1078066,
"name": "Dreamocel",
"short_name": "Dreamocel",
"slug": "dreamocel",
"position": "hc"
},
"character": {
"id": 1726,
"name": "Io",
"slug": "io"
},
"statistics": {
"assists": 6,
"deaths": 3,
"denies": 3,
"gold_per_min": 678,
"hero_level": 26,
"kills": 4,
"last_hits": 605,
"net_worth": 29055,
"xp_per_min": 936
}
}
]
}
}
}
Example response for part=rounds (Counter-Strike, shortened):
{
"code": 200,
"msg": "OK",
"data": {
"game_id": 588953,
"part": "rounds",
"source_url": "https://api.sofascore.com/api/v1/esports-game/588953/rounds",
"fetched_at": "2026-10-07T17:00:00Z",
"rounds": {
"rounds_in_a_half": 12,
"overtime_chunk_size": 3,
"normaltime": [
{
"outcome_code": 0,
"outcome": "elimination",
"winner_code": 1,
"home_team_side_code": 5,
"home_team_side": "counter_terrorist"
},
{
"outcome_code": 0,
"outcome": "elimination",
"winner_code": 1,
"home_team_side_code": 5,
"home_team_side": "counter_terrorist"
},
{
"outcome_code": 1,
"outcome": "bomb_defused",
"winner_code": 1,
"home_team_side_code": 5,
"home_team_side": "counter_terrorist"
},
"..."
],
"overtime": [
{
"outcome_code": 0,
"outcome": "elimination",
"winner_code": 1,
"home_team_side_code": 4,
"home_team_side": "terrorist"
},
{
"outcome_code": 2,
"outcome": "bomb_exploded",
"winner_code": 1,
"home_team_side_code": 4,
"home_team_side": "terrorist"
},
"..."
]
}
}
}
Example response for part=statistics (Dota 2, shortened):
{
"code": 200,
"msg": "OK",
"data": {
"game_id": 588883,
"part": "statistics",
"source_url": "https://api.sofascore.com/api/v1/esports-game/588883/statistics",
"fetched_at": "2026-10-07T17:00:00Z",
"statistics": {
"home": {
"statistics": {
"barracks_destroyed": 0,
"barracks_remaining": 6,
"faction": 2,
"kills": 31,
"towers_destroyed": 2,
"towers_remaining": 9
},
"flags": {
"first_blood": true
}
},
"away": {
"statistics": {
"barracks_destroyed": 4,
"barracks_remaining": 2,
"faction": 3,
"kills": 14,
"towers_destroyed": 8,
"towers_remaining": 3
},
"flags": {
"first_blood": false
}
}
}
}
}
Example response for part=bans (Dota 2, shortened):
{
"code": 200,
"msg": "OK",
"data": {
"game_id": 588883,
"part": "bans",
"source_url": "https://api.sofascore.com/api/v1/esports-game/588883/bans",
"fetched_at": "2026-10-07T17:00:00Z",
"bans": {
"home": [
{
"id": 1737,
"name": "Lone Druid",
"slug": "lone-druid"
},
{
"id": 1577,
"name": "Bounty Hunter",
"slug": "bounty-hunter"
}
],
"away": [
{
"id": 1563,
"name": "Doom",
"slug": "doom"
},
{
"id": 1544,
"name": "Bane",
"slug": "bane"
}
]
}
}
}
| Field | Filled in, of 5 checked |
|---|---|
| player | 5 |
| character | 5 |
| statistics | 5 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| id | string | Yes | Numeric SofaScore esports game id from sofascore-event-esports-games | 588883 | |
| part | string | Yes | Which resource of the game to return Allowed values: statistics, lineups, bans, rounds. | lineups | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/sofascore/esports-game?id=588883&part=lineups" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"game_id": 588883,
"part": "lineups",
"source_url": "https://api.sofascore.com/api/v1/esports-game/588883/lineups",
"fetched_at": "2026-10-07T17:00:00Z",
"lineups": {
"home_players": [
{
"player": {
"id": 1078099,
"name": "Oli",
"short_name": "Oli",
"slug": "oli",
"position": "hs"
},
"character": {
"id": 1638,
"name": "Witch Doctor",
"slug": "witch-doctor"
},
"statistics": {
"assists": 17,
"deaths": 6,
"denies": 3,
"gold_per_min": 340,
"hero_level": 20,
"kills": 2,
"last_hits": 37,
"net_worth": 15120,
"xp_per_min": 505
}
}
],
"away_players": [
{
"player": {
"id": 1078066,
"name": "Dreamocel",
"short_name": "Dreamocel",
"slug": "dreamocel",
"position": "hc"
},
"character": {
"id": 1726,
"name": "Io",
"slug": "io"
},
"statistics": {
"assists": 6,
"deaths": 3,
"denies": 3,
"gold_per_min": 678,
"hero_level": 26,
"kills": 4,
"last_hits": 605,
"net_worth": 29055,
"xp_per_min": 936
}
}
]
}
}
}Request schema
No body schema
Response schema
#/definitions/sofascore.esportsGameResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | sofascore.EsportsGameResponse | No | ||||
| data.bans | sofascore.EsportsGameBans | No | ||||
| data.bans.away | array | No | ||||
| data.bans.away[].id | integer | No | 1638 | |||
| data.bans.away[].name | string | No | Witch Doctor | |||
| data.bans.away[].slug | string | No | witch-doctor | |||
| data.bans.home | array | No | ||||
| data.bans.home[].id | integer | No | 1638 | |||
| data.bans.home[].name | string | No | Witch Doctor | |||
| data.bans.home[].slug | string | No | witch-doctor | |||
| data.fetched_at | string | No | ||||
| data.game_id | integer | No | 588883 | |||
| data.lineups | sofascore.EsportsGameLineups | No | ||||
| data.lineups.away_players | array | No | ||||
| data.lineups.away_players[].character | sofascore.EsportsCharacter | No | ||||
| data.lineups.away_players[].character.id | integer | No | 1638 | |||
| data.lineups.away_players[].character.name | string | No | Witch Doctor | |||
| data.lineups.away_players[].character.slug | string | No | witch-doctor | |||
| data.lineups.away_players[].flags | object | No | ||||
| data.lineups.away_players[].player | sofascore.PlayerBrief | No | PlayerBrief record, 6 fields: id, jersey_number, name, position, short_name, slug. Described under SofaScore event at-bat pitches API. | |||
| data.lineups.away_players[].role | string | No | mid | |||
| data.lineups.away_players[].statistics | object | No | ||||
| data.lineups.home_players | array | No | ||||
| data.lineups.home_players[].character | sofascore.EsportsCharacter | No | ||||
| data.lineups.home_players[].character.id | integer | No | 1638 | |||
| data.lineups.home_players[].character.name | string | No | Witch Doctor | |||
| data.lineups.home_players[].character.slug | string | No | witch-doctor | |||
| data.lineups.home_players[].flags | object | No | ||||
| data.lineups.home_players[].player | sofascore.PlayerBrief | No | PlayerBrief record, 6 fields: id, jersey_number, name, position, short_name, slug. Described under SofaScore event at-bat pitches API. | |||
| data.lineups.home_players[].role | string | No | mid | |||
| data.lineups.home_players[].statistics | object | No | ||||
| data.part | string | No | lineups | |||
| data.rounds | sofascore.EsportsGameRounds | No | ||||
| data.rounds.normaltime | array | No | ||||
| data.rounds.normaltime[].home_team_side | string | No | counter_terrorist | |||
| data.rounds.normaltime[].home_team_side_code | integer | No | 5 | HomeTeamSideCode is the side the home team played this round: 4 is terrorist and 5 is counter-terrorist; HomeTeamSide names it. | ||
| data.rounds.normaltime[].outcome | string | No | bomb_defused | |||
| data.rounds.normaltime[].outcome_code | integer | No | 1 | OutcomeCode is SofaScore's round-result code. In Counter-Strike 0 is an elimination, 1 a defused bomb, 2 an exploded bomb and 3 a round lost on time; Outcome names it. | ||
| data.rounds.normaltime[].winner_code | integer | No | 1 | WinnerCode is 1 for the home side and 2 for the away side. | ||
| data.rounds.overtime | array | No | ||||
| data.rounds.overtime[].home_team_side | string | No | counter_terrorist | |||
| data.rounds.overtime[].home_team_side_code | integer | No | 5 | HomeTeamSideCode is the side the home team played this round: 4 is terrorist and 5 is counter-terrorist; HomeTeamSide names it. | ||
| data.rounds.overtime[].outcome | string | No | bomb_defused | |||
| data.rounds.overtime[].outcome_code | integer | No | 1 | OutcomeCode is SofaScore's round-result code. In Counter-Strike 0 is an elimination, 1 a defused bomb, 2 an exploded bomb and 3 a round lost on time; Outcome names it. | ||
| data.rounds.overtime[].winner_code | integer | No | 1 | WinnerCode is 1 for the home side and 2 for the away side. | ||
| data.rounds.overtime_chunk_size | integer | No | 3 | |||
| data.rounds.rounds_in_a_half | integer | No | 12 | |||
| data.source_url | string | No | ||||
| data.statistics | sofascore.EsportsGameStatistics | No | ||||
| data.statistics.away | sofascore.EsportsTeamStatistics | No | ||||
| data.statistics.away.flags | object | No | ||||
| data.statistics.away.statistics | object | No | ||||
| data.statistics.home | sofascore.EsportsTeamStatistics | No | ||||
| data.statistics.home.flags | object | No | ||||
| data.statistics.home.statistics | object | No | ||||
| 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/esports-game?id=588883&part=lineups" \
-H "x-api-key: $CRAWLORA_API_KEY"