# Flashscore Scraper (`piotrv1001/flashscore-scraper`) Actor

Extract live scores, fixtures and results from FlashScore: kick-off times, teams, live and final scores, set and period breakdowns, winners and tournament details. Covers soccer, tennis, basketball, hockey, handball, baseball and American football, for any day within a week either side of today.

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

## Pricing

from $3.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 🚀 FlashScore Scraper

Extract **live scores, fixtures and results** from [FlashScore](https://www.flashscore.com) in structured JSON. The **FlashScore Scraper** returns a whole day's schedule in a single request — every match with its tournament, teams, start time, live or final score, set-by-set breakdown and winner — across **soccer, tennis, basketball, hockey, handball, baseball and American football**.

Pick a sport, hit run, and get a clean dataset. Running it on Apify also gives you scheduled runs, an API, webhooks, integrations with Google Sheets, Zapier and Make, automatic proxy rotation, and run monitoring — no infrastructure to maintain.

### ✨ Features

- ⚽ **Soccer-first, seven sports deep** — soccer, tennis, basketball, hockey, handball, baseball and American football, all returning the same fields.
- 🔴 **Live, finished and upcoming in one pass** — today's feed carries matches still to start, matches in play with their running score, and matches already decided.
- 🏆 **Every match placed in its tournament** — competition name, id, stage id and the FlashScore path it lives at, so rows group cleanly by league.
- 🎾 **Set and period breakdowns** — the score of each set, quarter, period or inning alongside the overall score.
- 🏅 **Teams and players in full** — id, full name, short name, slug and crest or headshot image for both sides, plus country where the sport names one.
- 📅 **A fortnight of coverage** — any day from seven back to seven ahead, so you can pull yesterday's results or next week's fixtures with one input change.
- ⚠️ **Retirements and walkovers flagged** — a `statusDetail` of `retired`, `walkover` or `after-penalties` tells you when the winner cannot be read off the score.
- ⚡ **Fast and lightweight** — an entire day of soccer, over 480 matches across 200+ tournaments, arrives in one request. No browser required.

### 💡 Why use the FlashScore Scraper?

- **Power a live-score widget or bot** with a scheduled run against today's feed.
- **Build a results history** by running the scraper daily, or backfilling the last week one day at a time.
- **Feed sports models and prediction tools** with a consistent, structured match history across seven sports.
- **Track a competition** by filtering the dataset on the tournament name or id you care about.
- **Monitor in-play matches** using the `live` status and the running score that comes with it.

### 🛠️ How to use the FlashScore Scraper

1. **Pick your sport.** `sport` accepts `soccer` (the default), `tennis`, `basketball`, `hockey`, `handball`, `baseball` or `american-football`.
2. **Pick your day.** `dayOffset` is counted from today: `0` for today, `-1` for yesterday, `3` for three days out. Anything from `-7` to `7` works.
3. **Set the match limit.** `maxItems` caps how many matches you get.
4. **Run it.** Results appear in the dataset and can be downloaded as JSON, CSV, Excel, HTML or XML, or pulled from the API.

### 📥 Input

| Field                | Type    | Description                                                                                                                         |
| -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `sport`              | string  | Which sport to return: `soccer`, `tennis`, `basketball`, `hockey`, `handball`, `baseball` or `american-football`. Default `soccer`. |
| `dayOffset`          | integer | Which day, counted from today. `0` today, `-1` yesterday, `1` tomorrow. Range `-7` to `7`. Default `0`.                             |
| `maxItems`           | integer | Maximum number of matches to return. Default `50`.                                                                                  |
| `proxyConfiguration` | object  | Proxy used for the run. The default is fine — results do not vary by country.                                                       |

Example input:

```json
{
    "sport": "soccer",
    "dayOffset": 0,
    "maxItems": 500,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### 📊 Sample output data

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
[
    {
        "matchId": "n0DIvUYs",
        "sport": "soccer",
        "tournament": {
            "id": "8189",
            "name": "PREMIER LEAGUE: Round 2",
            "stageId": "hnrqmMpc",
            "url": "/football/england/premier-league/"
        },
        "startsAt": "2026-08-21T19:00:00.000Z",
        "updatedAt": "2026-08-21T19:47:12.000Z",
        "status": "live",
        "statusDetail": "live",
        "home": {
            "id": "ppjDR086",
            "name": "Manchester City",
            "shortName": "MCI",
            "slug": "manchester-city",
            "country": "England",
            "image": "8mfxRUyd-hpqHTiSz.png"
        },
        "away": {
            "id": "Wtn9Stg0",
            "name": "Tottenham",
            "shortName": "TOT",
            "slug": "tottenham",
            "country": "England",
            "image": "OMwjPqbK-CQKBqPPZ.png"
        },
        "score": { "home": 1, "away": 0 },
        "periods": [{ "home": 1, "away": 0 }],
        "winner": null,
        "scrapedAt": "2026-08-21T19:48:03.117Z"
    }
]
```

### 📋 Data fields

| Field          | Description                                                                                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `matchId`      | FlashScore's identifier for the match                                                                                                                                                            |
| `sport`        | The sport the match belongs to                                                                                                                                                                   |
| `tournament`   | Competition object: `id`, `name`, `stageId` and `url` (a FlashScore path)                                                                                                                        |
| `startsAt`     | Start time in ISO 8601 (UTC)                                                                                                                                                                     |
| `updatedAt`    | When the match was last updated, in ISO 8601 (UTC). Only set once a match has started                                                                                                            |
| `status`       | `scheduled`, `live` or `finished`                                                                                                                                                                |
| `statusDetail` | Finer-grained state: `scheduled`, `live`, `finished`, `postponed`, `retired`, `walkover` or `after-penalties`. Unrecognised codes pass through as `unknown:<code>` rather than being mislabelled |
| `home`, `away` | Team or player object: `id`, `name`, `shortName`, `slug`, `country` and `image`. `country` is set for individual sports such as tennis and is usually empty for club teams                       |
| `score`        | Overall score, as `{ home, away }`. `null` until a match starts                                                                                                                                  |
| `periods`      | Array of `{ home, away }`, one per set, quarter, period or inning played so far                                                                                                                  |
| `winner`       | `home`, `away` or `null` — `null` while a match is unplayed or in progress, and for a draw                                                                                                       |
| `scrapedAt`    | When the row was collected, in ISO 8601 (UTC)                                                                                                                                                    |

### 💰 How much does it cost to scrape FlashScore?

The scraper uses **pay per event** pricing, so you only pay for the data you actually get:

| Event       | Price  | What it covers                                                                       |
| ----------- | ------ | ------------------------------------------------------------------------------------ |
| Actor start | $0.005 | Charged once per run                                                                 |
| Match       | $0.003 | One match with its tournament, teams, start time, status, score and period breakdown |

A default run of **50 matches costs about $0.16**. A full day of soccer — around 480 matches across 200+ tournaments — costs about **$1.45**. Apify's free tier includes $5 of monthly usage, enough to pull several full days.

### ⚙️ Tips and advanced options

- **Raise `maxItems` for a full day.** The default of `50` is a sample; a day of soccer runs to roughly 480 matches, tennis to around 200.
- **The next day or two carry the fullest fixture lists.** Today's feed only reaches to the end of today, and days further out are still filling up, so `dayOffset: 1` and `2` usually return the most scheduled matches.
- **Schedule it for live scores.** Run it every few minutes against `dayOffset: 0` and read the `live` rows — `score` and `periods` update in play, and `updatedAt` tells you how fresh each row is.
- **Backfill a week one day at a time.** Seven runs at `-1` through `-7` give you the last week of finished results.
- **Do not read the winner off the score.** For rows where `statusDetail` is `retired` or `walkover`, the win goes to the side that did *not* retire, so the winner can hold the lower score — trust the `winner` field.
- **Group by `tournament.id`, not by name.** Names carry the round (`PREMIER LEAGUE: Round 2`) and so change week to week; the id does not.

### 🧐 Good to know

- **All times are UTC.** `startsAt`, `updatedAt` and `scrapedAt` are ISO 8601 with a `Z` suffix.
- **`periods` grows as a match progresses** and holds up to five entries — enough for a five-set tennis match or four quarters plus overtime.
- **Only the current window is published.** Days outside `-7` to `7` return nothing, which is why the input rejects them.
- **`score` is sets in tennis, goals in soccer**, points in basketball and so on — it is the sport's own headline score, with the finer detail in `periods`.
- **A tournament name can be missing a round** for competitions that do not have one; the field is still returned.

### ❓ FAQ

**Which sports are supported?**
Soccer, tennis, basketball, hockey, handball, baseball and American football. Every sport returns the same fields, so one downstream schema handles them all.

**How far ahead or back can I go?**
Seven days in each direction. Beyond that FlashScore publishes nothing for the day, and the scraper rejects the input rather than finishing with an empty dataset.

**Does it return live scores?**
Yes. Matches in progress come back with `status: "live"`, the running score, the periods played so far, and an `updatedAt` timestamp.

**Can I get more than one sport in a run?**
One sport per run. Schedule one run per sport, or call the Actor once per sport through the API — a run is a single request, so it finishes in seconds.

**Why is `winner` empty on a match that finished 2-1?**
It should not be. `winner` is empty only while a match is unplayed or in progress, and for draws. If you see it empty on a decided match, open an issue.

**What does `unknown:24` in `statusDetail` mean?**
FlashScore uses a wide range of fine-grained state codes and adds new ones. Rather than guess, the scraper passes unrecognised codes through untouched. `status` is always one of the three known values, so filter on that.

**Is scraping FlashScore legal?**
The scraper only collects publicly available data and stores no personal information. FlashScore's Terms of Service still apply to you as the operator of the run, so you are responsible for making sure your use complies with applicable law and terms — consult a lawyer if you are unsure.

### 🆘 Support

**Something is broken or missing.**
Open an issue on the Actor's **Issues** tab and it will be looked at. Custom variants and bulk extractions can also be arranged.

Start extracting FlashScore live scores today! 🚀

# Actor input Schema

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

Which sport's schedule to return. Soccer is the largest feed by far; every sport returns the same fields.

## `dayOffset` (type: `integer`):

Which day to return, counted from today. `0` is today (live scores plus everything already played and still to come), `-1` yesterday, `1` tomorrow. Anything from `-7` to `7` works; outside that window nothing is published.

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

Maximum number of matches to return.

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

Proxy used for the run. The default is fine - results do not vary by country.

## Actor input object example

```json
{
  "sport": "soccer",
  "dayOffset": 0,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "sport": "soccer",
    "dayOffset": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("piotrv1001/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 = {
    "sport": "soccer",
    "dayOffset": 0,
}

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

```

## MCP server setup

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