SofaScore API endpoint
Returns the penalties a player has taken, newest first: the totals (`attempts`, `scored`) and, per penalty, the outcome (`goal`, `miss`, `post` or `save`), the zone of the goal (for example `low-right`, `high-left`, `close-high`), the x and y position in the goal mouth on SofaScore's 0 to 100 scale, the expected-goals value when available and the match. Returns 404 for players with no recorded penalties, such as most goalkeepers and defenders.
/sofascore/player-penalty-historyQuery parameters:
id: required. Numeric SofaScore player id, e.g. 839956. Get it from sofascore-search or sofascore-team-players.Notable response behavior:
attempts and scored are career totals. Each penalty has an outcome (observed values: goal, miss, post, save), a zone of the goal (observed values include low-left, low-right, low-centre, high-left, high-right, high-centre, high, right, close-high), x and y for the position in the goal mouth on SofaScore's 0 to 100 scale (low y values are high in the goal), the expected-goals xg when available and the match.404 for players with no recorded penalties, such as most goalkeepers and defenders.| Field | Filled in, of 61 checked | Values in the sample |
|---|---|---|
| id | 61 | |
| outcome | 61 | goal (52), save (5), post (3) and 1 more |
| zone | 61 | “low-right” and 8 other values |
| x | 61 | |
| y | 61 | |
| event | 61 | |
| xg | 33 | 0.79 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| id | string | Yes | Numeric SofaScore player id | 839956 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/sofascore/player-penalty-history?id=839956" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"player_id": 839956,
"source_url": "https://api.sofascore.com/api/v1/player/839956/penalty-history",
"fetched_at": "2026-10-07T00:00:00Z",
"attempts": 61,
"scored": 52,
"count": 1,
"penalties": [
{
"id": 6086510,
"outcome": "goal",
"zone": "low-left",
"x": 32.8,
"y": 96.83,
"xg": 0.7884,
"event": {
"id": 16363867,
"slug": "sunderland-manchester-city",
"start_timestamp": 1789909200,
"start_time": "2026-09-20T13:00:00Z",
"status": {
"code": 100,
"description": "Ended",
"type": "finished"
},
"winner_code": 1,
"tournament": {
"id": 1,
"name": "Premier League",
"slug": "premier-league",
"category": "England",
"unique_tournament_id": 17,
"unique_tournament_name": "Premier League"
},
"home_team": {
"id": 17,
"name": "Manchester City",
"short_name": "Man City",
"slug": "manchester-city"
},
"away_team": {
"id": 41,
"name": "Sunderland",
"short_name": "Sunderland",
"slug": "sunderland"
},
"home_score": {
"current": 5,
"period1": 3,
"period2": 2
},
"away_score": {
"current": 3,
"period1": 2,
"period2": 1
}
}
}
]
}
}Request schema
No body schema
Response schema
#/definitions/sofascore.playerPenaltyHistoryResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | sofascore.PlayerPenaltyHistoryResponse | No | ||||
| data.attempts | integer | No | 61 | |||
| data.count | integer | No | ||||
| data.fetched_at | string | No | ||||
| data.penalties | array | No | ||||
| data.penalties[].event | sofascore.EventSummary | No | 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.penalties[].id | integer | No | 6089564 | |||
| data.penalties[].outcome | string | No | goal | |||
| data.penalties[].x | number | No | 68.82 | |||
| data.penalties[].xg | number | No | 0.78 | XG is the expected-goals value of the penalty when SofaScore has one. | ||
| data.penalties[].y | number | No | 95.83 | |||
| data.penalties[].zone | string | No | low-right | |||
| data.player_id | integer | No | 839956 | |||
| data.scored | integer | No | 52 | |||
| data.source_url | string | 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/player-penalty-history?id=839956" \
-H "x-api-key: $CRAWLORA_API_KEY"