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 gamessort=utc_datematters. utc_dateis 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
- Build with AI: let your coding assistant take it from here.
- Find any ID: every way to look up ids.
- Fixtures and results and League tables: more of what you just did.
- Live matches: follow games in play.
- Pagination: read lists longer than one page.
- API reference: every endpoint.
# 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](/dashboard/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](/register). 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](/dashboard/keys) page.
Keep the key in an environment variable rather than in your code:
```bash
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](/docs/authentication) shows a safe setup.
## 2. Find the competition
Search competitions by name. The best match comes first.
```bash
curl "https://api.soccer-data.co/v1/competitions?search=Premier%20League&per_page=3" \
-H "X-Api-Key: YOUR_API_KEY"
```
```javascript
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
```
```python
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"])
```
```json
{
"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.
```bash
curl "https://api.soccer-data.co/v1/teams?search=Arsenal&is_mens_team=true&per_page=3" \
-H "X-Api-Key: YOUR_API_KEY"
```
```javascript
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);
```
```python
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"])
```
```json
{
"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.
```bash
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"
```
```javascript
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}`);
```
```python
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"]}')
```
```json
{
"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.
```bash
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"
```
```javascript
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);
```
```python
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"])
```
```json
{
"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
- [Build with AI](/docs/build-with-ai): let your coding assistant take it from here.
- [Find any ID](/docs/guides/finding-ids): every way to look up ids.
- [Fixtures and results](/docs/guides/fixtures-and-results) and [League tables](/docs/guides/standings): more of what you just did.
- [Live matches](/docs/guides/live-matches): follow games in play.
- [Pagination](/docs/concepts/pagination): read lists longer than one page.
- [API reference](/docs/reference): every endpoint.