EPL API
Welcome to the BALLDONTLIE EPL API, the best SOCCER API on the planet. This API contains data from 1992-current. An API key is required. You can obtain an API key by creating a free account on our website. Read the authentication section to learn how to use the API key.
Download language specific libraries:
Take a look at our other APIs:
Join us on discord.
AI-Powered Integration
Using the OpenAPI Specification with AI
Our complete OpenAPI specification allows AI assistants to automatically understand and interact with our API. Simply share the spec URL with your AI assistant and describe what you want to build—the AI will handle the technical implementation.
Getting Started with AI:
- Copy this URL:
https://www.balldontlie.io/openapi.yml - Share it with your preferred AI assistant (ChatGPT, Claude, Gemini, etc.)
- Tell the AI what you want to build (e.g., "Create a dashboard showing this week's EPL matches")
- The AI will read the OpenAPI spec and write the code for you
Example prompts to try:
- "Using the OpenAPI spec at https://www.balldontlie.io/openapi.yml, show me how to get Mohamed Salah's season stats"
- "Read the BALLDONTLIE OpenAPI spec and create a Python script that fetches this week's EPL matches"
- "Help me understand the available EPL endpoints from this OpenAPI spec: https://www.balldontlie.io/openapi.yml"
This makes it incredibly easy for non-technical users, analysts, and researchers to leverage our sports data without needing to learn programming from scratch.
Account Tiers
There are three different account tiers which provide you access to different types of data. Visit our website to create an account for free.
Paid tiers do not apply across sports. The tier you purchase for EPL will not automatically be applied to other sports. You can purchase the ALL-ACCESS ($159.99/mo) tier to get access to every endpoint for every sport.
Read the table below to see the breakdown.
| Endpoint | Free | ALL-STAR | GOAT |
|---|---|---|---|
| Teams | Yes | Yes | Yes |
| Team Players | Yes | Yes | Yes |
| Players | Yes | Yes | Yes |
| Games | Yes | Yes | Yes |
| Team Standings | No | Yes | Yes |
| Player Season Stats | No | Yes | Yes |
| Player Stat Leaders | No | Yes | Yes |
| Team Season Stats | No | Yes | Yes |
| Team Stat Leaders | No | Yes | Yes |
| Game Lineups | No | No | Yes |
| Game Goals | No | No | Yes |
| Game Team Stats | No | No | Yes |
| Game Player Stats | No | No | Yes |
| Betting Odds | No | Yes | Yes |
The feature breakdown per tier is shown in the table below.
| Tier | Requests / Min | $USD / mo. |
|---|---|---|
| GOAT | 600 | 39.99 |
| ALL-STAR | 60 | 9.99 |
| Free | 5 | 0 |
Authentication
To authorize, use this code:
curl "api_endpoint_here" -H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
Make sure to replace
YOUR_API_KEYwith your API key.
BALLDONTLIE uses API keys to allow access to the API. You can obtain an API key by creating a free account at our website
We expect the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: YOUR_API_KEY
Pagination
This API uses cursor based pagination rather than limit/offset. Endpoints that support pagination will send back responses with a meta key that looks like what is displayed on the right.
{
"meta": {
"next_cursor": 90,
"per_page": 25
}
}
You can use per_page to specify the maximum number of results. It defaults to 25 and doesn't allow values larger than 100.
You can use next_cursor to get the next page of results. Specify it in the request parameters like this: ?cursor=NEXT_CURSOR.
Errors
The API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 401 | Unauthorized - You either need an API key or your account tier does not have access to the endpoint. |
| 400 | Bad Request -- The request is invalid. The request parameters are probably incorrect. |
| 404 | Not Found -- The specified resource could not be found. |
| 406 | Not Acceptable -- You requested a format that isn't json. |
| 429 | Too Many Requests -- You're rate limited. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Teams
Get All Teams
curl "https://api.balldontlie.io/epl/v1/teams?season=2024" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const teams = await api.epl.getTeams({ season: 2024 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
teams = api.epl.teams.list(season=2024)
The above command returns JSON structured like this:
{
"data": [
{
"id": 1,
"name": "Arsenal",
"short_name": "Arsenal",
"abbr": "ARS",
"city": "London",
"stadium": "Emirates Stadium"
},
{
"id": 2,
"name": "Aston Villa",
"short_name": "Aston Villa",
"abbr": "AVL",
"city": "Birmingham",
"stadium": "Villa Park"
},
...
]
}
This endpoint retrieves all teams.
HTTP Request
GET https://api.balldontlie.io/epl/v1/teams
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns teams for this season |
Team Players
Get Players for a Team
curl "https://api.balldontlie.io/epl/v1/teams/1/players?season=2024" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const teamId = 1;
const players = await api.epl.getTeamPlayers(teamId, { season: 2024 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
team_id = 1
players = api.epl.teams.get_players(team_id=team_id, season=2024)
The above command returns JSON structured like this:
{
"data": [
{
"id": 245,
"position": "Left Winger",
"national_team": "England",
"height": 176,
"weight": 67,
"birth_date": "2006-01-19T00:00:00.000Z",
"age": "18 years 335 days",
"name": "Kadan Young",
"first_name": "Kadan",
"last_name": "Young"
},
{
"id": 233,
"position": "Left/Centre/Right Second Striker",
"national_team": "England",
"height": 180,
"weight": 75,
"birth_date": "1995-12-30T00:00:00.000Z",
"age": "28 years 355 days",
"name": "Ollie Watkins",
"first_name": "Ollie",
"last_name": "Watkins"
},
...
]
}
This endpoint retrieves all teams.
HTTP Request
GET https://api.balldontlie.io/epl/v1/teams/:id/players
URL Parameters
| Parameter | Description |
|---|---|
| id | Player ID |
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns players for this season |
Team Season Stats
Get Season Stats for a Team
curl "https://api.balldontlie.io/epl/v1/teams/1/season_stats?season=2024" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const teamId = 1;
const stats = await api.epl.getTeamSeasonStats(teamId, { season: 2024 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
team_id = 1
stats = api.epl.teams.get_season_stats(team_id=team_id, season=2024)
The above command returns JSON structured like this:
{
"data": [
{
"value": 29,
"name": "goals",
"rank": 5,
"season": 2024
},
{
"value": 182,
"name": "dispossessed",
"rank": 3,
"season": 2024
},
{
"value": 40,
"name": "saves",
"rank": 18,
"season": 2024
},
...
]
}
This endpoint retrieves all teams.
HTTP Request
GET https://api.balldontlie.io/epl/v1/teams/:id/season_stats
URL Parameters
| Parameter | Description |
|---|---|
| id | Team ID |
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns stats for this season. Pass in 0 if you want stats across all seasons |
Response
The response is an array of objects that look like { name: string, value: number }. The name can be any of the following:
- goals
- total_red_card
- total_tackle
- total_scoring_att
- dispossessed
- saves
- total_offside
- own_goals
- touches
- clean_sheet
- total_pass
- clearance_off_line
- hit_woodwork
- total_clearance
- punches
- wins
- total_yel_card
- penalty_save
- total_high_claim
- big_chance_missed
- losses
Team Stats Leaders
Get Leaders for Team Stats
curl "https://api.balldontlie.io/epl/v1/team_stats/leaders?season=2024&type=goals" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const leaders = await api.epl.getTeamStatsLeaders({
season: 2024,
type: "goals",
});
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
team_id = 1
leaders = api.epl.leaders.teams.list(season=2024, type="goals")
The above command returns JSON structured like this:
{
"data": [
{
"team": {
"id": 15,
"name": "Chelsea",
"short_name": "Chelsea",
"abbr": "CHE",
"city": "London",
"stadium": "Stamford Bridge"
},
"season": 2024,
"rank": 1,
"value": 37,
"name": "goals"
},
{
"team": {
"id": 45,
"name": "Tottenham Hotspur",
"short_name": "Spurs",
"abbr": "TOT",
"city": "London",
"stadium": "Tottenham Hotspur Stadium"
},
"season": 2024,
"rank": 2,
"value": 36,
"name": "goals"
},
{
"team": {
"id": 10,
"name": "Brentford",
"short_name": "Brentford",
"abbr": "BRE",
"city": "Brentford",
"stadium": "Gtech Community Stadium"
},
"season": 2024,
"rank": 3,
"value": 32,
"name": "goals"
},
{
"team": {
"id": 26,
"name": "Liverpool",
"short_name": "Liverpool",
"abbr": "LIV",
"city": "Liverpool",
"stadium": "Anfield"
},
"season": 2024,
"rank": 4,
"value": 31,
"name": "goals"
},
...
]
}
This endpoint retrieves all teams.
HTTP Request
GET https://api.balldontlie.io/epl/v1/team_stats/leaders
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| cursor | false | The page number, used for pagination. |
| per_page | false | The number of results returned per call, used for pagination. Max 100. |
| season | true | Returns stats for this season. Pass in 0 if you want all time leaders across all seasons |
| type | true | Leaders for this stat type. Possible values: wins, losses, touches, own_goals, total_yel_card, total_red_card, goals, total_pass, total_scoring_att, total_offside, hit_woodwork, big_chance_missed, total_tackle, total_clearance, clearance_off_line, dispossessed, clean_sheet, saves, penalty_save, total_high_claim, punches |
Team Standings
Get Standings
curl "https://api.balldontlie.io/epl/v1/standings?season=2024" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const standings = await api.epl.getStandings({ season: 2024 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
standings = api.epl.standings.get(season=2024)
The above command returns JSON structured like this:
{
"data": [
{
"team": {
"id": 26,
"name": "Liverpool",
"short_name": "Liverpool",
"abbr": "LIV",
"city": "Liverpool",
"stadium": "Anfield"
},
"season": 2024,
"position": 1,
"form": "WWWDD",
"home_played": 8,
"home_drawn": 1,
"home_won": 6,
"home_lost": 1,
"home_goals_against": 5,
"home_goals_difference": 10,
"home_goals_for": 15,
"home_points": 19,
"away_played": 7,
"away_drawn": 2,
"away_won": 5,
"away_lost": 0,
"away_goals_against": 8,
"away_goals_difference": 8,
"away_goals_for": 16,
"away_points": 17,
"overall_played": 15,
"overall_drawn": 3,
"overall_won": 11,
"overall_lost": 1,
"overall_goals_against": 13,
"overall_goals_difference": 18,
"overall_goals_for": 31,
"overall_points": 36
},
...
]
}
This endpoint retrieves all teams.
HTTP Request
GET https://api.balldontlie.io/epl/v1/standings
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns team standings for this season |
Players
Get All Players
curl "https://api.balldontlie.io/epl/v1/players?season=2024&team_ids[]=1&team_ids[]=2" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const players = await api.epl.getPlayers({ season: 2024, team_ids: [1, 2] });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
players = api.epl.players.list(
season=2024,
team_ids=[1, 2],
)
The above command returns JSON structured like this:
{
"data": [
{
"id": 66,
"position": "Centre Central Defender",
"national_team": "France",
"height": 192,
"weight": 92,
"birth_date": "2001-03-24T00:00:00.000Z",
"age": "23 years 270 days",
"name": "William Saliba",
"first_name": "William",
"last_name": "Saliba",
"team_ids": [1]
},
{
"id": 67,
"position": "Left Full Back",
"national_team": "Scotland",
"height": 178,
"weight": 70,
"birth_date": "1997-06-05T00:00:00.000Z",
"age": "27 years 197 days",
"name": "Kieran Tierney",
"first_name": "Kieran",
"last_name": "Tierney",
"team_ids": [1]
},
...
]
}
This endpoint retrieves all players.
HTTP Request
GET https://api.balldontlie.io/epl/v1/players
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns players for this season |
| cursor | false | The cursor for pagination |
| per_page | false | Number of results per page (max 100) |
| team_ids | false | Filter by team IDs |
| player_ids | false | Filter by player IDs |
| search | false | Search by player name |
| first_name | false | Filter by player's first name |
| last_name | false | Filter by player's last name |
Player Season Stats
Get Player Season Stats
curl "https://api.balldontlie.io/epl/v1/players/295/season_stats?season=2024" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const playerId = 295;
const stats = await api.epl.getPlayerSeasonStats(playerId, { season: 2024 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
player_id = 295
stats = api.epl.players.get_season_stats(player_id=player_id, season=2024)
The above command returns JSON structured like this:
{
"data": [
{
"value": 13,
"name": "appearances",
"rank": 169,
"season": 2024
},
{
"value": 4,
"name": "big_chance_missed",
"rank": 38,
"season": 2024
},
{
"value": 1,
"name": "clean_sheet",
"rank": 104,
"season": 2024
},
{
"value": 13,
"name": "dispossessed",
"rank": 80,
"season": 2024
},
{
"value": 3,
"name": "fouls",
"rank": 302,
"season": 2024
},
...
]
}
This endpoint retrieves season statistics for a specific player.
HTTP Request
GET https://api.balldontlie.io/epl/v1/players/:id/season_stats
URL Parameters
| Parameter | Description |
|---|---|
| id | Player ID |
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| season | true | Returns stats for this season |
Response
The response is an array of objects that look like { name: string, value: number }. The name can be any of the following:
- goals
- appearances
- total_tackle
- fouls
- total_scoring_att
- dispossessed
- saves
- yellow_card
- total_offside
- own_goals
- mins_played
- touches
- red_card
- clean_sheet
- total_pass
- clearance_off_line
- hit_woodwork
- total_clearance
- punches
- penalty_save
- total_high_claim
- big_chance_missed
- goal_assist
Player Stats Leaders
Get Leaders for Player Stats
curl "https://api.balldontlie.io/epl/v1/player_stats/leaders?season=2024&type=goals" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const leaders = await api.epl.getPlayerStatsLeaders({
season: 2024,
type: "goals",
});
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
leaders = api.epl.leaders.players.list(
season=2024,
type="goals",
)
The above command returns JSON structured like this:
{
"data": [
{
"player": {
"id": 15,
"position": "Left/Centre/Right Winger",
"national_team": "Egypt",
"height": 175,
"weight": 71,
"birth_date": "1992-06-15T00:00:00.000Z",
"age": "32 years 187 days",
"name": "Mohamed Salah",
"first_name": "Mohamed",
"last_name": "Salah Hamed Mahrous Ghaly"
},
"season": 2024,
"rank": 1,
"value": 13,
"name": "goals"
},
{
"player": {
"id": 118,
"position": "Centre Striker",
"national_team": "Norway",
"height": 194,
"weight": 88,
"birth_date": "2000-07-21T00:00:00.000Z",
"age": "24 years 151 days",
"name": "Erling Haaland",
"first_name": "Erling",
"last_name": "Haaland"
},
"season": 2024,
"rank": 1,
"value": 13,
"name": "goals"
},
...
]
}
This endpoint retrieves statistical leaders among players.
HTTP Request
GET https://api.balldontlie.io/epl/v1/player_stats/leaders
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| cursor | false | The cursor for pagination |
| per_page | false | Number of results per page (max 100) |
| season | true | Returns stats for this season |
| type | true | Leaders for this stat type. Possible values: goals, goal_assist, clean_sheet, appearances, mins_played, yellow_card, red_card, total_pass, touches, total_scoring_att, hit_woodwork, big_chance_missed, total_offside, total_tackle, fouls, dispossessed, own_goals, total_clearance, clearance_off_line, saves, penalty_save, total_high_claim, punches |
Games
Get All Games
curl "https://api.balldontlie.io/epl/v1/games?season=2024&week=1" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const games = await api.epl.getGames({ season: 2024, week: 1 });
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
games = api.epl.games.list(season=2024, week=1)
The above command returns JSON structured like this:
{
"data": [
{
"id": 12776,
"week": 1,
"kickoff": "2024-08-19T19:00:00.000Z",
"provisional_kickoff": "2024-08-19T19:00:00.000Z",
"home_team_id": 25,
"away_team_id": 45,
"home_score": 1,
"away_score": 1,
"status": "C",
"season": 2024,
"ground": "King Power Stadium",
"clock": 6000,
"clock_display": "90 +10'00",
"extra_time": false
},
{
"id": 12777,
"week": 1,
"kickoff": "2024-08-18T15:30:00.000Z",
"provisional_kickoff": "2024-08-18T15:30:00.000Z",
"home_team_id": 15,
"away_team_id": 28,
"home_score": null,
"away_score": 2,
"status": "C",
"season": 2024,
"ground": "Stamford Bridge",
"clock": 5760,
"clock_display": "90 +6'00",
"extra_time": false
},
...
]
}
This endpoint retrieves all games.
HTTP Request
GET https://api.balldontlie.io/epl/v1/games
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| cursor | false | The cursor for pagination |
| per_page | false | Number of results per page (max 100) |
| season | false | Returns games for this season |
| team_id | false | Filter games by team ID |
| week | false | Filter games by week number |
Game Lineups
Get Lineups for a Game
curl "https://api.balldontlie.io/epl/v1/games/12785/lineups" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const gameId = 12785;
const lineups = await api.epl.getGameLineups(gameId);
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
game_id = 12785
lineups = api.epl.games.get_lineups(game_id=game_id)
The above command returns JSON structured like this:
{
"data": [
{
"team_id": 29,
"player": {
"id": 401,
"position": "Right Full Back",
"national_team": "Morocco",
"height": 183,
"weight": 63,
"birth_date": "1997-11-14T00:00:00.000Z",
"age": "27 years 35 days",
"name": "Noussair Mazraoui",
"first_name": "Noussair",
"last_name": "Mazraoui"
},
"substitute": false,
"captain": false,
"position": "D",
"shirt_number": 3,
"sub_clock": 4860,
"sub_clock_display": "81'00"
},
{
"team_id": 29,
"player": {
"id": 380,
"position": "Right Full Back",
"national_team": "Portugal",
"height": 183,
"weight": 78,
"birth_date": "1999-03-18T00:00:00.000Z",
"age": "25 years 276 days",
"name": "Diogo Dalot",
"first_name": "José Diogo",
"last_name": "Dalot Teixeira"
},
"substitute": false,
"captain": false,
"position": "D",
"shirt_number": 20,
"sub_clock": null,
"sub_clock_display": null
},
{
"team_id": 29,
"player": {
"id": 392,
"position": "Right Winger",
"national_team": "Cote D’Ivoire",
"height": 173,
"weight": 72,
"birth_date": "2002-07-11T00:00:00.000Z",
"age": "22 years 161 days",
"name": "Amad Diallo",
"first_name": "Amad",
"last_name": "Diallo"
},
"substitute": false,
"captain": false,
"position": "M",
"shirt_number": 16,
"sub_clock": 3660,
"sub_clock_display": "61'00"
},
...
]
}
This endpoint retrieves the lineups for a specific game.
HTTP Request
GET https://api.balldontlie.io/epl/v1/games/:id/lineups
URL Parameters
| Parameter | Description |
|---|---|
| id | Game ID |
Game Goals
Get Goals for a Game
curl "https://api.balldontlie.io/epl/v1/games/12785/goals" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const gameId = 12785;
const goals = await api.epl.getGameGoals(gameId);
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
game_id = 12785
goals = api.epl.games.get_goals(game_id=game_id)
The above command returns JSON structured like this:
{
"data": [
{
"game_id": 12785,
"scorer": {
"id": 399,
"position": "Centre Striker",
"national_team": "Netherlands",
"height": 193,
"weight": 84,
"birth_date": "2001-05-22T00:00:00.000Z",
"age": "23 years 211 days",
"name": "Joshua Zirkzee",
"first_name": "Joshua",
"last_name": "Zirkzee"
},
"assister": {
"id": 394,
"position": "Left/Right Winger",
"national_team": "Argentina",
"height": 180,
"weight": 73,
"birth_date": "2004-07-01T00:00:00.000Z",
"age": "20 years 171 days",
"name": "Alejandro Garnacho",
"first_name": "Alejandro",
"last_name": "Garnacho"
},
"clock": 5220,
"clock_display": "87'00",
"phase": "2",
"type": "G"
}
]
}
This endpoint retrieves all goals scored in a specific game.
HTTP Request
GET https://api.balldontlie.io/epl/v1/games/:id/goals
URL Parameters
| Parameter | Description |
|---|---|
| id | Game ID |
Game Team Stats
Get Team Stats for a Game
curl "https://api.balldontlie.io/epl/v1/games/12785/team_stats" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const gameId = 12785;
const stats = await api.epl.getGameTeamStats(gameId);
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
game_id = 12785
stats = api.epl.games.get_team_stats(game_id=game_id)
The above command returns JSON structured like this:
{
// Response JSON will be added here
}
{
"data": {
"game_id": 12785,
"teams": [
{
"team_id": 29,
"stats": [
{
"name": "won_contest",
"value": 8
},
{
"name": "successful_open_play_pass",
"value": 391
},
...
]
},
{
"team_id": 20,
"stats": [
{
"name": "possession_percentage",
"value": 44.6
},
{
"name": "accurate_pass",
"value": 306
},
{
"name": "backward_pass",
"value": 53
},
...
]
}
]
}
}
This endpoint retrieves team statistics for a specific game.
HTTP Request
GET https://api.balldontlie.io/epl/v1/games/:id/team_stats
URL Parameters
| Parameter | Description |
|---|---|
| id | Game ID |
Response
The stat object looks like { name: string, value: number }. The name can be any of the following:
- pts_dropped_winning_pos
- att_rf_target
- att_corner
- accurate_chipped_pass
- ontarget_att_assist
- dispossessed
- lost_corners
- att_obox_miss
- own_goals
- successful_fifty_fifty
- att_pen_goal
- att_cmiss_high_right
- won_tackle
- att_freekick_miss
- overrun
- poss_won_att_3rd
- att_lf_target
- duel_lost
- total_long_balls
- total_fwd_zone_pass
- accurate_goal_kicks
- saves
- att_assist_openplay
- att_pen_miss
- fouled_final_third
- draws
- total_clearance
- crosses_18yard
- accurate_cross
- shield_ball_oop
- total_red_card
- put_through
- total_throws
- total_layoffs
- passes_left
- accurate_layoffs
- penalty_won
- att_one_on_one
- goal_kicks
- att_hd_miss
- clearance_off_line
- att_miss_left
- att_hd_goal
- att_miss_right
- att_freekick_post
- challenge_lost
- att_obp_goal
- last_man_tackle
- attempts_obox
- total_contest
- total_final_third_passes
- diving_save
- accurate_freekick_cross
- att_hd_total
- aerial_lost
- unsuccessful_touch
- att_fastbreak
- punches
- corner_taken
- offtarget_att_assist
- total_corners_intobox
- losses
- defender_goals
- saved_ibox
- att_miss_high
- subs_goals
- att_lg_left
- att_goal_high_left
- error_lead_to_shot
- midfielder_goals
- hit_woodwork
- att_hd_target
- accurate_keeper_sweeper
- total_high_claim
- hand_ball
- att_obox_goal
- total_chipped_pass
- att_lf_miss
- att_hd_post
- att_bx_right
- post_scoring_att
- effective_clearance
- interception
- goals_conceded_obox
- att_bx_centre
- att_sv_low_left
- ontarget_scoring_att
- att_goal_low_left
- att_freekick_total
- att_miss_high_left
- first_half_goals
- blocked_scoring_att
- outfielder_block
- attempted_tackle_foul
- att_sv_low_centre
- poss_lost_all
- open_play_pass
- leftside_pass
- att_lg_right
- total_att_assist
- att_assist_setplay
- second_yellow
- goal_fastbreak
- att_goal_low_right
- goals_openplay
- att_obxd_right
- saved_obox
- pen_goals_conceded
- penalty_faced
- touches_in_opp_box
- accurate_long_balls
- pts_gained_losing_pos
- att_cmiss_high
- successful_final_third_passes
- total_pull_back
- att_goal_high_centre
- shot_off_target
- att_lg_centre
- att_ibox_post
- head_clearance
- accurate_corners_intobox
- att_obx_left
- own_goal_accrued
- att_ibox_miss
- att_sv_high_right
- total_flick_on
- shot_fastbreak
- att_goal_low_centre
- accurate_pull_back
- accurate_keeper_throws
- accurate_flick_on
- att_rf_miss
- accurate_pass
- total_tackle
- accurate_through_ball
- keeper_throws
- goals_conceded_ibox
- ball_recovery
- touches
- att_lf_goal
- att_obox_post
- att_obxd_left
- wins
- att_openplay
- total_fastbreak
- formation_used
- accurate_cross_nocorner
- att_ibox_target
- total_distance_in_m
- successful_put_through
- total_offside
- att_setpiece
- att_obx_centre
- big_chance_created
- total_yel_card
- attempts_conceded_obox
- goal_assist
- att_cmiss_right
- total_scoring_att
- total_back_zone_pass
- long_pass_own_to_opp
- won_contest
- clean_sheet
- att_obox_own_goal
- att_pen_post
- won_corners
- penalty_save
- att_sv_low_right
- goals_conceded
- crosses_18yardplus
- goal_assist_setplay
- possession_percentage
- rightside_pass
- successful_open_play_pass
- passes_right
- interceptions_in_box
- poss_won_mid_3rd
- att_cmiss_left
- att_cmiss_high_left
- fk_foul_won
- att_freekick_target
- goal_assist_intentional
- freekick_cross
- total_cross_nocorner
- accurate_launches
- rescinded_red_card
- total_through_ball
- goal_assist_deadball
- total_keeper_sweeper
- duel_won
- six_yard_block
- error_lead_to_goal
- backward_pass
- att_rf_total
- att_post_left
- poss_lost_ctrl
- subs_made
- blocked_cross
- fwd_pass
- attempts_conceded_ibox
- att_sv_high_centre
- att_obox_target
- goal_assist_openplay
- att_obx_right
- forward_goals
- effective_blocked_cross
- att_freekick_goal
- att_rf_goal
- total_launches
- blocked_pass
- att_goal_high_right
- fifty_fifty
- att_sv_high_left
- effective_head_clearance
- penalty_conceded
- att_ibox_blocked
- att_ibox_goal
- att_bx_left
- big_chance_scored
- goals
- long_pass_own_to_opp_success
- att_miss_high_right
- poss_won_def_3rd
- pen_area_entries
- accurate_back_zone_pass
- interception_won
- attempts_ibox
- att_post_high
- att_pen_target
- total_cross
- att_post_right
- aerial_won
- att_obox_blocked
- fk_foul_lost
- final_third_entries
- good_high_claim
- att_lf_total
- accurate_throws
- foul_throw_in
- att_ibox_own_goal
- total_pass
- contentious_decision
- big_chance_missed
- accurate_fwd_zone_pass
Game Player Stats
Get Player Stats for a Game
curl "https://api.balldontlie.io/epl/v1/games/12785/player_stats" \
-H "Authorization: YOUR_API_KEY"
import { BalldontlieAPI } from "@balldontlie/sdk";
const api = new BalldontlieAPI({ apiKey: "YOUR_API_KEY" });
const gameId = 12785;
const stats = await api.epl.getGamePlayerStats(gameId);
from balldontlie import BalldontlieAPI
api = BalldontlieAPI(api_key="YOUR_API_KEY")
game_id = 12785
stats = api.epl.games.get_player_stats(game_id=game_id)
The above command returns JSON structured like this:
{
"data": {
"game_id": 12785,
"players": [
{
"team_id": 29,
"player_id": 401,
"stats": [
{
"name": "formation_place",
"value": 2
},
{
"name": "times_tackled",
"value": 0
},
{
"name": "winning_goal",
"value": 0
},
...
]
},
{
"team_id": 29,
"player_id": 380,
"stats": [
{
"name": "formation_place",
"value": 3
},
{
"name": "winning_goal",
"value": 0
},
{
"name": "game_started",
"value": 1
},
...
]
},
...
]
}
}
This endpoint retrieves player statistics for a specific game.
HTTP Request
GET https://api.balldontlie.io/epl/v1/games/:id/player_stats
URL Parameters
| Parameter | Description |
|---|---|
| id | Game ID |
Betting Odds
Get Betting Odds
curl "https://api.balldontlie.io/epl/v1/odds?season=2025&week=10" \
-H "Authorization: YOUR_API_KEY"
const axios = require("axios");
const response = await axios.get("https://api.balldontlie.io/epl/v1/odds", {
params: {
season: 2025,
week: 10,
},
headers: {
Authorization: "YOUR_API_KEY",
},
});
import requests
response = requests.get(
'https://api.balldontlie.io/epl/v1/odds',
params={'season': 2025, 'week': 10},
headers={'Authorization': 'YOUR_API_KEY'}
)
print(response.json())
The above command returns JSON structured like this:
{
"data": [
{
"id": 5823885,
"game_id": 108694,
"vendor": "caesars",
"moneyline_home_odds": -105,
"moneyline_away_odds": 280,
"moneyline_draw_odds": 250,
"updated_at": "2025-11-01T02:20:58.620Z"
},
{
"id": 5823896,
"game_id": 108694,
"vendor": "draftkings",
"moneyline_home_odds": -105,
"moneyline_away_odds": 280,
"moneyline_draw_odds": 260,
"updated_at": "2025-11-01T02:21:09.145Z"
},
{
"id": 5825457,
"game_id": 108694,
"vendor": "fanduel",
"moneyline_home_odds": -105,
"moneyline_away_odds": 290,
"moneyline_draw_odds": 260,
"updated_at": "2025-11-01T02:21:35.994Z"
},
{
"id": 5825488,
"game_id": 108694,
"vendor": "betmgm",
"moneyline_home_odds": -110,
"moneyline_away_odds": 290,
"moneyline_draw_odds": 260,
"updated_at": "2025-11-01T02:21:43.798Z"
},
{
"id": 5823888,
"game_id": 108695,
"vendor": "caesars",
"moneyline_home_odds": 1200,
"moneyline_away_odds": -400,
"moneyline_draw_odds": 450,
"updated_at": "2025-11-01T02:20:58.620Z"
},
{
"id": 5823894,
"game_id": 108695,
"vendor": "draftkings",
"moneyline_home_odds": 950,
"moneyline_away_odds": -370,
"moneyline_draw_odds": 500,
"updated_at": "2025-11-01T02:21:09.145Z"
},
{
"id": 5825458,
"game_id": 108695,
"vendor": "fanduel",
"moneyline_home_odds": 1100,
"moneyline_away_odds": -425,
"moneyline_draw_odds": 500,
"updated_at": "2025-11-01T02:21:35.994Z"
},
{
"id": 5825484,
"game_id": 108695,
"vendor": "betmgm",
"moneyline_home_odds": 1100,
"moneyline_away_odds": -400,
"moneyline_draw_odds": 500,
"updated_at": "2025-11-01T02:21:43.798Z"
},
{
"id": 5823884,
"game_id": 108696,
"vendor": "caesars",
"moneyline_home_odds": -105,
"moneyline_away_odds": 280,
"moneyline_draw_odds": 250,
"updated_at": "2025-11-01T02:20:58.620Z"
},
{
"id": 5823897,
"game_id": 108696,
"vendor": "draftkings",
"moneyline_home_odds": 100,
"moneyline_away_odds": 280,
"moneyline_draw_odds": 255,
"updated_at": "2025-11-01T02:21:09.145Z"
},
{
"id": 5825455,
"game_id": 108696,
"vendor": "fanduel",
"moneyline_home_odds": 100,
"moneyline_away_odds": 270,
"moneyline_draw_odds": 260,
"updated_at": "2025-11-01T02:21:35.994Z"
},
{
"id": 5825485,
"game_id": 108696,
"vendor": "betmgm",
"moneyline_home_odds": -102,
"moneyline_away_odds": 270,
"moneyline_draw_odds": 260,
"updated_at": "2025-11-01T02:21:43.798Z"
},
{
"id": 5823887,
"game_id": 108697,
"vendor": "caesars",
"moneyline_home_odds": -120,
"moneyline_away_odds": 360,
"moneyline_draw_odds": 240,
"updated_at": "2025-11-01T02:20:58.620Z"
},
{
"id": 5823898,
"game_id": 108697,
"vendor": "draftkings",
"moneyline_home_odds": -115,
"moneyline_away_odds": 340,
"moneyline_draw_odds": 250,
"updated_at": "2025-11-01T02:21:09.145Z"
},
{
"id": 5825456,
"game_id": 108697,
"vendor": "fanduel",
"moneyline_home_odds": -125,
"moneyline_away_odds": 360,
"moneyline_draw_odds": 250,
"updated_at": "2025-11-01T02:21:35.994Z"
},
{
"id": 5825486,
"game_id": 108697,
"vendor": "betmgm",
"moneyline_home_odds": -115,
"moneyline_away_odds": 333,
"moneyline_draw_odds": 240,
"updated_at": "2025-11-01T02:21:43.798Z"
},
{
"id": 5823890,
"game_id": 108698,
"vendor": "caesars",
"moneyline_home_odds": -160,
"moneyline_away_odds": 380,
"moneyline_draw_odds": 320,
"updated_at": "2025-11-01T02:20:58.620Z"
},
{
"id": 5823900,
"game_id": 108698,
"vendor": "draftkings",
"moneyline_home_odds": -155,
"moneyline_away_odds": 400,
"moneyline_draw_odds": 330,
"updated_at": "2025-11-01T02:21:09.145Z"
},
{
"id": 5825460,
"game_id": 108698,
"vendor": "fanduel",
"moneyline_home_odds": -155,
"moneyline_away_odds": 390,
"moneyline_draw_odds": 320,
"updated_at": "2025-11-01T02:21:35.994Z"
},
{
"id": 5825490,
"game_id": 108698,
"vendor": "betmgm",
"moneyline_home_odds": -155,
"moneyline_away_odds": 375,
"moneyline_draw_odds": 320,
"updated_at": "2025-11-01T02:21:43.798Z"
}
],
"meta": {
"next_cursor": 5825490,
"per_page": 25
}
}
This endpoint retrieves betting odds for EPL games. EPL odds include moneyline odds for home, away, and draw outcomes only (no spreads or totals).
Note: Betting odds data is only available from the 2025 season, week 10 and beyond.
HTTP Request
GET https://api.balldontlie.io/epl/v1/odds
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| cursor | false | The cursor for pagination |
| per_page | false | Number of results per page (max 100) |
| season | false | Filter by season (must be provided with week) |
| week | false | Filter by week (must be provided with season) |
| game_ids | false | Filter by game IDs (array). Either this or season+week is required |
Note: You must provide either season and week together, or game_ids.