# Football Results Scraper - Goals, Cards & Stats, All Leagues (`neverempty/football-results-scraper`) Actor

For football bettors, fantasy players and data teams: results from every league on Flashscore with goal scorers, assists, cards, substitutions, half-time score, round and stats incl. xG. 3,260 of 3,260 matches matched Flashscore's page in a 3-day check. Monitoring returns only matches that changed.

- **URL**: https://apify.com/neverempty/football-results-scraper.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** Sports, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.65 / 1,000 match returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Football Results Scraper - Goals, Cards & Stats, All Leagues

For football bettors, fantasy players and data teams: every match Flashscore lists, across all countries and leagues, with teams, league, round, score, half-time score, winner, red cards and status, plus goal scorers with assists and minute, cards, substitutions, referee, attendance and match statistics including xG. In a check on 2026-09-21, 3,260 of 3,260 matches over 3 days matched Flashscore's own page field by field. Ask by date, league name or team name - no match ids to look up - and turn on monitoring so a schedule receives only the matches that finished or whose score changed.

Export as JSON, CSV or Excel.

### What you get

One row per match, for any day from 7 days back to 7 days ahead:

- **League**: country or region, league name, Flashscore's header (`ENGLAND: Premier League`), league id and page, and the round (`Round 5`, `Quarter-finals`), read from the match page because Flashscore's daily feed does not carry it.
- **Teams**: home and away as Flashscore shows them, with Flashscore team id, slug and short code.
- **Score**: the score, half-time score, 90-minute score, score after extra time, penalty shoot-out score, winner (`home`, `away` or `draw`) and how it was decided (`regular-time`, `extra-time`, `penalties`), red cards per team.
- **Status**: scheduled, live (with the period and the minute), finished, postponed, cancelled, interrupted, abandoned, awarded and more, with Flashscore's own status text.
- **Events** (matches that have started): goals with scorer, assist, minute, penalty or own goal and the score after it; yellow, second-yellow and red cards with the reason; substitutions; missed penalties; half scores; referee, stadium, city, attendance and capacity.
- **Statistics** (matches that have started): possession, shots, shots on target, corners, fouls, offsides, yellow cards and xG as columns, and every statistic Flashscore shows (passes, big chances, xGOT, tackles...) for the match and each half in `statistics`.

Between 2026-09-14 and 2026-09-20 Flashscore's daily football feed carried 171 to 1,780 matches a day (weekend days the most).

### How it matches Flashscore's page

The rows come from the same feeds Flashscore's website reads, assembled the way the page assembles them:

1. **The daily feed can be minutes old.** It is served from a cache, so the page applies Flashscore's recent-changes feed on top right after loading. This Actor does the same, and every row says whether that step worked in `liveUpdatesApplied`. When the cached copy that answered is older than two minutes the Actor asks again (up to twice) and keeps the freshest; `feedAgeSeconds` says how old it was.
2. **Each day's feed also carries matches that belong to the day before or after.** Flashscore's page does not show them on that day, and neither does this Actor: a match is returned under the day it starts on in your time zone.
3. **After a penalty shoot-out** Flashscore's feed adds one goal to the winner. The page shows the real score and the shoot-out in brackets, and so does this Actor: `homeScore` / `awayScore` are the goals after extra time, the shoot-out is in `penaltiesHomeScore` / `penaltiesAwayScore`.
4. **The half-time score** is not in the daily feed; it is the 90-minute score minus the second-half score, which matched the half scores of Flashscore's match pages on every match checked.

The check behind the numbers above: Flashscore's football page was opened in a browser on 2026-09-21 for three days with every collapsed league expanded, and at the same moment the daily and recent-changes feeds were read. Every match on the page (3,260) was compared on team names, score, penalty shoot-out score, red cards, status text, the live minute, the start time and the day it is listed on: 3,260 of 3,260 matched.

### Input

| Field | What it does |
|---|---|
| `days` | Days to read: `today`, `yesterday`, `tomorrow`, a number from `-7` to `7`, or `YYYY-MM-DD`. Empty = today. Days outside Flashscore's 15-day window are refused before anything is requested. |
| `utcOffsetHours` | Your time zone as hours from UTC (0 = UTC). Decides where a day starts, as on Flashscore in that time zone. `startTime` is always UTC. |
| `countries` | Keep only these countries or regions as Flashscore names them (`England`, `Spain`, `Europe`, `World`). Whole name, case-insensitive. |
| `leagues` | Keep a match if its league matches one of these: Flashscore's header or part of it (`england: premier league`, `champions league`), the league path (`england/premier-league`) or a league URL. `premier league` alone also keeps other countries' Premier Leagues. |
| `teams` | Keep a match if one of these appears in the home or away team name or slug (partial, case-insensitive). |
| `matchStatuses` | `live`, `finished`, `scheduled`, `other` (postponed, cancelled, interrupted...). Empty = all. |
| `includeEvents` | On (default) = one extra request per returned match that has started, for goals, cards, substitutions, referee and attendance. |
| `includeStatistics` | On (default) = one extra request per returned match that has started, for match statistics. |
| `includeRound` | On (default) = one small extra request per returned match to read the round from its page (only the first 32 KB are read). Off = faster, `round` is null. |
| `maxMatches` | Maximum rows to return (default 200, up to 3,000). Not used in monitoring mode. |
| `monitoringMode` | Return only matches that changed since the row last returned for them. Needs at least one of `countries`, `leagues` or `teams`, unless `monitorEveryLeague` is on. |
| `monitorEveryLeague` | Allow monitoring with no country, league or team filter. Off (default) = such a run is refused with a free row, because its first run would return and charge every match of the day. |
| `changeDetail` | In monitoring mode: `score` (default: a goal, a red card, extra-time or shoot-out score, or a change of status such as kick-off or full time; half time and the minute do not count) or `finished` (each match once, when it reaches a final state: finished, walkover, awarded, cancelled or abandoned). |
| `resetMonitoringState` | Forget the remembered rows for this filter set, so everything counts as new. |
| `useProxy` | On (default) = if Flashscore answers 401, 403, 429 or 503, retry through an Apify proxy. |

Example: yesterday's and today's results from the Premier League and LaLiga, in London summer time.

```json
{
    "days": ["yesterday", "today"],
    "utcOffsetHours": 1,
    "leagues": ["england: premier league", "spain: laliga"],
    "matchStatuses": ["finished"]
}
```

### Output

A finished match returned by a monitoring run (`change` and the `previous...` fields appear only in monitoring mode; `statistics` is cut to 3 of its 101 entries here):

```json
{
    "source": "flashscore.com",
    "status": "ok",
    "matchId": "fZCq6HE7",
    "matchUrl": "https://www.flashscore.com/match/fZCq6HE7/",
    "date": "2026-09-20",
    "utcOffsetHours": 0,
    "startTime": "2026-09-20T13:00:00.000Z",
    "country": "England",
    "league": "Premier League",
    "leagueHeader": "ENGLAND: Premier League",
    "leagueId": "dYlOSQOD",
    "leagueUrl": "https://www.flashscore.com/football/england/premier-league/",
    "round": "Round 5",
    "matchStatus": "finished",
    "statusText": "Finished",
    "statusCode": 3,
    "isLive": false,
    "isFinished": true,
    "livePeriod": null,
    "liveMinute": null,
    "statusChangedAt": "2026-09-20T14:57:59.000Z",
    "homeTeam": "Manchester City",
    "homeTeamId": "Wtn9Stg0",
    "homeTeamSlug": "manchester-city",
    "homeTeamShort": "MCI",
    "awayTeam": "Sunderland",
    "awayTeamId": "WSzc94ws",
    "awayTeamSlug": "sunderland",
    "awayTeamShort": "SUN",
    "homeScore": 5,
    "awayScore": 3,
    "scoreText": "5-3",
    "winner": "home",
    "winnerTeam": "Manchester City",
    "decidedBy": "regular-time",
    "halfTimeHomeScore": 3,
    "halfTimeAwayScore": 2,
    "regularTimeHomeScore": 5,
    "regularTimeAwayScore": 3,
    "extraTimeHomeScore": null,
    "extraTimeAwayScore": null,
    "penaltiesHomeScore": null,
    "penaltiesAwayScore": null,
    "homeRedCards": 0,
    "awayRedCards": 0,
    "info": null,
    "scrapedAt": "2026-09-21T15:00:00.000Z",
    "liveUpdatesApplied": true,
    "feedAgeSeconds": null,
    "change": "status-changed",
    "previousMatchStatus": "live",
    "previousScoreText": "4-3",
    "previousHomeScore": 4,
    "previousAwayScore": 3,
    "previousReturnedAt": "2026-09-20T17:08:00.000Z",
    "eventsStatus": "ok",
    "goals": [
        {
            "period": "1st Half",
            "minute": "9",
            "minuteValue": 9,
            "team": "home",
            "player": "Fernandez E.",
            "playerId": "nZnbEVWP",
            "type": "goal",
            "assist": null,
            "assistId": null,
            "homeScoreAfter": 1,
            "awayScoreAfter": 0
        },
        {
            "period": "1st Half",
            "minute": "12",
            "minuteValue": 12,
            "team": "away",
            "player": "Brobbey B.",
            "playerId": "pfAvgQUT",
            "type": "goal",
            "assist": "Le Fee E.",
            "assistId": "hC5yfF2A",
            "homeScoreAfter": 1,
            "awayScoreAfter": 1
        },
        {
            "period": "1st Half",
            "minute": "29",
            "minuteValue": 29,
            "team": "home",
            "player": "Cherki R.",
            "playerId": "vm0eu2V3",
            "type": "goal",
            "assist": "Semenyo A.",
            "assistId": "r1Gz1yPk",
            "homeScoreAfter": 2,
            "awayScoreAfter": 1
        },
        {
            "period": "1st Half",
            "minute": "33",
            "minuteValue": 33,
            "team": "away",
            "player": "Brobbey B.",
            "playerId": "pfAvgQUT",
            "type": "goal",
            "assist": "Meunier T.",
            "assistId": "WUyrShAL",
            "homeScoreAfter": 2,
            "awayScoreAfter": 2
        },
        {
            "period": "1st Half",
            "minute": "43",
            "minuteValue": 43,
            "team": "home",
            "player": "Semenyo A.",
            "playerId": "r1Gz1yPk",
            "type": "goal",
            "assist": "Guehi M.",
            "assistId": "KEeklutO",
            "homeScoreAfter": 3,
            "awayScoreAfter": 2
        },
        {
            "period": "2nd Half",
            "minute": "57",
            "minuteValue": 57,
            "team": "home",
            "player": "Semenyo A.",
            "playerId": "r1Gz1yPk",
            "type": "goal",
            "assist": null,
            "assistId": null,
            "homeScoreAfter": 4,
            "awayScoreAfter": 2
        },
        {
            "period": "2nd Half",
            "minute": "59",
            "minuteValue": 59,
            "team": "away",
            "player": "Brobbey B.",
            "playerId": "pfAvgQUT",
            "type": "goal",
            "assist": "Angulo N.",
            "assistId": "GtWYwr5H",
            "homeScoreAfter": 4,
            "awayScoreAfter": 3
        },
        {
            "period": "2nd Half",
            "minute": "81",
            "minuteValue": 81,
            "team": "home",
            "player": "Haaland E.",
            "playerId": "UmV9iQmE",
            "type": "goal",
            "assist": "Gvardiol J.",
            "assistId": "86K1f1fd",
            "homeScoreAfter": 5,
            "awayScoreAfter": 3
        }
    ],
    "goalsText": "9' Fernandez E. [home]; 12' Brobbey B. [away]; 29' Cherki R. [home]; 33' Brobbey B. [away]; 43' Semenyo A. [home]; 57' Semenyo A. [home]; 59' Brobbey B. [away]; 81' Haaland E. [home]",
    "goalsListed": 8,
    "goalsComplete": true,
    "cards": [
        {
            "period": "1st Half",
            "minute": "8",
            "minuteValue": 8,
            "team": "away",
            "player": "Methalie D.",
            "playerId": "v71VNtNg",
            "card": "yellow",
            "reason": "Roughing",
            "onBench": false
        }
    ],
    "substitutions": [
        {
            "period": "2nd Half",
            "minute": "60",
            "minuteValue": 60,
            "team": "away",
            "playerIn": "Fofana M.",
            "playerInId": "6N65iDOI",
            "playerOut": "Angulo N.",
            "playerOutId": "GtWYwr5H"
        },
        {
            "period": "2nd Half",
            "minute": "68",
            "minuteValue": 68,
            "team": "away",
            "playerIn": "Isidor W.",
            "playerInId": "veOg2tx3",
            "playerOut": "Sadiki N.",
            "playerOutId": "UJnCIUV6"
        },
        {
            "period": "2nd Half",
            "minute": "75",
            "minuteValue": 75,
            "team": "home",
            "playerIn": "Doku J.",
            "playerInId": "lMHcYK4f",
            "playerOut": "Ndiaye I.",
            "playerOutId": "Im0c6Oy7"
        },
        {
            "period": "2nd Half",
            "minute": "79",
            "minuteValue": 79,
            "team": "away",
            "playerIn": "Hume T.",
            "playerInId": "CfLIw4XG",
            "playerOut": "Meunier T.",
            "playerOutId": "WUyrShAL"
        },
        {
            "period": "2nd Half",
            "minute": "85",
            "minuteValue": 85,
            "team": "home",
            "playerIn": "O'Reilly N.",
            "playerInId": "xOrYaNWc",
            "playerOut": "Cherki R.",
            "playerOutId": "vm0eu2V3"
        }
    ],
    "missedPenalties": [],
    "periods": [
        {
            "period": "1st Half",
            "homeScore": 3,
            "awayScore": 2
        },
        {
            "period": "2nd Half",
            "homeScore": 2,
            "awayScore": 1
        }
    ],
    "referee": "Jones R.",
    "venue": "Etihad Stadium",
    "city": "Manchester",
    "attendance": 60312,
    "venueCapacity": 61038,
    "statisticsStatus": "ok",
    "statistics": [
        {
            "period": "Match",
            "group": "Top stats",
            "name": "Expected goals (xG)",
            "home": "2.81",
            "away": "3.57"
        },
        {
            "period": "Match",
            "group": "Top stats",
            "name": "Ball possession",
            "home": "55%",
            "away": "45%"
        },
        {
            "period": "Match",
            "group": "Top stats",
            "name": "Total shots",
            "home": "16",
            "away": "17"
        }
    ],
    "homePossession": 55,
    "awayPossession": 45,
    "homeShots": 16,
    "awayShots": 17,
    "homeShotsOnTarget": 6,
    "awayShotsOnTarget": 9,
    "homeCorners": 6,
    "awayCorners": 5,
    "homeXg": 2.81,
    "awayXg": 3.57,
    "homeFouls": 14,
    "awayFouls": 14,
    "homeYellowCards": 0,
    "awayYellowCards": 1,
    "homeOffsides": 0,
    "awayOffsides": 0,
    "roundStatus": "ok"
}
```

Notes on the columns:

- `homeScore` / `awayScore` are null before kick-off. For a match decided on penalties they are the goals after extra time; the shoot-out is in `penaltiesHomeScore` / `penaltiesAwayScore`. `regularTimeHomeScore` is the score after 90 minutes, `extraTimeHomeScore` after extra time (null when there was none).
- `halfTimeHomeScore` / `halfTimeAwayScore` are filled once the first half is over.
- `homeRedCards` / `awayRedCards` count red cards (including second yellows) as Flashscore shows them on the list; null before kick-off.
- `livePeriod` is `first-half`, `half-time`, `second-half`, `extra-time`, `break` or `penalties`. `liveMinute` is worked out the way Flashscore's page does it (minutes since the period started, `45+2` / `90+3` in added time) and can be a minute off the page.
- `statusCode` is Flashscore's own status number; `statusText` is Flashscore's text for it; `matchStatus` is one of `scheduled`, `live`, `finished`, `walkover`, `awarded`, `cancelled`, `postponed`, `interrupted`, `abandoned`, `delayed`, `awaiting-updates`, `to-finish` (or `ended` / `unknown` for a status number Flashscore adds later).
- `goals[].team` is the side the goal counts for; an own goal (`type: "own-goal"`) is credited to the other team, so `player` plays for the opposite side. `goals[].type` is `goal`, `penalty` or `own-goal`. Penalty shoot-out kicks are not listed as goals.
- `cards[].card` is `yellow`, `second-yellow` or `red`; `onBench` is true for a card shown to someone not on the pitch.
- `eventsStatus`: `ok`, `no-incidents-listed` (Flashscore lists only the half scores for this match, common in lower leagues), `not-available` (Flashscore returned no events at all for this match), `not-started`, `unreadable` or `not-requested`. Lower leagues often list a goal without the scorer's name (`player` is null, shown as `?` in `goalsText`). `goalsListed` is how many goals have a named scorer; `goalsComplete` is true only when every goal scored has a named scorer.
- `statisticsStatus`: `ok`, `not-available` (Flashscore has no statistics for this match), `not-started`, `unreadable` or `not-requested`. The `home...` / `away...` statistic columns are numbers (possession in percent); `statistics` keeps Flashscore's text such as `85% (406/475)`. xG is only there for leagues where Flashscore shows it.
- `roundStatus`: `ok`, `not-shown` (the match page shows no round), `unreadable` or `not-requested`.
- `info` is Flashscore's note on the match, such as `First leg result: 2-1. Aggregate: 3-1.`
- `change` (monitoring): `"first-check"` (not returned before for this filter set), `"status-changed"` or `"score-changed"`.
- Odds, TV listings, line-ups and commentary text are not included.

#### Rows that are not charged

When something is not returned, a row says why. These rows have no `matchId` and cost nothing:

| `status` | Meaning |
|---|---|
| `no-results` | Flashscore lists no matches for the day(s) asked for. |
| `no-filter-match` | Matches were read, none fit your filters. |
| `no-change` | Monitoring: no match changed since its last returned row. |
| `not-returned` | More matches fit than `maxMatches`; the row says how many. |
| `budget-reached` | The run hit its maximum total charge; the row says how many matches were not returned. |
| `day-out-of-range` | Flashscore did not return the day (outside its 7-back / 7-ahead window). |
| `blocked` | Flashscore refused the request even after retrying. |
| `unreadable` | Flashscore's answer could not be read. Nothing is guessed. |
| `invalid-input` | The input could not be used; nothing was requested. |

### Monitoring

Run the Actor on a schedule with `monitoringMode` on. The first run returns every match that fits your filters (with `changeDetail: "finished"`, every match that has already ended). Later runs compare each match with the row last returned for it and return only the ones that changed, with the previous score and status next to the new ones, and with fresh goals, cards and statistics.

- Every match compared is a **check**, also the first time a match is seen. A match that was already returned in a final state (finished, walkover, awarded, cancelled or abandoned) and has not changed is not charged a check.
- A match is listed on the day it starts. For a schedule that runs across midnight, put `["yesterday", "today"]` in `days`, or a late match that ends after midnight drops off the list before its result is returned.
- With `matchStatuses: ["live"]` a match leaves your filter when it ends, so its final result is not returned. Keep `finished` in the filter to receive results.
- A match that looks older than the row already returned for it (an older cached copy of Flashscore's feed, or a goal Flashscore took back) is not returned as a change.
- Rows are remembered per filter set (`countries`, `leagues`, `teams`, `matchStatuses`, `changeDetail`) for 10 days after the match starts, so two schedules with different filters do not affect each other.
- `maxMatches` is not used in monitoring mode, so no match is left out behind the limit. For the same reason monitoring needs at least one of `countries`, `leagues` or `teams`: with no filter, the first run would return every match of the day (up to about 1,800). Turn on `monitorEveryLeague` if that is what you want.
- A row is remembered only after it was delivered and charged. If a run hits its maximum total charge, the matches it could not return are not remembered as returned, so they still count as changed when they are compared again.
- Do not put the same filter set in two schedules that can run at the same time: the remembered rows live in a key-value store without atomic updates, so this cannot be fully prevented.

### Pricing

Pay per event, no start fee:

- **$5.00 per 1,000 match rows**, charged only for rows with `status: "ok"`. Goals, cards, statistics and the round are included in the row price.
- **$0.30 per 1,000 match checks** in monitoring mode.

Example: 20 matches you follow, checked every 5 minutes for 3 hours, is 720 checks, which is **$0.22**, plus $0.005 for each change row (a goal, a red card, kick-off or full time). Checking every match of a busy Saturday (about 1,800) every 5 minutes for 12 hours would be 259,200 checks, so use filters for frequent schedules.

### Notes

- Unofficial. Public data only. Not affiliated with Flashscore or Livesport. Data is what Flashscore shows publicly and can change or be corrected by Flashscore.
- Only Flashscore's football feeds and match pages that its robots.txt allows are read; standings, draws and news are not.
- Requests are spaced out: a 0.4 s pause before each request, and at most 3 matches' details in flight at once. With goals, statistics and the round on, a run takes about 0.75 s per match row (1,329 rows took 16 minutes on 2026-09-21); the log reports progress every 100 rows.

# Actor input Schema

## `days` (type: `array`):

Which days to read: today, yesterday, tomorrow, a number of days from today (-7 to 7), or a date as YYYY-MM-DD. Flashscore's daily feed covers 7 days back and 7 days ahead of today; other days are refused before anything is requested. Empty = today. A match is returned under the day Flashscore's own page lists it on.

## `utcOffsetHours` (type: `integer`):

Where a day starts and ends, as on Flashscore when your browser is in that time zone. 0 = UTC. Example: -5 for New York in winter, 1 for London in summer, 9 for Tokyo. startTime is always in UTC.

## `countries` (type: `array`):

Keep only matches of competitions under these countries or regions, as Flashscore names them (case-insensitive, whole name): England, Spain, Brazil, Europe, World, South America... Empty = all.

## `leagues` (type: `array`):

Keep a match if its competition matches one of these. Write the Flashscore header (england: premier league, spain: laliga), part of it (champions league), the league path (england/premier-league) or a league URL from flashscore.com. Headers are matched as a partial text, so premier league alone also keeps other countries' Premier Leagues. Empty = all leagues.

## `teams` (type: `array`):

Keep a match if one of these appears in the home or away team name or slug (case-insensitive, partial): arsenal, real madrid, boca.

## `matchStatuses` (type: `array`):

Keep only these. live = in play (halves, half time, extra time, penalty shoot-out). finished = finished (also after extra time or penalties), walkover or awarded. scheduled = not started. other = postponed, cancelled, interrupted, abandoned, delayed and similar. Empty = all.

## `includeEvents` (type: `boolean`):

On = one extra request per returned match that has started, for goal scorers with assists and minute, yellow and red cards, substitutions, missed penalties, half scores, referee, stadium and attendance. Off = faster; those columns stay empty.

## `includeStatistics` (type: `boolean`):

On = one extra request per returned match that has started, for Flashscore's match statistics (possession, shots, shots on target, corners, fouls, and xG where Flashscore has it) for the match and each half. Off = faster; those columns stay empty.

## `includeRound` (type: `boolean`):

The round is not in Flashscore's daily feed. On = one extra small request per returned match to read it from the match page (only the first 32 KB are read). Off = faster, round is null.

## `maxMatches` (type: `integer`):

How many match rows to return. You are charged for the rows you actually receive. Between 2026-09-14 and 2026-09-20 a day carried 171 to 1,780 matches across all leagues (weekend days the most). Not used in monitoring mode, which always checks every match that fits your input.

## `monitoringMode` (type: `boolean`):

Off = return every match that fits your input. On = remember the last row returned for each match and, on later runs, return only matches that changed (see Change detail). Each match compared is a check with a small fee, also the first time; a match already returned as finished that has not changed is not charged. For a schedule that runs across midnight use days yesterday and today. Remembered per filter set, for 10 days.

## `monitorEveryLeague` (type: `boolean`):

Monitoring has no row limit, so without countries, leagues or teams its first run would return and charge every match of the day (up to about 1,800 on a weekend). Such a run is refused with a free row unless this is on.

## `changeDetail` (type: `string`):

What counts as a change in monitoring mode. score = a goal, a red card, extra-time or penalty score, or a change of match status (kick-off, full time, postponed...); half time and the minute do not count. finished = only when a match reaches a final state (finished, walkover, awarded, cancelled or abandoned): each match is returned once, with its final result.

## `resetMonitoringState` (type: `boolean`):

Clear the remembered rows for this filter set before this run, so every match counts as new again.

## `useProxy` (type: `boolean`):

On = if Flashscore answers 401, 403, 429 or 503, the request is retried through a proxy. Off = retried directly, then returned as a free row.

## Actor input object example

```json
{
  "days": [
    "yesterday"
  ],
  "utcOffsetHours": 0,
  "countries": [],
  "leagues": [],
  "teams": [],
  "matchStatuses": [],
  "includeEvents": true,
  "includeStatistics": true,
  "includeRound": true,
  "maxMatches": 20,
  "monitoringMode": false,
  "monitorEveryLeague": false,
  "changeDetail": "score",
  "resetMonitoringState": false,
  "useProxy": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per football match on Flashscore for the days asked for: country, league, round, start time, home and away teams with ids, score, half-time, 90-minute, extra-time and penalty scores, winner, red cards and match status (with the minute while live); for matches that have started, goal scorers with assists and minute, cards, substitutions, missed penalties, referee, stadium, attendance and match statistics including xG where Flashscore has it; in monitoring mode, what changed and the previous score. Days with no matches, filters that match nothing, refused requests and runs that hit their maximum charge come back as free rows that say why.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "days": [
        "yesterday"
    ],
    "maxMatches": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/football-results-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "days": ["yesterday"],
    "maxMatches": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("neverempty/football-results-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "days": [
    "yesterday"
  ],
  "maxMatches": 20
}' |
apify call neverempty/football-results-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/football-results-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/2UAZDf1oQOaAN50rN/builds/080GO7Rr4El2B597J/openapi.json
