# Followscores Scraper (`batscrape/followscores-scraper`) Actor

Football data scraper for FollowScores — extract live fixtures, results & team profiles as clean JSON/CSV. Fast, no-code Apify actor for sports apps, betting models & dashboards. Start scraping in minutes.

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

## Pricing

from $7.00 / 1,000 dataset items

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

![](https://github-production-user-asset-6210df.s3.amazonaws.com/441156/653042973-7f97e202-9a19-46b1-ac23-9808ed8bcb13.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20260917%2Fus-east-1%2Fs3%2Faws4_request\&X-Amz-Date=20260917T030857Z\&X-Amz-Expires=300\&X-Amz-Signature=ea8a67e432c9d67fbe75559e5268290548fe0e29fc2d423aa948e99e9dee7c34\&X-Amz-SignedHeaders=host\&response-content-type=image%2Fjpeg)

## Football Scores Scraper: Live Fixtures, Results & Team Data for 11 European Leagues ⚽

Extract live football/soccer data — today's fixtures, results over a date range, or a full team profile (summary, squad, results, upcoming) — across **11 top European competitions** with transparent event-based pricing. Perfect for sports dashboards, betting-odds research, fan apps, and match-data pipelines.

💰 **Price:** $0.0075 flat per run + $0.016/query (today's matches, each day of a range, or a team's squad/results/upcoming) or $0.05/query (a team's summary) + $0.0007/dataset item
🏆 **Coverage:** 11 competitions, 214 teams — Süper Lig, 1. Lig, Premier League, Championship, LaLiga, Serie A, Bundesliga, Ligue 1, Eredivisie, Liga Portugal, UEFA Europa League
📊 **Data:** Fixtures with live status/score, team summary, squad, results, upcoming fixtures
🎯 **3 Modes:** Today's matches, results by date range (up to 31 days), or team info
🛡️ **Event-Based Pricing**

### Quick Navigation

- [Football Scores Scraper: Live Fixtures, Results & Team Data for 11 European Leagues ⚽](#football-scores-scraper-live-fixtures-results--team-data-for-11-european-leagues-)
  - [Quick Navigation](#quick-navigation)
  - [ℹ️ Disclaimer About This Football Scores Scraper](#ℹ️-disclaimer-about-this-football-scores-scraper)
  - [🧭 What Does Football Scores Scraper Do?](#-what-does-football-scores-scraper-do)
  - [Core Extraction Capabilities](#core-extraction-capabilities)
    - [📅 Today's Matches](#-todays-matches)
    - [📊 Results by Date Range](#-results-by-date-range)
    - [👕 Team Info](#-team-info)
  - [🐉 Features and Functionality](#-features-and-functionality)
    - [Core Features](#core-features)
  - [💰 Pricing: Transparent Event-Based Costs](#-pricing-transparent-event-based-costs)
  - [Pricing Structure](#pricing-structure)
    - [How Pricing Works](#how-pricing-works)
    - [💵 Real-World Pricing Examples](#-real-world-pricing-examples)
  - [🎎 Who Needs This?](#-who-needs-this)
  - [🍚 Input Parameters](#-input-parameters)
    - [`option`](#option)
    - [Option 1 — Today's matches](#option-1--todays-matches)
    - [Option 2 — Results by date range](#option-2--results-by-date-range)
    - [Option 3 — Team info](#option-3--team-info)
    - [Everything else](#everything-else)
    - [💡 Input Strategy Guide](#-input-strategy-guide)
  - [📦 Output](#-output)
    - [Today's matches / Results by date range](#todays-matches--results-by-date-range)
    - [Team info](#team-info)
    - [No data found](#no-data-found)
  - [🧩 Custom Map Function](#-custom-map-function)
  - [⚙️ How It Works](#️-how-it-works)
  - [🔧 Configuration](#-configuration)
  - [🔧 Troubleshooting](#-troubleshooting)
    - [❓ Getting Few or No Results?](#-getting-few-or-no-results)
    - [💰 Unexpected Costs?](#-unexpected-costs)
    - [💡 Want to Minimize Costs?](#-want-to-minimize-costs)
    - [🈳 Missing Team Data?](#-missing-team-data)
  - [📞 Contact](#-contact)

### 🧭 What Does Football Scores Scraper Do?

This actor fetches football/soccer data for 11 top European competitions and pushes it to your dataset as structured JSON — no browser automation, no HTML parsing, no proxies to manage. Pick one of three modes (`option`) and it queues exactly the requests that mode needs, respecting your `maxItems` cap and pay-per-event budget as it goes.

### Core Extraction Capabilities

#### 📅 Today's Matches

Every match being played today across all 11 competitions, or narrowed down to specific leagues. Each match reports its live `status` and, once kicked off, its running score.

#### 📊 Results by Date Range

The same fixture data as above, but for every day across a range (capped at **31 days per run** — each day is its own query and its own charge), optionally filtered to specific leagues and/or teams.

#### 👕 Team Info

Pick one or more of the 214 supported teams and get each one's **full profile** in one go — summary, squad, past results, and upcoming fixtures — no separate view picker needed.

### 🐉 Features and Functionality

#### Core Features

| Feature                     | Description                                                                               | Benefit                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| 💰 **Event-Based Pricing**  | Pay only for the queries and dataset items you actually generate                          | Cost control: no subscriptions, no monthly fees           |
| 🎯 **3 Focused Modes**      | Today's matches, date-range results, or team info — one clear choice per run              | No wasted queries on data you didn't ask for              |
| 🔤 **Name-Based Dropdowns** | Pick leagues/teams by name, not by hunting down internal ids                              | Faster setup, no external lookup needed                   |
| ⚽ **Live Match Status**    | `not_started` / in-progress / `ended`, with scores once available                         | Build a live scoreboard without polling logic of your own |
| 👥 **Full Team Profiles**   | Summary + squad + results + upcoming in one selection, no extra config                    | One click gets everything about a team                    |
| 🔧 **Custom Map Function**  | JavaScript function to reshape or enrich output on-the-fly                                | Shape results to match your exact requirements            |
| 💵 **Budget-Aware**         | Every query and dataset item is checked against the run's charge budget before it's spent | A run stops cleanly instead of overspending               |

### 💰 Pricing: Transparent Event-Based Costs

Pay-per-event pricing — no subscription, no hidden fees. Every query is charged once up front; every dataset item is charged as it's pushed.

### Pricing Structure

| Event                    | Price (USD) | Charged For                                                                    | Best For                               |
| ------------------------ | ----------- | ------------------------------------------------------------------------------ | -------------------------------------- |
| 🚀 **Actor Start**       | **$0.0075** | Once per run, regardless of input                                              | N/A — a flat, unavoidable run fee      |
| 📋 **List Query**        | **$0.016**  | Today's matches, each day of a date range, and a team's squad/results/upcoming | Bulk fixture data, team squads/history |
| 👤 **Single-Item Query** | **$0.05**   | A team's summary                                                               | Quick team lookups                     |
| 📊 **Dataset Item**      | **$0.0007** | Each match / squad entry / result / upcoming fixture actually stored           | Scales with how much data you keep     |

#### Apify Console setup (pay-per-event)

When configuring this actor's pricing in the Apify Console's "Set up monetization" wizard, four events need to exist, exactly like this:

| Event name (exact)              | Reserved? | Title              | Description                                                                    | Price      |
| -------------------------------- | --------- | ------------------ | ------------------------------------------------------------------------------ | ---------- |
| `apify-actor-start`              | ✅ yes    | Actor Start        | Charged once when the Actor starts running, regardless of input.               | `$0.0075`  |
| `apify-default-dataset-item`     | ✅ yes    | Result             | Charged for every item pushed to the default dataset.                          | `$0.0007`  |
| `single-item-query`              | custom    | Single-item query  | A single-record lookup — currently only a team's summary.                      | `$0.05`    |
| `list-query`                     | custom    | List query         | A list/table/feed query — today's matches, each day of a range, or a team's squad/results/upcoming. | `$0.016` |

The first two are Apify's reserved event names — the Console pre-fills them (non-editable) and bills them automatically the moment the run starts / an item hits the default dataset, independent of anything this actor's code reports. **Ignore the wizard's own example price** for the `apify-default-dataset-item` card (it defaults to a placeholder like `$0.00001`) — enter `$0.0007` to match this actor's actual pricing. The last two are ordinary custom events you add yourself via "+ Add another event".

These four names/prices must stay in sync with [`src/services/subscription/events.js`](src/services/subscription/events.js) — that file is the source of truth this actor's own budget bookkeeping reads from.

#### How Pricing Works

Every run starts with a flat **$0.0075 Actor Start** charge, regardless of mode or input, then adds:

**Today's matches:** One list-query charge ($0.016) for the day, plus one dataset item ($0.0007) per match returned.

**Results by date range:** One list-query charge **per day** in the range (up to 31 days) — a 7-day range is 7 separate $0.016 charges — plus $0.0007 per match across all those days.

**Team info:** Each selected team queues **4 queries**: 1 single-item query for `summary` ($0.05) + 3 list queries for `squad`, `results`, `upcoming` ($0.016 each = $0.048) — **$0.098 per team** before any dataset items — plus $0.0007 per squad player / past result / upcoming fixture returned.

#### 💵 Real-World Pricing Examples

| Use Case                     | Configuration                                                    | Total Cost  | Breakdown                                     |
| ---------------------------- | ---------------------------------------------------------------- | ----------- | --------------------------------------------- |
| **Quick scoreboard check**   | Today's matches, all leagues (64 matches on a real test day)     | **$0.0683** | $0.0075 + $0.016 + (64 × $0.0007)             |
| **Single-league scoreboard** | Today's matches, 1 league filter (~6 matches)                    | **$0.0277** | $0.0075 + $0.016 + (6 × $0.0007)              |
| **Weekly results digest**    | 7-day date range, all leagues (~450 matches/week)                | **$0.4345** | $0.0075 + (7 × $0.016) + (450 × $0.0007)      |
| **Full month of results**    | 31-day date range, all leagues (~2,000 matches)                  | **$1.9035** | $0.0075 + (31 × $0.016) + (2,000 × $0.0007)   |
| **Single team deep-dive**    | 1 team, full profile (~50 combined squad/results/upcoming items) | **$0.1405** | $0.0075 + $0.098 (4 queries) + (50 × $0.0007) |
| **Multi-team scouting**      | 10 teams, full profiles (~500 combined items)                    | **$1.3375** | $0.0075 + (10 × $0.098) + (500 × $0.0007)     |

*Match/item counts vary day to day and team to team — the 64-match "quick scoreboard" row is from a real run; the rest are illustrative at similar volumes.*

### 🎎 Who Needs This?

- **Sports dashboard builders**: Live scoreboards and results feeds without polling a scraper yourself.
- **Fan / fantasy-football apps**: Team squads, upcoming fixtures and results to power app content.
- **Betting-odds & sports-data researchers**: Structured match and team datasets for modeling.
- **Content & media sites**: Automated match-day and weekly results roundups.
- **Data analysts**: Historical results across a date range for trend/performance analysis.

### 🍚 Input Parameters

`option` picks which of the three modes actually runs — fields under the other two are ignored, so it's safe to leave stale values in them.

#### `option`

| Value                    | Runs                             |
| ------------------------ | -------------------------------- |
| `todayMatches` (default) | Option 1 — Today's matches       |
| `dateRange`              | Option 2 — Results by date range |
| `teamInfo`               | Option 3 — Team info             |

#### Option 1 — Today's matches

| Field          | Description                                                       |
| -------------- | ----------------------------------------------------------------- |
| `todayLeagues` | Optional league dropdown (11 competitions). Empty = every league. |

#### Option 2 — Results by date range

| Field                           | Description                                                            |
| ------------------------------- | ---------------------------------------------------------------------- |
| `dateRangeFrom` / `dateRangeTo` | Both required when `option` is `dateRange`. Capped at 31 days per run. |
| `dateRangeLeagues`              | Optional league dropdown. Empty = every league.                        |
| `dateRangeTeams`                | Optional team dropdown. Empty = every team.                            |

#### Option 3 — Team info

| Field   | Description                                                                                                                                                                                                                                                                                                                                                       |
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `teams` | Team dropdown (multi-select), covering 214 teams across Süper Lig, 1. Lig, Premier League, Championship, LaLiga, Serie A, Bundesliga, Ligue 1, Eredivisie, Liga Portugal and the UEFA Europa League. Each selected team returns its summary, squad, results and upcoming fixtures — no separate view picker. Required (at least one) when `option` is `teamInfo`. |

#### Everything else

| Field               | Description                                                                     | Default  |
| ------------------- | ------------------------------------------------------------------------------- | -------- |
| `maxItems`          | Max dataset items for the whole run. `0`/empty = unlimited.                     | `1000`   |
| `customMapFunction` | `(object) => object` applied to every item. **Must not be used for filtering.** | *(none)* |

#### 💡 Input Strategy Guide

**Just want a live scoreboard?** Use `todayMatches` with no league filter — one $0.016 query gets every match being played today across all 11 competitions.

**Building a results archive?** Use `dateRange` and set `dateRangeLeagues`/`dateRangeTeams` to narrow it down — filtering happens after the fetch, so it reduces *stored* items (and their $0.0004 charges) but not the per-day query cost.

**Researching specific clubs?** Use `teamInfo` with exactly the teams you need — each team is a fixed $0.098 in query charges regardless of squad size, so batch every team you're interested in into one run rather than several small ones.

### 📦 Output

Output is stored in a dataset. Every item carries `queryType` (which query produced it) and `inputSource` (the date/id that was queried) — everything else is the underlying data untouched.

#### Today's matches / Results by date range

One dataset item per match:

```json
{
  "fixtureID": "72478582",
  "competitionID": "8",
  "competitionName": "LaLiga",
  "countryName": "Spain",
  "seasonID": "142176",
  "homeTeamID": "2818",
  "homeTeamName": "Rayo Vallecano",
  "awayTeamID": "2814",
  "awayTeamName": "Espanyol",
  "status": "not_started",
  "startTime": "2026-09-15T17:00:00Z",
  "queryType": "todayMatches",
  "inputSource": "2026-09-15"
}
```

`status` is `not_started`, in progress, or `ended` (with score fields present once a match has kicked off). `queryType` is `"todayMatches"` or `"dateRangeResults"`; `inputSource` is the date that produced the row.

#### Team info

One dataset item per view per team (`queryType` one of `team:summary`, `team:squad`, `team:results`, `team:upcoming`; `inputSource` is the team id):

```json
{
  "teamID": "3061",
  "teamFullName": "Galatasaray Istanbul",
  "teamName": "Galatasaray",
  "countryName": "Turkey",
  "queryType": "team:summary",
  "inputSource": "3061"
}
```

The exact fields vary by view — inspect a run's dataset to see them all, or use `customMapFunction` to reshape what you need.

#### No data found

A query that comes back empty is still stored, so your run's item count always matches what you asked for:

```json
{ "noResults": true, "queryType": "team:results", "inputSource": "3061" }
```

### 🔧 Troubleshooting

#### ❓ Getting Few or No Results?

- ✅ Check `maxItems` — the run stops once it's reached
- ✅ Check the charge budget — a run that can't afford another dataset item stops cleanly rather than erroring
- ✅ For `dateRange`, confirm both `dateRangeFrom` and `dateRangeTo` are set (both are required)
- ✅ For `teamInfo`, confirm at least one team is picked in `teams`

#### 💰 Unexpected Costs?

Remember: every run charges a flat **$0.0075 Actor Start** fee once, no matter what you ask for. On top of that, **team info always queues 4 queries per team** (1 summary + 3 list queries = $0.098) regardless of how much data comes back — picking 10 teams costs at least $0.98 in queries alone, before any dataset items.

#### 💡 Want to Minimize Costs?

- ✅ Use `todayLeagues`/`dateRangeLeagues`/`dateRangeTeams` filters to reduce **stored items** (dataset-item charges) — note this doesn't reduce the per-day query charge for `dateRange`
- ✅ Keep date ranges as short as you actually need — every extra day is another $0.016 query
- ✅ Set `maxItems` to a hard cap matching your budget

#### 🈳 Missing Team Data?

`team:squad` / `team:results` / `team:upcoming` can legitimately come back empty for a team with no current squad data, no past results yet this season, or no fixtures scheduled — this is stored as `{ noResults: true, ... }`, not an error.

### 📞 Contact

Reach out to the maintainers directly for support.

- ✉️ **Email:** <batscrape@gmail.com>
- 💬 **Discord:** [discord.com/invite/ZRANXwhWU](https://discord.com/invite/ZRANXwhWU)
- 🐦 **X (Twitter):** [x.com/batscrape](https://x.com/batscrape)
- 🛒 **Apify:** [apify.com/batscrape](https://apify.com/batscrape)

# Actor input Schema

## `option` (type: `string`):

Pick exactly one. Only the fields under your chosen option (below) are used — everything else is ignored.

## `todayLeagues` (type: `array`):

Only include these leagues. Leave empty for all leagues.

## `dateRangeFrom` (type: `string`):

Start date. Both dates are required.

## `dateRangeTo` (type: `string`):

End date. Both dates are required.

## `dateRangeLeagues` (type: `array`):

Only include these leagues in the date-range results. Leave empty for all leagues.

## `dateRangeTeams` (type: `array`):

Only include matches involving these teams in the date-range results. Leave empty for all teams.

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

Pick one or more teams. For each one, this returns its full profile: summary, squad, past results and upcoming fixtures — no separate options to configure.

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

Maximum number of dataset items to store across the whole run. 0 or empty means unlimited.

## `customMapFunction` (type: `string`):

A function that takes each output object and returns a transformed object. MUST NOT be used for filtering. Leave empty to store items unchanged.

## Actor input object example

```json
{
  "option": "todayMatches",
  "todayLeagues": [],
  "dateRangeLeagues": [],
  "dateRangeTeams": [],
  "teams": [],
  "maxItems": 1000,
  "customMapFunction": "(object) => { return {...object} }"
}
```

# 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 = {
    "todayLeagues": [],
    "dateRangeLeagues": [],
    "dateRangeTeams": [],
    "teams": [],
    "maxItems": 1000,
    "customMapFunction": (object) => { return {...object} }
};

// Run the Actor and wait for it to finish
const run = await client.actor("batscrape/followscores-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 = {
    "todayLeagues": [],
    "dateRangeLeagues": [],
    "dateRangeTeams": [],
    "teams": [],
    "maxItems": 1000,
    "customMapFunction": "(object) => { return {...object} }",
}

# Run the Actor and wait for it to finish
run = client.actor("batscrape/followscores-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 '{
  "todayLeagues": [],
  "dateRangeLeagues": [],
  "dateRangeTeams": [],
  "teams": [],
  "maxItems": 1000,
  "customMapFunction": "(object) => { return {...object} }"
}' |
apify call batscrape/followscores-scraper --silent --output-dataset

```

## MCP server setup

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