Building with AI? Give your coding tool the whole reference in one file: https://soccer-data.co/llms.txt
SOCCER DATA Docs
Sign in Get API key
// Get started

Quickstart

Make your first requests in five minutes, from finding ids to a team's next match and a league table.

By the end of this page you'll have looked up a competition and a team, fetched Arsenal's next match and printed the Premier League table. The examples come in curl, JavaScript and Python. The JavaScript needs Node 18 or later (save it as a .mjs file so top-level await works), and the Python needs the requests package.

Tip Want to see responses before writing any code? The API tester in your dashboard runs every endpoint as your signed-in account, so it needs no key.

1. Get an API key

Create an account. Your first key is made for you when you sign up, and shown on the dashboard page you land on. Keys start with sd_. We show the full key only once, so copy it straight away. If you lose it, or want another, create one on the API keys page.

Keep the key in an environment variable rather than in your code:

export SOCCER_DATA_KEY="YOUR_API_KEY"

Warning Your key should only live on a server. Anything that runs in a browser or ships inside an app can be read by anyone. Authentication shows a safe setup.

2. Find the competition

Search competitions by name. The best match comes first.

curl "https://api.soccer-data.co/v1/competitions?search=Premier%20League&per_page=3" \
  -H "X-Api-Key: YOUR_API_KEY"
const params = new URLSearchParams({ search: "Premier League", per_page: "3" });
const res = await fetch(`https://api.soccer-data.co/v1/competitions?${params}`, {
  headers: { "X-Api-Key": process.env.SOCCER_DATA_KEY },
});
const body = await res.json();
console.log(body.data[0].id); // the Premier League's id
import os, requests

res = requests.get(
    "https://api.soccer-data.co/v1/competitions",
    params={"search": "Premier League", "per_page": 3},
    headers={"X-Api-Key": os.environ["SOCCER_DATA_KEY"]},
)
print(res.json()["data"][0]["id"])
{
  "data": [
    { "id": "competition_705uv6jm8myn", "name": "Premier League", "country": "England", "type": "league", "xg_available": true },
    { "id": "competition_ebdxduk29wtn", "name": "Egyptian Premier League", "country": "Egypt", "type": "league" },
    { "id": "competition_zbmq20gkyy8b", "name": "Russian Premier League", "country": "Russia", "type": "league" }
  ],
  "meta": { "page": 1, "per_page": 3, "total": 6, "total_pages": 2 }
}

The Premier League is competition_705uv6jm8myn. Ids never change, so you only need to look one up once.

3. Find the team

Search teams the same way. Add is_mens_team=true so women's sides with the same name drop out.

curl "https://api.soccer-data.co/v1/teams?search=Arsenal&is_mens_team=true&per_page=3" \
  -H "X-Api-Key: YOUR_API_KEY"
const params = new URLSearchParams({ search: "Arsenal", is_mens_team: "true", per_page: "3" });
const res = await fetch(`https://api.soccer-data.co/v1/teams?${params}`, {
  headers: { "X-Api-Key": process.env.SOCCER_DATA_KEY },
});
const { data } = await res.json();
for (const team of data) console.log(team.id, team.name);
import os, requests

res = requests.get(
    "https://api.soccer-data.co/v1/teams",
    params={"search": "Arsenal", "is_mens_team": "true", "per_page": 3},
    headers={"X-Api-Key": os.environ["SOCCER_DATA_KEY"]},
)
for team in res.json()["data"]:
    print(team["id"], team["name"])
{
  "data": [
    { "id": "team_f0ibhxdw7hs5", "name": "Arsenal", "country": "England", "is_mens_team": true },
    { "id": "team_oejc59y73fs9", "name": "Arsenal U21", "country": "England", "is_mens_team": true },
    { "id": "team_fg5femf0es8u", "name": "Arsenal Tula", "country": "Russian Federation", "is_mens_team": true }
  ],
  "meta": { "page": 1, "per_page": 3, "total": 13, "total_pages": 5 }
}

Arsenal's first team is team_f0ibhxdw7hs5.

4. Get the next match

Ask for the team's scheduled matches, sorted by kickoff, one per page.

curl "https://api.soccer-data.co/v1/matches?team_id=team_f0ibhxdw7hs5&status=scheduled&sort=utc_date&per_page=1" \
  -H "X-Api-Key: YOUR_API_KEY"
const params = new URLSearchParams({
  team_id: "team_f0ibhxdw7hs5",
  status: "scheduled",
  sort: "utc_date",
  per_page: "1",
});
const res = await fetch(`https://api.soccer-data.co/v1/matches?${params}`, {
  headers: { "X-Api-Key": process.env.SOCCER_DATA_KEY },
});
const [next] = (await res.json()).data;
console.log(`${next.home_team.name} v ${next.away_team.name}, ${next.utc_date}`);
import os, requests

res = requests.get(
    "https://api.soccer-data.co/v1/matches",
    params={"team_id": "team_f0ibhxdw7hs5", "status": "scheduled", "sort": "utc_date", "per_page": 1},
    headers={"X-Api-Key": os.environ["SOCCER_DATA_KEY"]},
)
match = res.json()["data"][0]
print(f'{match["home_team"]["name"]} v {match["away_team"]["name"]}, {match["utc_date"]}')
{
  "data": [
    {
      "id": "match_yoeml0e6ae37",
      "competition_id": "competition_705uv6jm8myn",
      "season_id": "season_hr1ie7yrsdmt",
      "matchday": 6,
      "status": "scheduled",
      "utc_date": "2026-10-10T11:30:00.000Z",
      "home_team": { "id": "team_f0ibhxdw7hs5", "name": "Arsenal" },
      "away_team": { "id": "team_w63vzmngfyz9", "name": "Leeds United" },
      "score": { "home": null, "away": null, "winner": null },
      "odds_available": true,
      "xg_available": false
    }
  ],
  "meta": { "page": 1, "per_page": 1, "total": 9, "total_pages": 9 }
}

Two things to know about /matches:

  • Without sort, it lists the latest kickoff first, so for upcoming games sort=utc_date matters.
  • utc_date is always in UTC.

For the most recent result instead, use status=finished and leave sort out.

5. Get the league table

A table belongs to a season, so first read the competition's current_season_id, then ask for that season's standings.

curl "https://api.soccer-data.co/v1/competitions/competition_705uv6jm8myn" \
  -H "X-Api-Key: YOUR_API_KEY"
# data.current_season_id is season_hr1ie7yrsdmt

curl "https://api.soccer-data.co/v1/competitions/competition_705uv6jm8myn/seasons/season_hr1ie7yrsdmt/standings" \
  -H "X-Api-Key: YOUR_API_KEY"
const headers = { "X-Api-Key": process.env.SOCCER_DATA_KEY };
const base = "https://api.soccer-data.co/v1/competitions/competition_705uv6jm8myn";

const competition = (await (await fetch(base, { headers })).json()).data;
const table = (await (await fetch(
  `${base}/seasons/${competition.current_season_id}/standings`,
  { headers },
)).json()).data;

for (const row of table) console.log(row.position, row.team.name, row.points);
import os, requests

headers = {"X-Api-Key": os.environ["SOCCER_DATA_KEY"]}
base = "https://api.soccer-data.co/v1/competitions/competition_705uv6jm8myn"

season_id = requests.get(base, headers=headers).json()["data"]["current_season_id"]
table = requests.get(f"{base}/seasons/{season_id}/standings", headers=headers).json()["data"]

for row in table:
    print(row["position"], row["team"]["name"], row["points"])
{
  "data": [
    {
      "team": { "id": "team_hof12pbei216", "name": "Manchester City" },
      "position": 1,
      "matches_played": 5,
      "wins": 5,
      "draws": 0,
      "losses": 0,
      "goals_for": 13,
      "goals_against": 5,
      "goal_difference": 8,
      "points": 15,
      "group_label": null
    },
    {
      "team": { "id": "team_f0ibhxdw7hs5", "name": "Arsenal" },
      "position": 2,
      "matches_played": 5,
      "wins": 4,
      "draws": 0,
      "losses": 1,
      "goals_for": 8,
      "goals_against": 4,
      "goal_difference": 4,
      "points": 12,
      "group_label": null
    }
  ]
}

Common mistakes

What went wrong What you see How to fix it
Sending date=2026-10-10 400 UNKNOWN_PARAMETER Use date_from and date_to, both set to the same day.
Leaving out sort=utc_date for upcoming matches The match furthest in the future comes first Add sort=utc_date.
Missing or mistyped key header 401 UNAUTHORIZED Send X-Api-Key: YOUR_API_KEY.
Guessing or typing ids by hand 404 NOT_FOUND Look ids up with search.

Next steps