# Flashscore Football Scraper: Scores, xG, Lineups, Odds, Tables (`steadyscrape/flashscore-football-scraper`) Actor

Every football match of a day from Flashscore: fixtures, live scores, results with half-time and penalties, plus xG statistics, lineups with player ratings, goals and cards, referee and venue, head-to-head, bookmaker odds with opening prices and league tables. 27 more sports. No browser.

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

## Pricing

from $1.00 / 1,000 matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Flashscore Football Scraper — live scores, fixtures, results, xG, lineups, odds and league tables

Every football match of a day from **Flashscore**, in every competition it covers: fixtures, live scores and results
with half-time, extra time and penalty shootouts. Add, for the same matches in the same run:

- **Match statistics** with **expected goals (xG)**, possession, shots, passes, corners, fouls and cards — for the match and each half
- **Lineups** with formations, team ratings, shirt numbers, captains, goalkeepers and **Flashscore player ratings**
- **Events**: every goal with its assist and the score after it, every card and substitution with its minute
- **Match information**: referee, venue, city, capacity, attendance
- **Head-to-head** and each team's recent form
- **Betting odds** from every bookmaker of a country, each price with its **opening price**
- **League tables** with every group, form and what each place leads to — once per competition

Plain HTTP against Flashscore's own feeds: no browser, no login, no proxy. A day of football (300+ matches) lists in
seconds. **27 more sports** list the same way: basketball, ice hockey, baseball, American football, handball,
volleyball, rugby, cricket, darts, futsal, eSports and more.

### What makes it different

- **Tables in the same run.** Ask for the standings and every competition of your matches comes back as one extra
  row with its whole table — fetched and charged once per competition, however many of its matches you scrape.
- **xG, lineups with ratings and opening odds together.** Most football scrapers give a listing, or a listing plus
  one kind of detail. Here a match row can carry all of it, and you pay the detail price only when it delivers some.
- **A section Flashscore does not have is never fetched.** Each match's own feed says which sections exist (a lower
  league has no statistics, a match not played yet has no lineups), so you are never charged for empty requests.
- **Your limits are checked before any detail is requested**: the maximum number of matches and your run's spending
  limit cut the run before the work, not after it.
- **Penalties done right**: regular time, after extra time and the shootout are separate scores, and two-legged ties
  say which side goes through, with Flashscore's aggregate note.

### Use cases

- **Betting models and value betting**: odds of 20 UK bookmakers with their opening prices, xG and form, every day on a schedule.
- **Live score feeds** for apps, bots and dashboards: run every few minutes with `matchStatus: live`.
- **Fantasy football and scouting**: lineups with player ratings, goals, assists and cards per match.
- **Football analytics and research**: statistics per half for whole leagues, with tables and head-to-head.
- **Content and newsletters**: yesterday's results and today's fixtures by country or competition.

### Input

| field | what it does |
|---|---|
| `sport` | `football` by default, or one of 27 other sports |
| `dateFrom`, `dateTo` | `today`, `yesterday`, `tomorrow`, `-3`, `+2` or `2026-10-12`; up to a week either side of today |
| `utcOffsetHours` | where your day starts; match times are always UTC |
| `matches` | match links or ids instead of days |
| `matchStatus` | `scheduled`, `live`, `finished`, `cancelled` |
| `countries`, `leagues`, `teams` | parts of names, case and accents ignored: `England`, `Premier League`, `Arsenal` |
| `includeStatistics`, `includeLineups`, `includeEvents`, `includeHeadToHead`, `includeOdds` | the detail sections |
| `oddsCountry`, `oddsRegion` | whose bookmakers: `GB` (about 20), `US` (+ `USNY`), `DE`, `IT`, `ES`… |
| `oddsMarkets` | `1x2` and `over_under` by default; also Asian and European handicap, both teams to score, double chance, draw no bet, half-time/full-time, correct score, odd/even |
| `oddsFullTimeOnly` | `true` by default; `false` adds the first-half and second-half markets |
| `includeStandings` | one table row per competition of the run |
| `recentMatchesPerTeam`, `maxMatches` | limits |

```json
{
  "dateFrom": "yesterday",
  "countries": ["England", "Spain"],
  "leagues": ["Premier League", "LaLiga"],
  "matchStatus": ["finished"],
  "includeStatistics": true,
  "includeLineups": true,
  "includeEvents": true,
  "includeStandings": true
}
```

**Full odds are heavy**: every market and half of 20 bookmakers is about 800 KB per match. The defaults keep 1X2 and
over/under for the full match; widen them only for the markets you use.

### Output

One row per match (`type: "match"`) and, when asked, one per competition (`type: "standings"`). Every row has a
`status`: only `ok` rows are charged; `no_matches`, `not_found` and `blocked` say why there is nothing to charge.

```json
{
  "type": "match",
  "status": "ok",
  "sport": "football",
  "matchId": "pfFSbE2B",
  "url": "https://www.flashscore.com/match/pfFSbE2B/",
  "startTime": "2026-10-12T19:00:00.000Z",
  "matchStatus": "finished",
  "matchStatusText": "Finished",
  "tournament": { "id": "j1MnZ14E", "stageId": "lEqmiyVI", "name": "Liga Profesional - Clausura", "country": "Argentina", "url": "https://www.flashscore.com/football/argentina/liga-profesional/" },
  "home": { "name": "Lanus", "shortName": "LAN", "id": "Y9yh1J7G", "url": "https://www.flashscore.com/team/lanus/Y9yh1J7G/", "logoUrl": "https://static.flashscore.com/res/image/data/I7GXcZiT-rRPTjfbN.png", "redCards": 0 },
  "away": { "name": "Velez Sarsfield", "shortName": "VEL", "id": "UsCR8gFd", "redCards": 0 },
  "winner": "home",
  "score": { "home": 2, "away": 0 },
  "halfTime": { "home": 0, "away": 0 },
  "regularTime": { "home": 2, "away": 0 },
  "afterExtraTime": null,
  "penalties": null,
  "statistics": [{ "period": "match", "group": "Top stats", "name": "Expected goals (xG)", "home": { "text": "1.57", "value": 1.57 }, "away": { "text": "0.56", "value": 0.56 } }],
  "lineups": { "home": { "formation": "1-4-2-3-1", "rating": 7.4, "starting": [{ "name": "Besozzi L.", "number": 77, "country": "Argentina", "captain": false, "goalkeeper": false, "rating": 7.4 }] } },
  "events": { "periods": [{ "name": "1st Half", "home": 0, "away": 0 }, { "name": "2nd Half", "home": 2, "away": 0 }], "incidents": [{ "period": "2nd Half", "minute": "59'", "side": "home", "type": "goal", "participants": [{ "role": "goal", "name": "Marcich S." }, { "role": "assistance", "name": "Besozzi L." }], "scoreAfter": { "home": 1, "away": 0 } }] },
  "matchInfo": { "referee": "Martinez S.", "venue": "Estadio Ciudad de Lanús – Néstor Díaz Pérez", "city": "Lanús", "capacity": 47090, "attendance": null },
  "odds": [{ "bookmaker": "BetMGM.uk", "market": "1x2", "period": "match", "selections": [{ "outcome": "home", "odds": 2.38, "openingOdds": 2.2 }, { "outcome": "draw", "odds": 3.7 }, { "outcome": "away", "odds": 2.6 }] }]
}
```

A standings row carries `tournament` and `groups`: each group's `table` with `rank`, `team`, `played`, `wins`,
`draws`, `losses`, `goalsFor`, `goalsAgainst`, `points`, `form` (`w`, `d`, `l`, newest first) and `qualification`
(`Promotion - …`, `Relegation`…).

Other sports give the same match row; `periods` holds their quarters, periods, sets or innings.

### Pricing

Pay per event, no start fee:

| event | price |
|---|---|
| `match` — a match row without details | US$0.001 |
| `match-with-details` — a match row that delivers at least one detail section | US$0.003 |
| `standings` — a competition's table | US$0.002 |

Rows with a status other than `ok` are free. A detail section Flashscore does not have is not fetched and not charged.

### Limits

- Flashscore publishes days up to a week before and after today.
- Statistics, lineups and ratings exist for the competitions Flashscore covers in depth; lower leagues often have
  only the score and the events.
- Bookmakers take their prices down after a match: ask for odds before and during it.
- A match asked for by link carries its score but not the per-half scores or red cards; ask for events to get them.

### Is it legal?

The Actor reads pages and feeds that Flashscore serves publicly, without logging in, and collects sports results and
statistics, not personal data beyond the names of professional players and officials as they appear in public
results. You are responsible for how you use the data; check the terms that apply to you and your jurisdiction.

# Actor input Schema

## `sport` (type: `string`):

Football by default. The other sports give the same rows — teams, scores per period, status, competition — and every detail section Flashscore has for them (statistics, lineups, events, head-to-head, odds, standings). Tennis has its own Actor: Flashscore Tennis Scraper.

## `dateFrom` (type: `string`):

<code>today</code>, <code>yesterday</code>, <code>tomorrow</code>, a number of days from today (<code>-3</code>, <code>+2</code>) or a date (<code>2026-10-12</code>). Relative days are what a scheduled run wants. Flashscore publishes days up to a week either side of today.

## `dateTo` (type: `string`):

Last day of the range, written like <b>From day</b>. Leave empty for a single day.

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

Where a day starts and ends: <code>0</code> cuts days at UTC, <code>-5</code> at New York time, <code>1</code> at London summer time. Match times in the output are always UTC.

## `matches` (type: `array`):

Flashscore match links (<code>…/match/\<id>/</code> or <code>…?mid=\<id></code>), or the eight-character ids the output gives as <code>matchId</code>. When this list is not empty the days and the filters are ignored.

## `matchStatus` (type: `array`):

Leave empty for all. <b>finished</b> includes walkovers and awarded matches; <b>live</b> includes interrupted matches; <b>cancelled</b> includes postponed and abandoned ones.

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

Part of a country as Flashscore names it: <code>England</code>, <code>Spain</code>, <code>Brazil</code>, <code>Europe</code> (Champions League…), <code>World</code>. Case and accents do not matter.

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

Part of a competition name: <code>Premier League</code>, <code>LaLiga</code>, <code>Serie A</code>, <code>Champions League</code>, or <code>England: Premier League</code> to tell same-named leagues apart. Case and accents do not matter.

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

Part of a team name: <code>Arsenal</code>, <code>Real Madrid</code>, <code>Boca</code>. Case and accents do not matter.

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

Expected goals (xG), possession, shots, passes, corners, fouls, cards… for the match and each half, each with its number and its fraction (<code>80% (360/451)</code> → 80, 360, 451).

## `includeLineups` (type: `boolean`):

Formation and team rating, starting eleven and substitutes with shirt number, nationality, captain, goalkeeper and Flashscore player rating, and the coaches.

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

Every goal (with the assist and the score after it), card and substitution with its minute and players, the score of each half — and the referee, venue, city, capacity and attendance.

## `includeHeadToHead` (type: `boolean`):

Previous meetings of the two teams and the last matches of each, with competition, score and winner. Available before the match starts, which is when a model needs it.

## `includeOdds` (type: `boolean`):

Every bookmaker's prices for the match with each one's <b>opening price</b>. Available before and during the match; bookmakers take them down after it. By default only 1X2 and over/under for the full match: <b>every market of 20 bookmakers is about 800 KB per match</b>, so add markets and halves only when you need them.

## `oddsCountry` (type: `string`):

Two-letter country code: Flashscore lists the bookmakers licensed there. <code>GB</code> has the most (about 20: bet365, William Hill, Betfair, BetMGM…); <code>US</code> has FanDuel, DraftKings and BetMGM; try <code>DE</code>, <code>IT</code>, <code>ES</code>, <code>BR</code>… An unknown code gets an international set.

## `oddsRegion` (type: `string`):

For countries that license by state. <code>USNY</code> adds the bookmakers of New York to those of the US. Leave empty otherwise.

## `oddsMarkets` (type: `array`):

Which markets to keep. Leave empty for every market Flashscore lists.

## `oddsFullTimeOnly` (type: `boolean`):

Keep the prices for the whole match and leave out the first-half and second-half markets.

## `includeStandings` (type: `boolean`):

One extra row per competition of the run with its table — every group, with played, won, drawn, lost, goals, points, form and what each place leads to (promotion, playoffs, relegation). Fetched and charged once per competition, however many of its matches the run has.

## `recentMatchesPerTeam` (type: `integer`):

How many of each team's last matches the head-to-head carries. Meetings between the two are all kept.

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

Stops after this many matches, earliest first. <code>0</code> for no limit. Your run's maximum charge is respected either way, and it is checked before any detail is fetched.

## Actor input object example

```json
{
  "sport": "football",
  "dateFrom": "yesterday",
  "utcOffsetHours": 0,
  "matchStatus": [
    "finished"
  ],
  "includeStatistics": true,
  "includeLineups": false,
  "includeEvents": false,
  "includeHeadToHead": false,
  "includeOdds": false,
  "oddsCountry": "GB",
  "oddsMarkets": [
    "1x2",
    "over_under"
  ],
  "oddsFullTimeOnly": true,
  "includeStandings": false,
  "recentMatchesPerTeam": 10,
  "maxMatches": 10
}
```

# Actor output Schema

## `matches` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "dateFrom": "yesterday",
    "matchStatus": [
        "finished"
    ],
    "includeStatistics": true,
    "maxMatches": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/flashscore-football-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 = {
    "dateFrom": "yesterday",
    "matchStatus": ["finished"],
    "includeStatistics": True,
    "maxMatches": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/flashscore-football-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 '{
  "dateFrom": "yesterday",
  "matchStatus": [
    "finished"
  ],
  "includeStatistics": true,
  "maxMatches": 10
}' |
apify call steadyscrape/flashscore-football-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/flashscore-football-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/P61rHSyqRsuQebtLL/builds/pusoI0n5zkvluBrM2/openapi.json
