# Flashscore Scraper - Results, Fixtures & Live Scores (`cirkit/flashscore-results-scraper`) Actor

Scrape Flashscore match results, fixtures and live scores across 28 sports: competition, country, UTC kickoff, final and live score, winner, period-by-period breakdown and both teams. Any date within today plus or minus 7 days. No login, one flat price.

- **URL**: https://apify.com/cirkit/flashscore-results-scraper.md
- **Developed by:** [Crikit](https://apify.com/cirkit) (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

$0.80 / 1,000 match results

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?

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

### What is Flashscore Scraper?

**Flashscore Scraper** lets you extract match results, upcoming fixtures and live scores from Flashscore across 28 sports, helping you build a sports results database, back-test a betting or fantasy model, and keep a scoreboard, app or newsletter fed without paying for a sports data API.

- **Build a results database in one run:** pick your sports and a date range and get every match Flashscore lists worldwide, with the competition, the country, the UTC kick-off time, the final score and the winner. A single run over a week of football, tennis, basketball, hockey and nine other sports returned 8,951 matches across 931 competitions and 129 countries in 17 seconds.
- **Back-test with period-level detail:** every finished match carries the score broken out by period, so you get half-time football scores, tennis sets with tie-break points, basketball quarters, hockey periods, volleyball sets and baseball innings, not just the final line.
- **Track fixtures before they happen:** the same run returns the schedule up to 7 days ahead, so you can pre-build a slate, publish a fixture list, or line up which matches to watch.
- **Follow live matches:** matches in progress come back flagged `isLive` with the score as it stands, so a scheduled run every few minutes is a live scoreboard.
- **One actor for every sport:** football, tennis, basketball, hockey, baseball, cricket, darts, MMA and 20 more. Most Flashscore scrapers on the Store cover one sport, which means one subscription per sport and one output shape per sport. This is one input, one schema, one price.

Flashscore has no public API and no export button. Its own site shows one sport and one day at a time.

### What data does Flashscore Scraper extract?

- ⚽️ Sport and Flashscore sport id (`sport`, `sportSlug`, `sportId`)
- 🏆 Competition name, category and stage (`competition`, `competitionCategory`, `competitionStage`)
- 🌍 Country or region of the competition (`country`)
- 🔗 Direct link to the competition page (`competitionUrl`)
- 📅 Match date and exact kick-off time in UTC (`matchDate`, `startTime`, `startTimestamp`)
- 🚦 Status: scheduled, live or finished (`status`), plus the live flag (`isLive`)
- 🏠 Home team or player, short code and id (`homeTeam`, `homeTeamShort`, `homeTeamId`)
- 🛫 Away team or player, short code and id (`awayTeam`, `awayTeamShort`, `awayTeamId`)
- 🖼 Crest or photo URL for both sides (`homeTeamLogo`, `awayTeamLogo`)
- 🇺🇳 Nationality of both players in individual sports (`homeTeamCountry`, `awayTeamCountry`)
- 🔢 Final or live score for both sides (`homeScore`, `awayScore`)
- 🥇 Winner: home, away or draw (`winner`)
- 📊 Score by period, with tie-break points where the sport has them (`periodScores`)
- ✅ Whether the match actually produced a result (`hasResult`), so postponed and abandoned games are not read as 0-0
- 📝 Aggregate and extra-time notes such as "First leg result: 0-4. Aggregate: 0-5." (`note`)
- 🔗 Direct link to the match page (`matchUrl`)
- ⏱ When Flashscore last touched the match (`lastUpdated`) and when this row was scraped (`scrapedAt`)

### How to use Flashscore Scraper

1. Click **Try for free** and open the input form.
2. Pick one or more **Sports**. Football and tennis carry by far the most fixtures.
3. Set **Date from** and **Date to**. Use a date like `2026-09-14`, or a day offset like `-1` for yesterday and `0` for today, which is what you want on a schedule so the input never goes stale.
4. Optionally narrow by **Match status**, **Countries**, **Competitions** or **Teams**. Filters run before billing, so you are never charged for rows your own filter removed.
5. Set **Max results** as your budget cap and click **Start**. Export to JSON, CSV, Excel or Google Sheets, or pull the dataset from the API.

### Input

```json
{
  "sports": ["football", "tennis"],
  "dateFrom": "-1",
  "dateTo": "1",
  "matchStatus": ["finished"],
  "countries": ["England", "Spain"],
  "competitions": ["Premier League", "LaLiga"],
  "maxItems": 500,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

Every field is optional except `sports`. Leaving `dateFrom` and `dateTo` empty collects today.

### Output

One row per match. A finished football match looks like this:

```json
{
  "matchId": "Gz0gHEnR",
  "matchUrl": "https://www.flashscore.com/match/football/foresters-ELM3WgvF/wiliete-2kqSBS5P/?mid=Gz0gHEnR",
  "sport": "Football / Soccer",
  "sportSlug": "football",
  "country": "Africa",
  "competitionCategory": "AFRICA",
  "competition": "CAF Champions League",
  "competitionStage": "Qualification",
  "competitionUrl": "https://www.flashscore.com/football/africa/caf-champions-league/",
  "matchDate": "2026-09-10",
  "startTime": "2026-09-10T15:00:00.000Z",
  "status": "finished",
  "isLive": false,
  "hasResult": true,
  "homeTeam": "Foresters FC (Sey)",
  "awayTeam": "Wiliete (Ang)",
  "homeScore": 0,
  "awayScore": 1,
  "winner": "away",
  "periodScores": [
    { "period": 1, "label": "1st half", "home": 0, "away": 1 }
  ],
  "note": "First leg result: 0-4. Aggregate: 0-5.",
  "lastUpdated": "2026-09-10T16:54:28.000Z",
  "scrapedAt": "2026-09-11T13:58:02.104Z"
}
```

A tennis row carries the same shape with sets in `periodScores`:

```json
{
  "sport": "Tennis",
  "competitionCategory": "ATP - SINGLES",
  "competition": "US Open (USA), hard",
  "homeTeam": "Khachanov K.",
  "awayTeam": "Blockx A.",
  "homeScore": 2,
  "awayScore": 0,
  "winner": "home",
  "periodScores": [
    { "period": 1, "label": "Part 1", "home": 6, "away": 2, "tiebreakHome": null, "tiebreakAway": null },
    { "period": 2, "label": "Part 2", "home": 7, "away": 6, "tiebreakHome": 7, "tiebreakAway": 2 }
  ]
}
```

Three ready-made table views ship with the dataset, so you do not have to read a 38-key blob:

- **Overview** - date, kick-off, sport, country, competition, both sides, score, status, winner, link
- **Results only** - score, winner, period breakdown and notes
- **Fixtures** - the schedule without any scoring columns

### How much does it cost to scrape Flashscore?

A flat **$0.80 per 1,000 matches**. No monthly fee, no per-sport surcharge, no tiers.

| Matches | Cost |
|---|---|
| 1,000 | $0.80 |
| 10,000 | $8.00 |
| 100,000 | $80.00 |

For scale: a full day of worldwide football is roughly 500 matches, and the week-wide 18-sport run used for the coverage table below returned 8,951 matches for $7.16.

Comparable Flashscore and sports-score actors on the Store charge $1.00 to $12.00 per 1,000, and the cheapest of them covers a single sport.

### Measured coverage

Measured on 2026-09-11 over one run: 18 sports, 7 days, **8,951 matches**, 126 of 126 feeds served, 931 competitions, 129 countries.

| Field | Present |
|---|---|
| `matchId`, `matchUrl`, `startTime`, `status` | 100% |
| `homeTeam`, `awayTeam`, and both ids and short codes | 100% |
| `competition`, `competitionCategory`, `competitionUrl` | 100% |
| `homeTeamLogo`, `awayTeamLogo` | 92.7% |
| `country` | 77.7% |
| `competitionStage` | 21.9% |

On the 3,426 **finished** matches in that run:

| Field | Present |
|---|---|
| `homeScore`, `awayScore` | 97.1% |
| `winner` | 97.8% |
| `periodScores` | 93.7% |

The finished matches without a score are the postponed, cancelled and abandoned ones. They are flagged `hasResult: false` rather than being published as 0-0.

`country` is empty on tennis and table tennis, where Flashscore files competitions by tour rather than by country. Those rows carry the tour in `competitionCategory` instead, for example `ATP - SINGLES`, `CHALLENGER MEN - SINGLES` or `ITF MEN - SINGLES`. `competitionStage` is only populated when the competition has a named stage such as `Qualification` or `Play Offs`.

### Limits

- **Flashscore serves today plus or minus 7 days.** Dates outside that window are trimmed and the run tells you so in the log. There is no archive access, so build history by running this on a schedule.
- **Days are UTC days.** A late kick-off that is Saturday night in Los Angeles lands on the Sunday feed. `startTime` is always an exact UTC timestamp, so the bucketing never affects the data itself.
- **No lineups, statistics, odds or commentary.** This actor reads the day feed, which is match-level. Player statistics and betting odds live behind separate per-match requests.
- **Leaderboard sports are not covered.** Golf, horse racing, motorsport and cycling are on Flashscore but are one row per competitor with no opponent, which does not fit a match row. They are deliberately excluded rather than published half-empty.
- **`statusCode` is Flashscore's raw stage id and is passed through untranslated.** `status` gives you scheduled, live or finished, which is the distinction that matters; the finer id (a live second half, a retirement, an abandonment) has no public label table and is not guessed at.

### FAQ

#### Is it legal to scrape Flashscore?

This actor reads publicly available match data: fixtures, scores and competition names, the same information printed in any newspaper. Scores and results are facts and are not themselves copyrightable in most jurisdictions. No login is used, no account is needed and no personal data is collected. You are responsible for how you use the output, including complying with Flashscore's terms and with the law where you operate.

#### How much does Flashscore Scraper cost?

$0.80 per 1,000 matches, charged per row written to the dataset. Nothing else. The Apify free tier includes $5 of monthly usage, which is about 6,250 matches.

#### Can I use Flashscore Scraper as an API?

Yes. Every actor on Apify is callable over HTTP. Start a run with `POST /v2/acts/cirkit~flashscore-results-scraper/runs?token=YOUR_TOKEN` and read the dataset when it finishes, or use `run-sync-get-dataset-items` to do both in one call. See the [Apify API docs](https://docs.apify.com/api/v2).

#### Can I use this in Python?

Yes, with `apify-client`:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("cirkit/flashscore-results-scraper").call(run_input={"sports": ["football"], "dateFrom": "-1"})
for match in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(match["homeTeam"], match["homeScore"], "-", match["awayScore"], match["awayTeam"])
```

#### How do I schedule Flashscore Scraper to run automatically?

Open the actor, go to **Schedules**, and add one. Set `dateFrom` to `-1` and `dateTo` to `-1` for a nightly job that collects yesterday's completed results, or `0` with `matchStatus: ["live"]` and a five-minute schedule for a live scoreboard.

#### Can I integrate Flashscore Scraper with other apps?

Yes. Apify connects to Zapier, Make, n8n, Slack, Google Sheets, Google Drive and Airtable, and can fire a webhook when a run finishes so your own service pulls the dataset.

#### Why did I get fewer results than expected?

Four usual reasons. Your **Max results** cap was reached, which the log says explicitly. Your date range fell partly outside the plus-or-minus-7-day window and was trimmed. A filter removed more than you expected, since **Countries**, **Competitions** and **Teams** are all substring matches. Or the sport genuinely has no fixtures that day, which is common in the off-season for cricket, American football and the winter sports.

#### Does it return live scores?

Yes. Matches in progress come back with `status: "live"`, `isLive: true` and the score as it stands at the moment of the request, including the period breakdown so far. Run it on a short schedule to keep a live table current.

#### Which sports are supported?

Football, tennis, basketball, ice hockey, American football, baseball, handball, rugby union, rugby league, volleyball, cricket, darts, snooker, table tennis, badminton, futsal, floorball, bandy, boxing, MMA, beach volleyball, beach soccer, water polo, field hockey, Aussie rules, netball, pesapallo and esports.

#### Can I get a field that is not listed?

Ask. If Flashscore's day feed carries it, it can usually be added quickly. Fields that live behind a separate per-match request, such as lineups, shot maps or odds, are a bigger change.

#### Do I need proxies?

Apify Proxy is on by default with the datacenter pool, which is the cheapest option and is all Flashscore needs. Residential is available in the input if you ever want it.

### You might also like

- [Polymarket & Kalshi Prediction Markets Scraper](https://apify.com/cirkit/polymarket-kalshi-scraper) - live odds and prices from the prediction markets, a natural pair with sports results
- [TradingView Screener Scraper](https://apify.com/cirkit/tradingview-screener-scraper) - screen equities, crypto and forex on any TradingView filter
- [Twitch Search & Streams Scraper](https://apify.com/cirkit/twitch-search-scraper) - live streams, categories and viewer counts
- [Telegram Channel Posts Scraper](https://apify.com/cirkit/telegram-channel-scraper) - public channel posts, views and media

### Changelog

#### 0.1 - 2026-09-11

First release. 28 head-to-head sports, any date within today plus or minus 7 days, status, country, competition and team filters, period-by-period scores, three table views.

# Actor input Schema

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

Which sports to collect. Every sport you pick is fetched for every day in the date range, so two sports across three days is six requests. Football and tennis carry the most fixtures by far.

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

First day to collect, as YYYY-MM-DD in UTC. You can also type a day offset such as -3 for three days ago or 0 for today, which is what you want on a schedule so the input never goes stale. Leave empty for today.

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

Last day to collect, same format as Date from. Leave empty to collect only the Date from day. Flashscore serves today plus or minus 7 days; anything outside that is trimmed and the run says so.

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

Hard cap on the number of match rows. Set to 0 for no limit. You are charged per row, so this is also your budget control. A single day of football is roughly 500 matches worldwide.

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

Keep only matches in these states. Scheduled means it has not started, live means it is in progress right now, finished means it is over. Leave empty for all three. Filters run before billing.

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

Keep only competitions from these countries, one per line, for example "England", "Spain", "USA". Matched as a case-insensitive substring against Flashscore's own country label. Leave empty for worldwide.

## `competitions` (type: `array`):

Keep only these competitions, one per line, for example "Premier League", "NBA", "Champions League". Matched as a case-insensitive substring, so "cup" keeps every cup. Leave empty for all.

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

Keep only matches where either side matches one of these, one per line, for example "Arsenal", "Djokovic". Matched as a case-insensitive substring against both participants. Leave empty for all.

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

Apify Proxy settings. The default datacenter pool is enough for Flashscore and is the cheapest option; residential works too if you ever need it.

## Actor input object example

```json
{
  "sports": [
    "football"
  ],
  "dateFrom": "",
  "dateTo": "",
  "maxItems": 200,
  "matchStatus": [],
  "countries": [],
  "competitions": [],
  "teams": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Everything this run collected as the Overview table: date, kickoff, sport, country, competition, both teams, the score, the status and a direct link to the match.

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

The scoring side on its own: final score, winner, the period-by-period breakdown and any aggregate or extra-time note.

## `fixtures` (type: `string`):

Upcoming matches without the scoring columns: date, kickoff time, competition, stage and both participants.

## `matchesCsv` (type: `string`):

The full result set as CSV, ready for a spreadsheet, a database import or a BI tool.

## `consoleRun` (type: `string`):

The Apify Console page for this run, including the live log.

# 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 = {
    "sports": [
        "football"
    ],
    "maxItems": 200,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/flashscore-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 = {
    "sports": ["football"],
    "maxItems": 200,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/flashscore-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 '{
  "sports": [
    "football"
  ],
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call cirkit/flashscore-results-scraper --silent --output-dataset

```

## MCP server setup

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