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
// Matches

List matches

Search fixtures and results across every competition we cover. Filter by competition, season, team, date range or status to build fixture lists, results pages or a live scoreboard. Results come 20 per page, newest kickoff first.

GET https://api.soccer-data.co/v1/matches Live
  • There is no single date filter. For one day's matches, send the same date as both date_from and date_to.
  • Send status=live to get every match in play right now. It is the easiest starting point for a live scoreboard.
  • If you send both competition_id and season_id, the season must belong to that competition, or you get a 400.
  • group only works together with competition_id. Without it you get a 400.
  • Asking for a page past the last one returns a 400 PAGE_OUT_OF_RANGE error. Use meta.total_pages to know where to stop.
  • Score breakdown fields stay null until a match is finished.
  • While matches are live, responses are normally at most 5 minutes old on Free and 15 seconds old on Pro and Business. Check live.updated_at to see how recent the clock is. If a fresh answer can't be fetched, you may get an older copy marked X-Cache: STALE instead: see When an answer is stale.
Query parameters
competition_id string

Only return matches from this competition.

season_id string

Only return matches from this season. If you also send competition_id, the season has to belong to it.

team_id string

Only return matches this team plays in, at home or away.

date_from date

Earliest kickoff day to include, as YYYY-MM-DD. The day is read in the utc_offset time zone.

date_to date

Last kickoff day to include, as YYYY-MM-DD, up to the end of that day. It can't be before date_from.

utc_offset string default +00:00

Time zone for date_from and date_to, as +HH:MM or -HH:MM (up to 14 hours). Use it so a 'day' matches your users' local day. Kickoff times in the response stay in UTC.

status string

Only return matches in this state. Use live for matches being played now.

scheduledlivefinishedpostponedcancelled
matchday integer

League round number, from 1. Handy for showing one gameweek.

stage string default all

regular covers league and group games. playoff covers knockout rounds, cup ties and promotion or relegation play-offs. all returns both.

regularplayoffall
group string

Only return matches from this tournament group. Not case-sensitive. Needs competition_id.

ABCDEFGHIJKL
sort string default -utc_date

-utc_date puts the latest kickoff first, which suits results. utc_date puts the soonest first, which suits fixtures. Matches with the same kickoff are ordered by id.

-utc_dateutc_date
page integer default 1

Page number, starting at 1.

per_page integer default 20

How many matches per page, from 1 to 100.

Response fields
data[].idstring

The match's id. Pass it to the other match endpoints for lineups, stats, events and more.

data[].competition_idstring

The competition this match belongs to.

data[].season_idstring

The season this match belongs to.

data[].matchdayinteger|null

League round number. Null for cup fixtures. On play-off fixtures it is the play-off round number, not a league gameweek.

data[].stagestring

regular for league and group games, playoff for knockout, cup and play-off fixtures.

data[].stage_namestring|null

Name of the round for cup and knockout games, such as final, semi_final, quarter_final, round_of_16, group_stage or qualifying. Null for normal league games.

data[].group_labelstring|null

Group letter (A to L) for group-stage games in tournaments that are split into groups. Null otherwise.

data[].statusstring

Where the match stands: scheduled, live, finished, postponed or cancelled.

data[].utc_datestring

Kickoff time in UTC, as an ISO 8601 date-time.

data[].home_team.idstring

Home team's id.

data[].home_team.namestring

Home team's name.

data[].away_team.idstring

Away team's id.

data[].away_team.namestring

Away team's name.

data[].score.homeinteger|null

Home goals in normal time. Null if the match hasn't been played.

data[].score.awayinteger|null

Away goals in normal time. Null if the match hasn't been played.

data[].score.final_scoreobject|null

Aggregate score with home and away, included only when it differs from the normal-time score.

data[].score.regulationobject|null

Score after 90 minutes, with home and away. Null until the match is finished.

data[].score.after_extra_timeobject|null

Score after 120 minutes, with home and away. Counts goals only, not shoot-out kicks. Null if there was no extra time.

data[].score.penalty_shootoutobject|null

Penalties scored by each side in a shoot-out, with home and away. Null if the match wasn't settled on penalties.

data[].score.went_to_extra_timeboolean|null

Whether extra time was played. False for formats that go straight to penalties. Null until finished, or when we can't tell.

data[].score.went_to_penaltiesboolean|null

Whether the match was decided by a shoot-out. Null until finished.

data[].score.winnerstring|null

home, away or draw, taking extra time and penalties into account. Null until finished.

data[].is_neutralboolean|null

True when the match is played at neither team's home ground. Null means we don't know, so don't treat it as false.

data[].liveobject|null

The in-play clock. Null unless status is live.

data[].live.match_statusstring|null

Detailed state of a live match: not_started, first_half, halftime, second_half, extra_time, penalties, finished, suspended or in_progress.

data[].live.elapsed_minutesinteger|null

Minutes since kickoff as a whole number. It keeps counting through the second half rather than starting again, and doesn't split out stoppage time.

data[].live.periodstring|null

first_half, halftime, second_half or finished. Null when match_status is extra_time, penalties, suspended, not_started or in_progress.

data[].live.updated_atstring|null

When the clock was last updated. If it stops moving, live updates may have stalled, so don't assume the minute is current.

data[].home_managerobject|null

Home team's manager. Can be null.

data[].home_manager.idstring

Manager's id.

data[].home_manager.namestring

Manager's name.

data[].away_managerobject|null

Away team's manager. Can be null.

data[].away_manager.idstring

Manager's id.

data[].away_manager.namestring

Manager's name.

data[].odds_availableboolean

True when pre-match odds exist for this match. Always false for postponed or cancelled matches.

data[].live_odds_availableboolean

True when in-play odds are available right now. Always false for postponed or cancelled matches.

data[].xg_availableboolean

True when match-level expected goals (xG) exist.

data[].shotmap_availableboolean

True when a shot map with per-shot xG exists.

data[].xg_qualitystring

full when per-shot xG values exist, none when they don't. Treat any value you don't recognise as none.

meta.pageinteger

The page you're on.

meta.per_pageinteger

Matches per page.

meta.totalinteger

Matching results across all pages.

meta.total_pagesinteger

Number of pages available.

curl "https://api.soccer-data.co/v1/matches?status=live" \
  -H "X-Api-Key: $SOCCER_DATA_KEY"
200 · Example response
{
    "data": [
        {
            "id": "match_9pd0ck6g2m9i",
            "competition_id": "competition_705uv6jm8myn",
            "season_id": "season_98l95mxugqs9",
            "matchday": 37,
            "stage": "regular",
            "stage_name": null,
            "group_label": null,
            "status": "finished",
            "utc_date": "2026-05-15T19:00:00.000Z",
            "home_team": {
                "id": "team_4mimn5fmya2v",
                "name": "Aston Villa"
            },
            "away_team": {
                "id": "team_74p8tg2k93z4",
                "name": "Liverpool"
            },
            "score": {
                "home": 4,
                "away": 2,
                "final_score": null,
                "regulation": {
                    "home": 4,
                    "away": 2
                },
                "after_extra_time": null,
                "penalty_shootout": null,
                "went_to_extra_time": false,
                "went_to_penalties": false,
                "winner": "home"
            },
            "is_neutral": false,
            "live": null,
            "home_manager": {
                "id": "manager_17xiheuxdn67",
                "name": "Unai Emery"
            },
            "away_manager": {
                "id": "manager_fzvvh82pzed4",
                "name": "Arne Slot"
            },
            "odds_available": true,
            "live_odds_available": false,
            "xg_available": true,
            "shotmap_available": true,
            "xg_quality": "full"
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 20,
        "total": 100,
        "total_pages": 5
    }
}
Get a free key to try it