NAV
shell javascript python

FIFA World Cup API

Welcome to the BALLDONTLIE FIFA World Cup API, your source for World Cup data across the 2018, 2022, and 2026 tournaments — teams, stadiums, players, rosters, matches, standings, lineups, events, per-match player and team stats, shot maps, attack momentum, and betting odds. 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.

Endpoints that filter by season accept a seasons[] query parameter (allowed values: 2018, 2022, 2026). When omitted, queries default to the current edition (2026) so existing integrations continue to work without changes.

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:

  1. Copy this URL: https://www.balldontlie.io/openapi/fifa.yml
  2. Share it with your preferred AI assistant (ChatGPT, the agent, Gemini, etc.)
  3. Tell the AI what you want to build (e.g., "Create a dashboard showing FIFA World Cup matches")
  4. The AI will read the OpenAPI spec and write the code for you

Example prompts to try:

This makes it incredibly easy for non-technical users, analysts, and researchers to leverage our FIFA World Cup data without needing to learn programming from scratch.

Google Sheets Integration

Our Google Sheets integration lets you access all the same data available through our API using simple spreadsheet formulas. Perfect for fantasy sports tracking, betting analysis, and sports research.

Quick Start:

  1. Get your API key from app.balldontlie.io
  2. Copy our Google Sheets script
  3. Paste it into your Google Sheet (Extensions > Apps Script)
  4. Start using functions in your cells

Example functions:

For full setup instructions and the complete list of 150+ functions, see our Google Sheets Integration Guide.

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 the FIFA World Cup will not automatically be applied to other sports. You can purchase the ALL-ACCESS ($299.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
Stadiums Yes Yes Yes
Group Standings No Yes Yes
Matches No No Yes
Odds No No Yes
Futures No No Yes
Players No No Yes
Rosters No No Yes
Match Lineups No No Yes
Match Events No No Yes
Player Match Stats No No Yes
Team Match Stats No No Yes
Match Shots No No Yes
Match Momentum No No Yes
Match Best Players No No Yes
Match Avg Positions No No Yes
Match Team Form No No 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

48-hour free trial

Every paid sport offers a 48-hour trial of the GOAT tier (all endpoints, 5 req/min during the trial). ALL-ACCESS is also available as a 48-hour trial with the same 5 req/min trial limit. A payment method is required at signup; there is no charge until the trial ends, and you can cancel anytime from your dashboard. One trial per sport per account. Existing ALL-STAR subscribers may trial the GOAT upgrade for their sports.

Authentication

To authorize, use this code:

curl "api_endpoint_here" -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/teams",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/teams',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f'Error: {response.status_code}')

Make sure to replace YOUR_API_KEY with 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

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/fifa/worldcup/v1/teams" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/teams",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/teams',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    teams = response.json()['data']
    for team in teams:
        print(f"{team['name']} ({team['abbreviation']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 13,
      "name": "Algeria",
      "abbreviation": "ALG",
      "country_code": "ALG",
      "confederation": "CAF"
    },
    {
      "id": 1,
      "name": "Argentina",
      "abbreviation": "ARG",
      "country_code": "ARG",
      "confederation": "CONMEBOL"
    },
    {
      "id": 25,
      "name": "Australia",
      "abbreviation": "AUS",
      "country_code": "AUS",
      "confederation": "AFC"
    }
    ...
  ]
}

This endpoint retrieves all participating nations for the requested World Cup edition(s). Defaults to 2026 when seasons[] is omitted.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/teams

Query Parameters

Parameter Type Description
seasons[] int[] Optional. World Cup years to include. Allowed: 2018, 2022, 2026. Default: [2026].

Response Fields

Field Type Description
id int Team ID
name string Full country name
abbreviation string Three-letter country code (e.g., USA, BRA, GER)
country_code string ISO country code
confederation string FIFA confederation (UEFA, CONMEBOL, CONCACAF, CAF, AFC, OFC)

Stadiums

Get All Stadiums

curl "https://api.balldontlie.io/fifa/worldcup/v1/stadiums" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/stadiums",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/stadiums',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    stadiums = response.json()['data']
    for stadium in stadiums:
        print(f"{stadium['name']} - {stadium['city']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 13,
      "name": "Atlanta Stadium",
      "city": "Atlanta",
      "country": "USA",
      "capacity": 71000,
      "latitude": 33.7553,
      "longitude": -84.4006
    },
    {
      "id": 8,
      "name": "BC Place Vancouver",
      "city": "Vancouver",
      "country": "CAN",
      "capacity": 54500,
      "latitude": 49.2767,
      "longitude": -123.1119
    }
    ...
  ]
}

This endpoint retrieves the host stadiums used by the requested World Cup edition(s). Defaults to 2026 when seasons[] is omitted.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/stadiums

Query Parameters

Parameter Type Description
seasons[] int[] Optional. World Cup years to include. Allowed: 2018, 2022, 2026. Default: [2026].

Response Fields

Field Type Description
id int Stadium ID
name string Stadium name
city string Host city
country string Country code
capacity int Seating capacity (nullable)
latitude float Geographic latitude (nullable)
longitude float Geographic longitude (nullable)

Group Standings

Get Group Standings

curl "https://api.balldontlie.io/fifa/worldcup/v1/group_standings" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/group_standings",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/group_standings',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    standings = response.json()['data']
    for standing in standings:
        print(f"{standing['group']['name']}: {standing['team']['name']} - {standing['points']} pts")

The above command returns JSON structured like this:

{
  "data": [
    {
      "season": { "id": 1, "year": 2026 },
      "team": {
        "id": 8,
        "name": "Mexico",
        "abbreviation": "MEX",
        "country_code": "MEX",
        "confederation": "CONCACAF"
      },
      "group": {
        "id": 1,
        "name": "Group A"
      },
      "position": 1,
      "played": 0,
      "won": 0,
      "drawn": 0,
      "lost": 0,
      "goals_for": 0,
      "goals_against": 0,
      "goal_difference": 0,
      "points": 0
    }
    ...
  ]
}

This endpoint retrieves group stage standings for the requested World Cup edition(s). Defaults to 2026 when seasons[] is omitted.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/group_standings

Query Parameters

Parameter Type Description
seasons[] int[] Optional. World Cup years to include. Allowed: 2018, 2022, 2026. Default: [2026].

Response Fields

Field Type Description
season object Season { id, year }
team object Team object
group object Group object (id, name)
position int Position within the group
played int Games played
won int Games won
drawn int Games drawn
lost int Games lost
goals_for int Goals scored
goals_against int Goals conceded
goal_difference int Goal difference
points int Total points

Matches

Get All Matches

curl "https://api.balldontlie.io/fifa/worldcup/v1/matches" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/matches",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/matches',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    matches = response.json()['data']
    for match in matches:
        home = match['home_team']['name'] if match['home_team'] else 'TBD'
        away = match['away_team']['name'] if match['away_team'] else 'TBD'
        print(f"{home} vs {away}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 1030,
      "match_number": 1,
      "datetime": "2022-11-20T16:00:00.000Z",
      "status": "completed",
      "season": { "id": 2, "year": 2022 },
      "stage": { "id": 24, "name": "Group Stage", "order": 1 },
      "group": { "id": 1, "name": "Group A" },
      "stadium": {
        "id": 476,
        "name": "Al Bayt Stadium",
        "city": "Al Khor",
        "country": "QAT",
        "capacity": 60000,
        "latitude": 51.31667,
        "longitude": 25.76667
      },
      "home_team": {
        "id": 7,
        "name": "Qatar",
        "abbreviation": "QAT",
        "country_code": "QAT",
        "confederation": "AFC"
      },
      "away_team": {
        "id": 20,
        "name": "Ecuador",
        "abbreviation": "ECU",
        "country_code": "ECU",
        "confederation": "CONMEBOL"
      },
      "home_team_source": null,
      "away_team_source": null,
      "home_score": 0,
      "away_score": 2,
      "home_score_penalties": null,
      "away_score_penalties": null,
      "first_half_home_score": 0,
      "first_half_away_score": 2,
      "second_half_home_score": 0,
      "second_half_away_score": 0,
      "extra_time_home_score": null,
      "extra_time_away_score": null,
      "has_extra_time": false,
      "has_penalty_shootout": false,
      "round_number": 1,
      "round_name": null,
      "home_formation": "5-3-2",
      "away_formation": "4-4-2",
      "referee": {
        "id": 168,
        "name": "Daniele Orsato",
        "country_code": "ITA",
        "country_name": "Italy"
      },
      "home_manager": {
        "id": 369,
        "name": "Félix Sánchez",
        "short_name": "F. Sánchez"
      },
      "away_manager": {
        "id": 372,
        "name": "Gustavo Alfaro",
        "short_name": "G. Alfaro"
      }
    },
    {
      "id": 73,
      "match_number": 73,
      "datetime": "2026-06-28T15:00:00.000Z",
      "status": "scheduled",
      "stage": {
        "id": 6,
        "name": "Round of 32",
        "order": 2
      },
      "group": null,
      "stadium": {
        "id": 4,
        "name": "Los Angeles Stadium",
        "city": "Los Angeles",
        "country": "USA"
      },
      "home_team": null,
      "away_team": null,
      "home_team_source": {
        "type": "group_2nd",
        "source_match_id": null,
        "source_match_number": null,
        "source_group_id": 1,
        "source_group_name": "Group A",
        "placeholder": "2A",
        "description": "2nd place in Group Group A"
      },
      "away_team_source": {
        "type": "group_2nd",
        "source_match_id": null,
        "source_match_number": null,
        "source_group_id": 2,
        "source_group_name": "Group B",
        "placeholder": "2B",
        "description": "2nd place in Group Group B"
      },
      "home_score": null,
      "away_score": null,
      "home_score_penalties": null,
      "away_score_penalties": null
    },
    ...
  ]
}

This endpoint retrieves matches for the requested World Cup edition(s) — group stage and knockout rounds. Defaults to 2026 when seasons[] is omitted. Results are paginated by cursor.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/matches

Query Parameters

Parameter Type Description
seasons[] int[] Optional. Allowed: 2018, 2022, 2026. Default: [2026].
match_ids[] int[] Optional. Filter to specific match IDs.
team_ids[] int[] Optional. Filter to matches where one of these team IDs played.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
id int Match ID
match_number int Official match number
datetime string Match date and time in UTC
status string Match status (scheduled, in_progress, completed, postponed, cancelled)
season object Season { id, year }
stage object Stage object (id, name, order)
group object Group object (null for knockout matches)
stadium object Stadium object
home_team object Home team (null if TBD in knockout stage)
away_team object Away team (null if TBD in knockout stage)
home_team_source object Source info when home team is TBD
away_team_source object Source info when away team is TBD
home_score int Home team score (null if not started)
away_score int Away team score (null if not started)
home_score_penalties int Home team penalty shootout score (null if no shootout)
away_score_penalties int Away team penalty shootout score (null if no shootout)
first_half_home_score int First-half home score (nullable)
first_half_away_score int First-half away score (nullable)
second_half_home_score int Second-half home score (nullable)
second_half_away_score int Second-half away score (nullable)
extra_time_home_score int Extra-time home score (nullable; null unless has_extra_time)
extra_time_away_score int Extra-time away score (nullable)
has_extra_time boolean Whether extra time was played
has_penalty_shootout boolean Whether a penalty shootout was played
round_number int Round number within the tournament (nullable)
round_name string Round name, e.g. "Round of 16" (nullable)
home_formation string Home team formation, e.g. "4-3-3" (nullable until lineups confirmed)
away_formation string Away team formation (nullable)
referee object Referee { id, name, country_code, country_name } (nullable)
home_manager object Home manager { id, name, short_name } (nullable)
away_manager object Away manager (nullable)

Team Source Object

For knockout matches where teams are not yet determined, the home_team_source or away_team_source provides information about how the team will be determined:

Field Type Description
type string Source type (group_1st, group_2nd, winner, loser, etc.)
source_match_id int ID of the match that determines this team
source_match_number int Match number that determines this team
source_group_id int ID of the group (for group placement sources)
source_group_name string Group name (e.g., "A", "B")
placeholder string Placeholder text
description string Human-readable description (e.g., "Winner of Match 49")

Understanding Knockout Match Data

The 2026 World Cup includes 104 matches total; the 2018 and 2022 editions had 64 each. Before the knockout rounds begin, many matches will have home_team and/or away_team set to null because the participating teams have not yet been determined. You can construct the knockout bracket in addition to the group stages with this data.

How to interpret the data:

  1. Check if teams are determined: If home_team or away_team is null, the team has not yet qualified for that match.

  2. Use the source object: When a team is null, look at the corresponding home_team_source or away_team_source object to understand how the team will be determined.

  3. Source types explained:

  1. Display placeholder text: Use the description field for a human-readable label (e.g., "Winner of Group A" or "Winner of Match 49").

Odds

Get Betting Odds

curl "https://api.balldontlie.io/fifa/worldcup/v1/odds" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/odds",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/odds',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    odds = response.json()['data']
    for odd in odds:
        print(f"Match {odd['match_id']}: Home {odd['moneyline_home_odds']}, Draw {odd['moneyline_draw_odds']}, Away {odd['moneyline_away_odds']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 37515873,
      "match_id": 10,
      "vendor": "draftkings",
      "moneyline_home_odds": -115,
      "moneyline_away_odds": 320,
      "moneyline_draw_odds": 250,
      "updated_at": "2025-12-18T20:39:00.295Z"
    },
    {
      "id": 37515874,
      "match_id": 11,
      "vendor": "draftkings",
      "moneyline_home_odds": 230,
      "moneyline_away_odds": 130,
      "moneyline_draw_odds": 210,
      "updated_at": "2025-12-18T20:39:00.295Z"
    }
    ...
  ]
}

This endpoint retrieves moneyline betting odds for World Cup matches. Defaults to 2026 when seasons[] is omitted. Results are paginated by cursor.

Available Vendors:

Vendor Description
draftkings DraftKings
fanduel FanDuel

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/odds

Query Parameters

Parameter Type Description
seasons[] int[] Optional. Allowed: 2018, 2022, 2026. Default: [2026].
match_ids[] int[] Optional. Filter to specific match IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
id int Odds ID
match_id int Match ID
vendor string Sportsbook vendor
moneyline_home_odds int Home team moneyline odds
moneyline_away_odds int Away team moneyline odds
moneyline_draw_odds number Draw moneyline odds
updated_at string Last update timestamp

Futures

Get Futures Odds

curl "https://api.balldontlie.io/fifa/worldcup/v1/odds/futures" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/fifa/worldcup/v1/odds/futures",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/fifa/worldcup/v1/odds/futures',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    futures = response.json()['data']
    for future in futures:
        print(f"{future['subject']['name']}: {future['american_odds']} ({future['market_name']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 1297,
      "market_type": "finish_bottom",
      "market_name": "Group G",
      "subject": {
        "id": 41,
        "name": "New Zealand",
        "abbreviation": "NZL",
        "country_code": "NZL",
        "confederation": "OFC"
      },
      "vendor": "draftkings",
      "american_odds": -185,
      "decimal_odds": 1.5405,
      "updated_at": "2025-12-18T15:12:26.494Z"
    },
    {
      "id": 1283,
      "market_type": "finish_bottom",
      "market_name": "Group C",
      "subject": {
        "id": 44,
        "name": "Scotland",
        "abbreviation": "SCO",
        "country_code": "SCO",
        "confederation": "UEFA"
      },
      "vendor": "draftkings",
      "american_odds": 500,
      "decimal_odds": 6,
      "updated_at": "2025-12-18T15:12:26.494Z"
    }
    ...
  ]
}

This endpoint retrieves futures betting odds for the FIFA World Cup (e.g., tournament winner odds). Defaults to 2026 when seasons[] is omitted.

Available Vendors:

Vendor Description
draftkings DraftKings
fanduel FanDuel

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/odds/futures

Query Parameters

Parameter Type Description
seasons[] int[] Optional. Allowed: 2018, 2022, 2026. Default: [2026].

Response Fields

Field Type Description
id int Futures odds ID
market_type string Type of futures market
market_name string Name of the futures market
subject object Team object the odds are for
vendor string Sportsbook vendor
american_odds int American odds format
decimal_odds number Decimal odds format
updated_at string Last update timestamp

Market Types

Market Type Description
outright Tournament winner
group_winner Win their group
qualify_from_group Advance from group stage
finish_bottom Finish last in their group
win_all_group_games Win all three group stage matches
to_reach_quarters Advance to the quarterfinals
to_reach_semis Advance to the semifinals
to_reach_final Advance to the final
stage_of_elimination Stage at which a team will be eliminated

Players

Get Players

curl "https://api.balldontlie.io/fifa/worldcup/v1/players?search=pulisic" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 142,
      "name": "Christian Pulisic",
      "short_name": "C. Pulisic",
      "position": "M",
      "date_of_birth": "1998-09-18T00:00:00.000Z",
      "country_code": "USA",
      "country_name": "United States",
      "height_cm": 172,
      "jersey_number": "10"
    }
  ],
  "meta": { "next_cursor": 142, "per_page": 25 }
}

Lists biographical data for every player who has appeared in a FIFA World Cup squad. By default returns all players across every ingested edition; pass seasons[] and/or team_ids[] to filter.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/players

Query Parameters

Parameter Type Description
seasons[] int[] Optional. Allowed: 2018, 2022, 2026. When omitted, returns players across all editions.
team_ids[] int[] Optional. Filter to players who appeared on these team IDs.
search string Optional. Case-insensitive substring match on player name.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
id int Player ID
name string Full name
short_name string Short / display form (nullable)
position string Primary position code (nullable)
date_of_birth string ISO date (nullable)
country_code string Three-letter country code (nullable)
country_name string Country name (nullable)
height_cm int Height in centimeters (nullable)
jersey_number string Last known jersey number (nullable)

Rosters

Get Tournament Rosters

curl "https://api.balldontlie.io/fifa/worldcup/v1/rosters?team_ids[]=12" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "season": { "id": 1, "year": 2026 },
      "team_id": 12,
      "player": {
        "id": 142,
        "name": "Christian Pulisic",
        "short_name": "C. Pulisic",
        "position": "M",
        "date_of_birth": "1998-09-18T00:00:00.000Z",
        "country_code": "USA",
        "country_name": "United States",
        "height_cm": 172,
        "jersey_number": "10"
      },
      "position": "M",
      "appearances": 4,
      "starts": 4,
      "minutes_played": 360,
      "goals": 2,
      "assists": 1,
      "yellow_cards": 1,
      "red_cards": 0,
      "avg_rating": 7.6
    }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Returns the per-tournament squad (one row per player per team per edition) with cumulative tournament stats. By default returns rosters across all ingested editions; pass seasons[] to filter.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/rosters

Query Parameters

Parameter Type Description
seasons[] int[] Optional. Allowed: 2018, 2022, 2026. When omitted, returns rosters across all editions.
team_ids[] int[] Optional. Filter to specific team IDs.
player_ids[] int[] Optional. Filter to specific player IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
season object Season { id, year }
team_id int Team ID
player object Full player object
position string Primary position code (nullable)
appearances int Tournament appearances (matches with any minutes)
starts int Tournament starts
minutes_played int Total minutes played in the tournament
goals int Tournament goals
assists int Tournament assists
yellow_cards int Tournament yellow cards
red_cards int Tournament red cards
avg_rating number Average match rating (nullable)

Match Lineups

Get Match Lineups

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_lineups?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 1,
      "team_id": 8,
      "player": {
        "id": 142,
        "name": "Christian Pulisic",
        "short_name": "C. Pulisic",
        "position": "M",
        "date_of_birth": "1998-09-18T00:00:00.000Z",
        "country_code": "USA",
        "country_name": "United States",
        "height_cm": 172,
        "jersey_number": "10"
      },
      "is_starter": true,
      "is_substitute": false,
      "shirt_number": 10,
      "position": "AM",
      "formation": "4-3-3"
    }
  ],
  "meta": { "next_cursor": 100, "per_page": 25 }
}

Returns the registered match-day squad (starters + bench) for one or more matches.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_lineups

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
team_ids[] int[] Optional. Filter to specific team IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
match_id int Match ID
team_id int Team ID
player object Full player object
is_starter boolean Whether the player started the match
is_substitute boolean Whether the player was on the bench
shirt_number int Shirt number worn for this match
position string Position code for this match (nullable)
formation string Team formation, e.g. "4-3-3" (nullable)

Match Events

Get Match Events

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_events?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 3713,
      "match_id": 1030,
      "incident_type": "goal",
      "incident_class": "penalty",
      "time_minute": 16,
      "added_time": null,
      "period": null,
      "is_home": false,
      "player": {
        "id": 8760,
        "name": "Enner Valencia",
        "short_name": "E. Valencia",
        "position": "F",
        "date_of_birth": "1989-11-04T00:00:00.000Z",
        "country_code": "ECU",
        "country_name": "Ecuador",
        "height_cm": 177,
        "jersey_number": "10"
      },
      "assist_player": null,
      "player_in": null,
      "player_out": null,
      "home_score": 0,
      "away_score": 1,
      "shootout_sequence": null,
      "shootout_description": null,
      "rescinded": null,
      "reason": null
    }
  ],
  "meta": { "next_cursor": 3713, "per_page": 25 }
}

Returns time-ordered match events: goals, cards, substitutions, period markers, and penalty-shootout kicks. Most events surface home_score/away_score reflecting the running tally; non-goal events leave them null. The period field is sparse and usually null.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_events

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
id int Event ID
match_id int Match ID
incident_type string One of: goal, card, substitution, period, injuryTime, penaltyShootout
incident_class string E.g. regular, penalty, owngoal, yellow, red, yellowRed, shootoutScored
time_minute int Minute of the match (nullable)
added_time int Stoppage-time minute (nullable)
period string Period label (e.g. "1H", "2H", "ET1", "ET2") — nullable
is_home boolean Whether the event belongs to the home team (nullable for non-team events)
player object Primary player (nullable)
assist_player object Assist player on goals (nullable)
player_in object Substitution: player coming on (nullable)
player_out object Substitution: player coming off (nullable)
home_score int Running home score after this event (nullable)
away_score int Running away score after this event (nullable)
shootout_sequence int Penalty shootout kick sequence number (nullable)
shootout_description string Shootout outcome (Scored, Missed, Saved) — nullable
rescinded boolean Whether a card was later rescinded (nullable)
reason string Free-form reason text (nullable)

Player Match Stats

Get Player Match Stats

curl "https://api.balldontlie.io/fifa/worldcup/v1/player_match_stats?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 1,
      "player_id": 142,
      "team_id": 8,
      "is_home": true,
      "rating": 7.8,
      "minutes_played": 90,
      "expected_goals": 0.42,
      "expected_assists": 0.18,
      "goals": 1,
      "assists": 0,
      "shots_on_target": 2,
      "passes_total": 50,
      "passes_accurate": 45,
      "key_passes": 3,
      "tackles": 2,
      "tackles_won": 1,
      "interceptions": 1,
      "duels_won": 4,
      "duels_lost": 3,
      "fouls_committed": 1,
      "was_fouled": 2,
      "touches": 60,
      "saves": null
    }
  ],
  "meta": { "next_cursor": 5000, "per_page": 25 }
}

Returns per-player per-match performance statistics. Goalkeeper-only fields (saves, saves_inside_box, punches, high_claims) are returned null for outfield players.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/player_match_stats

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
player_ids[] int[] Optional. Filter to specific player IDs.
team_ids[] int[] Optional. Filter to specific team IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

The response includes match_id, player_id, team_id, is_home, plus the following nullable numeric fields: rating, minutes_played, expected_goals, expected_assists, goals, assists, shots_on_target, passes_total, passes_accurate, key_passes, long_balls_total, long_balls_accurate, crosses_total, crosses_accurate, dribbles_attempted, dribbles_completed, tackles, tackles_won, interceptions, clearances, blocked_shots, duels_won, duels_lost, aerial_duels_won, aerial_duels_lost, fouls_committed, was_fouled, touches, possession_lost, ball_recoveries, big_chances_created, big_chances_missed, saves, saves_inside_box, punches, high_claims.

Team Match Stats

Get Team Match Stats

curl "https://api.balldontlie.io/fifa/worldcup/v1/team_match_stats?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 1,
      "team_id": 8,
      "is_home": true,
      "possession_pct": 60,
      "expected_goals": 1.42,
      "big_chances": 3,
      "big_chances_missed": 1,
      "shots_total": 14,
      "shots_on_target": 6,
      "shots_off_target": 5,
      "shots_blocked": 3,
      "shots_inside_box": 9,
      "shots_outside_box": 5,
      "hit_woodwork": 0,
      "corners": 6,
      "offsides": 2,
      "fouls": 10,
      "yellow_cards": 1,
      "passes_total": 500,
      "passes_accurate": 440,
      "passes_final_third": 80,
      "long_balls_total": 30,
      "long_balls_accurate": 18,
      "crosses_total": 12,
      "crosses_accurate": 4,
      "tackles": 16,
      "interceptions": 9,
      "clearances": 11,
      "saves": 3,
      "ground_duels_won": 25,
      "ground_duels_total": 50,
      "aerial_duels_won": 10,
      "aerial_duels_total": 18,
      "dribbles_completed": 8,
      "dribbles_total": 14,
      "throw_ins": 22,
      "goal_kicks": 6,
      "free_kicks": 14
    }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Per-team per-match aggregates. The possession_pct field is normalized 0-100. Field names follow the BALLDONTLIE soccer API conventions (shots_total, passes_accurate, etc.).

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/team_match_stats

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
team_ids[] int[] Optional. Filter to specific team IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Match Shots

Get Match Shots

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_shots?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 5073,
      "match_id": 1030,
      "player_id": 8760,
      "team_id": 20,
      "is_home": false,
      "shot_type": "goal",
      "situation": "penalty",
      "body_part": "right-foot",
      "goal_type": "penalty",
      "xg": 0.7884,
      "xgot": 0.9937,
      "player_x": 11.5,
      "player_y": 50,
      "goal_mouth_x": 0,
      "goal_mouth_y": 46,
      "block_x": null,
      "block_y": null,
      "time_minute": 16,
      "added_time": null,
      "time_seconds": 949
    }
  ],
  "meta": { "next_cursor": 5073, "per_page": 25 }
}

Returns the shot map for one or more matches. Coordinates are normalized 0-100. xg and xgot are populated for 2022 and 2026 matches; 2018 shots have coordinates and body_part only.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_shots

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
player_ids[] int[] Optional. Filter to specific player IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
id int Shot ID
match_id int Match ID
player_id int Shooter ID
team_id int Team ID
is_home boolean Whether the shooter's team was the home team
shot_type string One of: goal, save, miss, block, post
situation string Play situation (e.g. regular, set-piece) — nullable
body_part string Body part used (e.g. right-foot, left-foot, header) — nullable
goal_type string Type of goal (e.g. header, freekick) — nullable
xg number Expected goals value (nullable for 2018)
xgot number Expected goals on target value (nullable for 2018)
player_x number Shooter X position 0-100 (nullable)
player_y number Shooter Y position 0-100 (nullable)
goal_mouth_x number Goal-mouth X coordinate (nullable)
goal_mouth_y number Goal-mouth Y coordinate (nullable)
block_x number Block X coordinate (nullable)
block_y number Block Y coordinate (nullable)
time_minute int Match minute
added_time int Stoppage-time minute (nullable)
time_seconds int Time within the match in seconds (nullable)

Match Momentum

Get Match Momentum

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_momentum?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    { "match_id": 1, "minute": 0, "value": 0 },
    { "match_id": 1, "minute": 1, "value": 12 },
    { "match_id": 1, "minute": 2, "value": -8 }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Returns per-minute attack momentum values. Positive values favor the home side; negative values favor the away side.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_momentum

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
match_id int Match ID
minute number Match minute (may include fractions)
value number Momentum value

Match Best Players

Get Match Best Players

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_best_players?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 1,
      "player_id": 142,
      "team_id": 8,
      "is_home": true,
      "side_rank": 1,
      "is_man_of_match": true,
      "rating": 9.1,
      "reason": "scored 1 goal, 3 key passes"
    }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Returns the top-rated players for each match (best XI per side plus the man of the match).

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_best_players

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
match_id int Match ID
player_id int Player ID
team_id int Team ID
is_home boolean Whether the player was on the home side
side_rank int Rank within the player's side (1 = top)
is_man_of_match boolean Whether the player was named MOTM
rating number Match rating (nullable)
reason string Highlight summary (nullable)

Match Avg Positions

Get Match Avg Positions

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_avg_positions?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 1,
      "player_id": 142,
      "team_id": 8,
      "is_home": true,
      "avg_x": 50.5,
      "avg_y": 60.2
    }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Returns each player's average pitch position (heatmap centroid) for a given match. Coordinates are normalized 0-100 from the home side's perspective.

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_avg_positions

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
team_ids[] int[] Optional. Filter to specific team IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
match_id int Match ID
player_id int Player ID
team_id int Team ID
is_home boolean Whether the player was on the home side
avg_x number Average X coordinate (0-100)
avg_y number Average Y coordinate (0-100)

Match Team Form

Get Match Team Form

curl "https://api.balldontlie.io/fifa/worldcup/v1/match_team_form?match_ids[]=1" \
  -H "Authorization: YOUR_API_KEY"

The above command returns JSON structured like this:

{
  "data": [
    {
      "match_id": 762,
      "team_id": 27,
      "is_home": true,
      "avg_rating": 6.6,
      "position": 2,
      "value": "3"
    }
  ],
  "meta": { "next_cursor": 200, "per_page": 25 }
}

Returns a pre-match team form summary: each side's recent average rating, group standings position going in, and a value summary string (a single-digit metric — typically points earned across recent matches).

HTTP Request

GET https://api.balldontlie.io/fifa/worldcup/v1/match_team_form

Query Parameters

Parameter Type Description
match_ids[] int[] Optional. Filter to specific match IDs.
per_page int Optional. Page size, max 100. Default 25.
cursor int Optional. Cursor for the next page.

Response Fields

Field Type Description
match_id int Match ID
team_id int Team ID
is_home boolean Whether the team is the home side
avg_rating number Average rating across recent matches (nullable)
position int Position going into the match (nullable)
value string Form summary value (typically recent-match points as a single-digit string, e.g. "3")