# Flashscore Scraper - Results, Stats, Lineups & Bookmaker Odds (`artsiom_k/flashscore-scraper`) Actor

Flashscore data for football, tennis, basketball, hockey and 13 more sports: results with period scores, match statistics (xG, possession, shots), lineups with ratings, incidents and opening/closing odds from ~20 bookmakers. By day or whole tournament seasons from the archive.

- **URL**: https://apify.com/artsiom_k/flashscore-scraper.md
- **Developed by:** [Artsiom Kunitsyn](https://apify.com/artsiom_k) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 results

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

## Flashscore Scraper - Results, Stats, Lineups & Bookmaker Odds

Match data from [Flashscore](https://www.flashscore.com) for **football (soccer), tennis, basketball, ice hockey,
American football, baseball, handball, rugby, volleyball, futsal, darts, table tennis, esports** and more:

- **Matches**: final score, score per half / quarter / period / set, regular-time score, status (finished, after
  extra time, after penalties, retired, walkover, postponed ...), winner, tournament, round.
- **Match statistics**: expected goals (xG), xGOT, possession, shots, big chances, corners, passes, crosses, tackles,
  duels, cards and more, for the whole match and each half (or set, quarter, period).
- **Lineups**: starters, substitutes, missing players and coaches, with formation, shirt number, nationality,
  captain and Flashscore's player and team ratings.
- **Incidents**: goals, penalties, assists, cards, substitutions and VAR from the match summary, with the score after
  each goal and Flashscore's commentary.
- **Bookmaker odds**: opening and closing odds **per bookmaker** (about 20 UK bookmakers: bet365, Betfair, Ladbrokes,
  Coral, Sky Bet, Betfred, Unibet, Betway, BetVictor ...) for 1X2, moneyline, over/under, Asian and European handicap,
  double chance, draw no bet, both teams to score, correct score and more, by full time, half, quarter or set.

Pick matches **by day** (7 days back to 7 days ahead), **by tournament and season** (whole seasons from Flashscore's
archive: the Premier League, Champions League, NBA, NHL, ATP and WTA tournaments and thousands more), or
**by match URL**. No proxy needed, so runs are fast and cheap.

### What you get

`entityType: "matches"` (the default) returns one row per match:

| Field | Example |
|---|---|
| `sport`, `match_id`, `date`, `start_time_utc` | `football`, `tW4rOkzg`, `2026-10-12`, `2026-10-12T19:00+00:00` |
| `country`, `tournament`, `round` | `England`, `Premier League`, `Round 6` |
| `home_team`, `away_team`, `home_score`, `away_score` | `Coventry`, `Newcastle`, `4`, `1` |
| `status`, `status_detail`, `winner` | `finished`, `Finished`, `Coventry` |
| `periods` | `[{"period": 1, "home": 1, "away": 0}, {"period": 2, "home": 3, "away": 1}]` |
| `home_score_regular_time`, `away_score_regular_time` | the score before extra time / penalties |
| `tournament_url`, `match_url` | Flashscore pages |

Every other type repeats the match columns (`date`, `tournament`, `home_team`, `away_team`, scores, `match_url`) and
adds:

- **`statistics`**: one row per period (`match`, `1st half`, `2nd half` ...). Each statistic is two columns,
  `home_<name>` and `away_<name>`: `home_expected_goals_xg`, `away_ball_possession`, `home_total_shots`,
  `home_shots_on_target`, `home_corner_kicks` ... Ratios like `70% (185/264)` become `home_passes` = 185,
  `home_passes_total` = 264 and `home_passes_pct` = 70.
- **`lineups`**: one row per player or coach: `side`, `team`, `role` (`starting`, `substitute`, `missing`, `coach`),
  `formation`, `player`, `shirt_number`, `nationality`, `rating`, `team_rating`, `captain`, `goalkeeper`.
- **`incidents`**: one row per incident: `period`, `minute`, `added_time`, `team`, `incident` (`Goal`, `Penalty`,
  `Yellow Card`, `Substitution - Out` ...), `player`, `incident2`/`player2` (the assist, or the player coming on),
  `home_score_after`, `away_score_after`, `commentary`.
- **`odds`**: one row per bookmaker, market and selection: `bookmaker`, `market` (`home_draw_away`, `home_away`,
  `over_under`, `asian_handicap` ...), `market_period`, `line`, `selection` (`home`, `draw`, `away`, `over`,
  `under`, `yes`, `no` or a score), `opening_odds`, `current_odds` (decimal; the closing odds once the match is over).

### How to use it

- **Yesterday's and today's football results** (the default): just run it.
- **Several sports**: pick them under **Sports**, e.g. tennis and basketball.
- **A whole season**: Tournaments = `https://www.flashscore.com/football/england/premier-league/`, Seasons =
  `2024/2025`, clear **Max items**. Seasons = `all` for every season in the archive.
- **xG and shots for a season**: the same, with `entityType: "statistics"`.
- **Closing odds for backtesting**: `entityType: "odds"` for a season. Pick the markets and periods you need: a
  football match has about 500 odds rows for 1X2, totals and Asian handicaps from 20 bookmakers, and ~3,000 with
  every market.
- **Pre-match odds**: `entityType: "odds"`, **Match status** = upcoming.
- **A daily feed**: schedule it daily with the default dates, **Max items** cleared and **Mode** = incremental.

### Input

| Field | Default | What it does |
|---|---|---|
| `entityType` | `matches` | `matches`, `statistics`, `lineups`, `incidents` or `odds`. |
| `sports` | football | Listing by day: which sports. |
| `dateFrom`, `dateTo` | yesterday and today | Listing by day covers 7 days back to 7 ahead. With tournaments, the dates only filter. |
| `matchStatus` | `finished` | `finished`, `upcoming` or `all`. |
| `tournaments`, `seasons` | none | Tournament URLs and which seasons (`2024/2025`, `24/25`, `2024`, `all`; empty = current). |
| `matchUrls` | none | Match URLs or ids. |
| `oddsCountry` | `GB` | Odds: the bookmakers of this country (the UK has ~20). |
| `oddsMarkets` | 1X2, moneyline, over/under, Asian handicap | Odds: which markets; empty = all. |
| `oddsPeriods` | full time | Odds: which parts of the match; empty = all. |
| `maxItems` | `50` | Row cap. Clear it for everything. |
| `mode` | `full` | `incremental` skips finished matches earlier incremental runs returned. |
| `concurrency` | `10` | Requests in parallel. |

### Good to know

- Times and dates are UTC.
- Statistics, lineups and odds exist mostly for the bigger competitions; smaller leagues often have results only.
- In tennis, `home_team`/`away_team` are player 1 and player 2 and the scores are sets; `periods` holds the games per
  set.
- Odds rows carry opening and closing odds, not every move in between.
- Standings are not included.

### Related sports data scrapers

- [SofaScore Scraper](https://apify.com/artsiom_k/sofascore-scraper) — results, team statistics, lineups with player ratings and per-player stats, incidents and odds for 21 sports.
- [TennisExplorer Scraper](https://apify.com/artsiom_k/tennisexplorer-scraper) — ATP/WTA/ITF results to the 1990s, bookmaker odds and SofaScore serve/return statistics.
- [Action Network Scraper](https://apify.com/artsiom_k/actionnetwork-scraper) — US sportsbook odds, public betting splits, line movement, props, injuries and futures.
- [Sports Odds History Scraper](https://apify.com/artsiom_k/sports-odds-history-scraper) — opening and closing lines per sportsbook since 2021 and ATS results since 2006.
- [Smarkets Betting Exchange Scraper](https://apify.com/artsiom_k/smarkets-scraper) — betting exchange back and lay odds, matched volume, results and traded-price history.
- [Kalshi & Polymarket Scraper](https://apify.com/artsiom_k/prediction-markets-scraper) — prediction market odds, settled results and price history.

# Actor input Schema

## `entityType` (type: `string`):

One row per match, per match period (statistics), per player (lineups), per incident or per bookmaker odds selection.

## `sports` (type: `array`):

Listing by day: which sports. Ignored when Tournaments or Match URLs are given.

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

First day (YYYY-MM-DD, UTC). Leave both dates empty for yesterday and today (upcoming: today and tomorrow). Listing by day covers 7 days back to 7 days ahead; for older matches use Tournaments, where the dates only filter.

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

Last day (YYYY-MM-DD, UTC).

## `matchStatus` (type: `string`):

Finished matches have results, statistics and closing odds; upcoming ones have fixtures and current odds.

## `tournaments` (type: `array`):

Flashscore tournament URLs, e.g. https://www.flashscore.com/football/england/premier-league/ or https://www.flashscore.com/tennis/atp-singles/wimbledon/. Returns whole seasons (see Seasons) from Flashscore's archive.

## `seasons` (type: `array`):

Tournaments only: which seasons, e.g. 2024/2025, 24/25 or 2024 (calendar-year events). Empty = the current season. "all" = every season in the archive.

## `matchUrls` (type: `array`):

Flashscore match URLs or 8-character match ids. Overrides every other way of picking matches.

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

Odds only: Flashscore shows the bookmakers licensed in a country. The UK has the most.

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

Odds only: which markets. Empty = all. A football match has ~3,000 odds rows across all markets, periods and ~20 UK bookmakers.

## `oddsPeriods` (type: `array`):

Odds only: which parts of the match. Empty = all.

## `maxItems` (type: `integer`):

Stop after this many rows. Clear it for everything in range.

## `mode` (type: `string`):

"incremental" remembers the finished matches earlier incremental runs with the same settings returned and skips them, so a daily schedule gets only new results.

## `concurrency` (type: `integer`):

Requests in parallel.

## `proxyConfiguration` (type: `object`):

Not needed: Flashscore answers without a proxy. Available in case a shared IP gets limited.

## Actor input object example

```json
{
  "entityType": "matches",
  "sports": [
    "football"
  ],
  "matchStatus": "finished",
  "oddsCountry": "GB",
  "oddsMarkets": [
    "home_draw_away",
    "home_away",
    "over_under",
    "asian_handicap"
  ],
  "oddsPeriods": [
    "full_time",
    "full_time_over_time"
  ],
  "maxItems": 50,
  "mode": "full",
  "concurrency": 10
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("artsiom_k/flashscore-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("artsiom_k/flashscore-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 '{}' |
apify call artsiom_k/flashscore-scraper --silent --output-dataset

```

## MCP server setup

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