# FotMob Scraper - Live Scores, xG, Ratings & Standings (`crawloop/fotmob-scraper`) Actor

Scrape FotMob football data in one Actor: fixtures, live scores, league standings, match details with lineups/xG/player ratings, team squads, player profiles, transfers, and search. HTTP JSON API alternative — Python, Node.js, MCP.

- **URL**: https://apify.com/crawloop/fotmob-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** News, Developer tools, Integrations
- **Features:** Limited permissions
- **Stats:** 37 total users, 13 monthly users, 98.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 match (fixtures / live / result)s

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

## FotMob Scraper — Live Scores, xG, Player Ratings, Standings & Transfers

Get structured football data from FotMob with one Apify Actor for matches, leagues, match details, teams, players, transfers, and search. Choose a mode, provide optional IDs or dates, then receive records in an Apify dataset. Use it as a football data API source for live scores, league standings, xG, player ratings, fixtures, results, team squads, and more, including Premier League, Bundesliga, and Champions League coverage available through FotMob.

### Why this Actor

- **Nine modes in one Actor:** `auto`, `matches`, `leagues`, `league`, `match`, `team`, `player`, `transfers`, and `search` cover a broad set of FotMob data needs.
- **Cheapest per record:** match records start at $2 per 1,000 and search hits at $1 per 1,000; per-event pricing is shown below so you can estimate costs from the records you need. Small runs have a tiny start fee.
- **HTTP JSON collection:** the Actor reads FotMob's public data endpoints directly. It does not need a browser, which keeps the collection process lightweight.
- **Match analysis fields:** request xG, player ratings, lineups, shotmap, and momentum when FotMob provides them.
- **Profiles and transfers included:** get team and player profiles and transfer feed records alongside match data, areas often outside the scope of single-purpose score tools.
- **Chain collection in one run:** collect matches, then set `enrichMatchDetails` to fetch details for those matches, including xG and lineups.
- **Structured export:** records land in an Apify dataset ready for JSON, CSV, Excel, API access, or further processing.

### What problems it solves

- **Analytics and prediction models:** build feature sets from fixtures, results, standings, xG, lineups, and player performance.
- **Live-score apps and alerts:** retrieve scheduled, live, or finished matches and feed score updates into your app or notification workflow.
- **Fantasy and tipster tools:** combine player ratings, team form, fixtures, and season leaders for research and planning.
- **Media and CMS scoreboards:** collect match lists, results, competition tables, and match details in a consistent dataset format.
- **ID mapping:** search clubs, players, and matches or enumerate league IDs before running targeted collections.

### What data you get

Each successful dataset item includes a record type, source, and scrape timestamp. The exact fields depend on the selected mode and optional include settings; FotMob may not publish every field for every record.

| Mode | What one record contains | Typical use |
| --- | --- | --- |
| `matches` | One fixture, live match, or result with teams, score, status, date, competition, and IDs | Daily schedules, live-score feeds, results |
| `leagues` | One competition directory entry with its name, category, country code, ID, and URL | Discover competitions and build ID lists |
| `league` | One competition season with available standings, fixtures, top players, season, and match IDs | League standings, season analysis, fixture lists |
| `match` | One match detail record with requested lineups, events, team and player stats, ratings, xG, venue, and related data | Match reports and performance analysis |
| `team` | One team profile with optional squad, fixtures, and standings slice | Squad research and club pages |
| `player` | One player profile with biography, position, primary team, recent matches, and career details when available | Player pages and profile enrichment |
| `transfers` | One recent transfer row with player, clubs, date, and fee fields when available | Transfer feeds and roster tracking |
| `search` | One typed search result with entity details and IDs | Resolve team, player, or match IDs |
| `auto` | Records from the mode inferred from the inputs you provide | Convenient runs when the target is clear from filled fields |

For match detail records, `includeShotmap` adds the shotmap payload and `includeMomentum` adds momentum graph data. These optional fields can increase record size. The `includeRaw` option attaches the full FotMob payload as `rawData`.

### How to use it in 60 seconds

1. **Pick a mode.** Choose `matches` for a date's fixtures, `league` for a competition season, `match` for match details, or another mode for profiles, transfers, and search. `auto` selects based on the inputs you fill.
2. **Fill targets.** Add IDs or URLs for the selected mode. For matches, use `dates` or `dateFrom` and `dateTo`; filters such as `leagueIds`, `matchStatus`, and `timezone` are optional.
3. **Run the Actor.** Set include options and `maxItems` as needed. Results are written as they are collected.
4. **Export or connect.** Download JSON, CSV, or Excel from the dataset, read records through the Apify API, or connect an integration.

### Input examples

Examples use only input fields defined by the Actor schema. You can combine applicable options; defaults are used for fields you leave out.

#### Today's matches (Berlin timezone)

```json
{
  "mode": "matches",
  "timezone": "Europe/Berlin",
  "matchStatus": "all",
  "locale": "de",
  "maxItems": 200
}
```

An empty `dates` list and no date range means today's matches in UTC by default. `timezone` selects the day bucket used for match collection.

#### Bundesliga standings and fixtures

```json
{
  "mode": "league",
  "leagueIds": ["54"],
  "includeStandings": true,
  "includeFixtures": true,
  "includeTopPlayers": true
}
```

#### Match details (lineups, xG, ratings)

```json
{
  "mode": "match",
  "matchIds": ["4506324"],
  "includeLineups": true,
  "includeTeamStats": true,
  "includePlayerStats": true,
  "includeEvents": true
}
```

#### Team squad

```json
{
  "mode": "team",
  "teamIds": ["9825"],
  "includeSquad": true,
  "includeFixtures": true
}
```

#### Transfers feed

```json
{
  "mode": "transfers",
  "transferPages": 2,
  "maxItems": 100
}
```

#### Search teams and players

```json
{
  "mode": "search",
  "searchQueries": ["Bayern", "Haaland"],
  "maxItems": 50
}
```

#### Premier League results over a date range

`dateFrom` and `dateTo` are inclusive and use `YYYYMMDD` format. League ID `47` is the Premier League.

```json
{
  "mode": "matches",
  "leagueIds": ["47"],
  "dateFrom": "20260801",
  "dateTo": "20260831",
  "matchStatus": "finished",
  "timezone": "Europe/London"
}
```

#### Today's matches with match detail enrichment

This fetches the match list and then requests match detail records for those matches. Details are charged as separate match-detail events; use a suitable run timeout for a large set.

```json
{
  "mode": "matches",
  "timezone": "Europe/Berlin",
  "matchStatus": "all",
  "enrichMatchDetails": true,
  "maxItems": 100
}
```

### Output examples

Every dataset item includes `recordType`, `source`, and `scrapedAt`. These examples show common fields; available data can vary by match and season.

#### Match row

```json
{
  "recordType": "match",
  "matchId": 5903801,
  "leagueId": 54,
  "leagueName": "Bundesliga",
  "ccode": "GER",
  "utcTime": "2026-08-04T17:00:00.000Z",
  "started": false,
  "finished": false,
  "homeTeam": { "id": 9823, "name": "Bayern München", "score": null },
  "awayTeam": { "id": 9788, "name": "Borussia Dortmund", "score": null },
  "matchUrl": "https://www.fotmob.com/match/5903801",
  "date": "20260804",
  "source": "fotmob-scraper",
  "scrapedAt": "2026-08-04T16:00:00Z"
}
```

#### Match details (xG, venue, player of the match)

```json
{
  "recordType": "matchDetail",
  "matchId": 4506324,
  "leagueName": "Premier League",
  "homeTeam": { "id": 10252, "name": "Aston Villa", "score": 0 },
  "awayTeam": { "id": 10260, "name": "Manchester United", "score": 0 },
  "xgHome": 0.5,
  "xgAway": 0.56,
  "xgotHome": 0.39,
  "xgotAway": 0.97,
  "venue": "Villa Park",
  "referee": "Robert Jones",
  "attendance": "42682",
  "playerOfTheMatch": {
    "playerId": 268375,
    "name": "Emiliano Martinez",
    "teamName": "Aston Villa",
    "rating": 8.4
  }
}
```

#### Record types at a glance

| `recordType` | Common fields |
| --- | --- |
| `match` | `matchId`, teams, score, status, `utcTime`, `leagueId`, `matchUrl` |
| `leagueDir` | `leagueId`, name, category, `ccode`, `leagueUrl` |
| `league` | standings, fixtures, `matchIds`, top players, season |
| `matchDetail` | lineups, events, `xgHome`/`xgAway`, `teamStats`, `playerStats`, venue, referee, H2H |
| `team` | squad, fixtures, standings slice |
| `player` | bio, primary team, position, recent matches, career |
| `transfer` | player, from/to clubs, fee fields, date |
| `searchHit` | typed search hits with entity IDs. `ccode` is not provided by FotMob search and is null |

### Pricing — what a run costs

This Actor uses pay-per-event pricing. The following prices are per 1,000 successfully delivered records:

| Event | Price per 1,000 records |
| --- | ---: |
| Match (fixture, live match, or result) | $2.00 |
| League directory row | $1.50 |
| League season record | $6.00 |
| Match details (xG, ratings, lineups) | $6.00 |
| Team profile | $5.00 |
| Player profile | $5.00 |
| Transfer row | $2.00 |
| Search hit | $1.00 |

The Actor start fee is **$0.00005 per run**—practically zero, so small runs stay cheap. For example:

- A day of fixtures (about 70 matches) costs approximately **$0.14**.
- 100 match detail records cost approximately **$0.60**.
- 5 top-league tables cost approximately **$0.03**.

You pay only for records delivered to the dataset. Set `maxItems` to limit the number of records, and use Apify's max-charge-per-run cap to control spend. Apify's free plan includes $5 monthly credit to try Actors. Exact prices are on the Pricing tab and may change.

### Compared to the alternatives

| Consideration | This Actor | Build your own scraper | Single-purpose FotMob tools | Manual copy |
| --- | --- | --- | --- | --- |
| Modes covered | Nine modes in one Actor, including `auto` | Whatever you implement | Usually focused on one data type per tool | Depends on what you copy |
| Team, player, and transfers | Team and player profiles plus transfers feed | Possible, with separate endpoint work | Depends on the specific tool | Manual and time-consuming |
| xG, shotmap, and momentum | Match details support these when available | Possible when endpoints expose them | Depends on the tool | Usually copied field by field |
| Setup time | Configure input and run | Build, deploy, and maintain collection code | Configure each separate tool | Repeat manual work for each update |
| Maintenance when FotMob changes | Actor is maintained; report issues in the Issues tab | You handle endpoint changes | Each tool maintainer handles its scope | You adjust your process |
| Export formats | Apify dataset formats and API | Choose and implement formats | Depends on platform and tool | Paste into your chosen format |
| Start fee | $0.00005 per run, plus record events | Infrastructure and engineering costs | Pricing varies by tool | No Actor fee; staff time applies |

The right choice depends on the fields and workflow you need. This Actor is designed for structured FotMob collection across match, competition, profile, transfer, and search data.

### Use cases

- **Daily football data pipeline:** schedule `matches`, then use `enrichMatchDetails` when the downstream process needs match detail records.
- **Prediction and model features:** collect xG, ratings, lineups, results, and competition context where FotMob provides them.
- **Fantasy and tipster research:** compare upcoming fixtures with team form and season player leaders.
- **CMS scoreboards:** export results for a date range as JSON, CSV, or Excel and load them into a publishing workflow.
- **ID discovery:** use `leagues` or `search`, then pass discovered IDs to targeted runs.
- **Soccer stats archive:** store dated match and league records in your own dataset for analysis over time.

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/fotmob-scraper').call({
  mode: 'matches',
  timezone: 'Europe/Berlin',
  maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_TOKEN")
run = client.actor("crawloop/fotmob-scraper").call(run_input={
    "mode": "league",
    "leagueIds": ["54"],
    "includeStandings": True,
    "includeFixtures": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("name"), len(item.get("standings") or []))
```

#### cURL

```bash
curl -s -X POST "https://api.apify.com/v2/acts/crawloop~fotmob-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"match","matchIds":["4506324"],"includePlayerStats":true,"includeTeamStats":true}'
```

### MCP and AI assistants

Use the Actor from AI tools through [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call the Actor by its Store ID or name: `crawloop/fotmob-scraper`.

Example prompts:

- “Run FotMob Scraper for today's matches in Europe/Berlin and return finished games as JSON.”
- “Get Bundesliga league ID 54 standings and top scorers.”
- “Fetch match 4506324 with lineups and xG, then summarize the player ratings.”

### Schedule it

Use Apify Schedules for daily results or to poll live matches every few minutes. Connect run results to webhooks or automation tools such as Zapier, Make, and Google Sheets to pass records into your workflow.

### FAQ

**Do I need a FotMob account?**\
No. The Actor uses public JSON endpoints and does not require a FotMob login.

**Is this a FotMob API?**\
It is an Actor that collects data from FotMob's public data endpoints and returns it in a structured Apify dataset. It is not an official FotMob API product, and endpoint availability can change.

**Is it legal, and is the data public?**\
The Actor reads data available from public FotMob pages and endpoints. You are responsible for your use of the data under applicable laws and FotMob's terms. See the disclaimer below.

**Does it need a proxy?**\
No. Requests use HTTP, and a datacenter proxy is usually sufficient if you choose to use one. Proxy configuration is optional.

**How fresh are live scores?**\
They are as fresh as FotMob's public feed at the time the Actor runs. This is a snapshot, not a guaranteed real-time push stream.

**Is German `/de` a separate dataset?**\
No. The `locale` option changes URL language and request language headers. Competition and match IDs are global.

**How do I find league or match IDs?**\
Run `mode: "leagues"` or `mode: "search"`, or start with `mode: "matches"` and read the `matchId` and `leagueId` fields from its records.

**Can I get historical seasons?**\
Yes. Use `mode: "league"` and provide a `seasons` value such as `2024/2025` when FotMob lists that season in its available seasons.

**Why can a player profile be empty?**\
FotMob sometimes returns empty player data. Missing records are not written to the dataset and are not billed as delivered records.

**What happens if FotMob changes its API?**\
We maintain the Actor as FotMob's public endpoints change. If a mode stops working or its output changes unexpectedly, report the issue in the Actor's Issues tab.

**What about transfers versus Transfermarkt?**\
This Actor provides FotMob's recent transfers feed. For deep transfer-fee histories, use a source focused on that data.

**Can I use it in production?**\
You can use it for scheduled collection and exports. Plan for the possibility of endpoint changes, set appropriate run limits, and follow applicable terms and laws.

### Related Actors

- [PrizePicks Player Props Scraper](https://apify.com/crawloop/prizepicks-player-props-scraper)
- [Underdog Fantasy Player Props](https://apify.com/crawloop/underdog-fantasy-player-props-scraper-real-time-lines-odds)
- [DFS Multi-Source Props Scraper](https://apify.com/crawloop/dfs-multi-source-props-scraper)
- [Betr Picks Scraper](https://apify.com/crawloop/betr-picks-scraper)

### Disclaimer

This Actor is not affiliated with FotMob. It collects publicly accessible data; you are responsible for using it under applicable law and FotMob's terms. Data availability and accuracy are not guaranteed.

# Actor input Schema

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

What to scrape. matches = fixtures/live/results by date; leagues = full competition directory; league = standings+fixtures for league ids; match = deep match details; team / player / transfers / search; auto picks from filled inputs.

## `dates` (type: `array`):

Dates for matches mode. Example: 20260804. Leave empty (with no range) for today UTC.

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

Inclusive start of a date range for matches mode.

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

Inclusive end of a date range for matches mode.

## `timezone` (type: `string`):

IANA timezone for the matches day bucket (e.g. Europe/Berlin, UTC).

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

Filter matches mode results by status.

## `leagueIds` (type: `array`):

FotMob league ids (e.g. 54 = Bundesliga, 47 = Premier League). Used as filter in matches mode or as targets in league mode.

## `leagueUrls` (type: `array`):

FotMob league page URLs. Ids are parsed automatically.

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

Optional seasons for league mode (e.g. 2025/2026). Empty = current season.

## `category` (type: `string`):

For leagues mode: which bucket to return.

## `countryCodes` (type: `array`):

FIFA country codes for leagues mode domestic filter (e.g. GER, ENG, ESP).

## `matchIds` (type: `array`):

FotMob match ids for match mode (and optional enrich).

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

FotMob match page URLs.

## `teamIds` (type: `array`):

FotMob team ids for team mode.

## `teamUrls` (type: `array`):

FotMob team page URLs.

## `playerIds` (type: `array`):

FotMob player ids for player mode.

## `playerUrls` (type: `array`):

FotMob player page URLs.

## `searchQueries` (type: `array`):

Terms for search mode (team, player, match suggest).

## `fullSearch` (type: `boolean`):

When true, use searchapi/search instead of suggest (search mode).

## `transferPages` (type: `integer`):

How many pages to pull in transfers mode (≈50 rows/page).

## `enrichMatchDetails` (type: `boolean`):

In matches or league mode, also fetch full match details (lineups, xG, ratings) for each match id. Billed as separate match-detail events. Uses extra HTTP calls — raise the run timeout if you enrich a large date range.

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

Include standings tables in league / team modes.

## `includeFixtures` (type: `boolean`):

Include fixtures / match lists in league / team modes.

## `includeTopPlayers` (type: `boolean`):

Include season top players (rating / goals / assists) in league mode.

## `includeSquad` (type: `boolean`):

Include squad groups in team mode.

## `includeTeamStats` (type: `boolean`):

Match details: team-vs-team stats including xG when available.

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

Match details: goals, cards, substitutions timeline.

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

Match details: formations, starters, subs, coach.

## `includePlayerStats` (type: `boolean`):

Match details: per-player stats and ratings.

## `includeH2H` (type: `boolean`):

Match details: previous meetings block.

## `includeShotmap` (type: `boolean`):

Match details: raw shotmap payload (larger).

## `includeMomentum` (type: `boolean`):

Match details: momentum graph data.

## `includeRaw` (type: `boolean`):

Attach the full FotMob JSON as rawData (larger datasets).

## `locale` (type: `string`):

UI locale for URLs / Accept-Language (en or de). Data ids are global.

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

Stop after this many dataset records (0 = unlimited).

## `requestDelaySecs` (type: `number`):

Throttle between HTTP requests.

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

Optional Apify Proxy. Datacenter is usually enough.

## Actor input object example

```json
{
  "mode": "auto",
  "dates": [],
  "dateFrom": "",
  "dateTo": "",
  "timezone": "UTC",
  "matchStatus": "all",
  "leagueIds": [],
  "leagueUrls": [],
  "seasons": [],
  "category": "all",
  "countryCodes": [],
  "matchIds": [],
  "matchUrls": [],
  "teamIds": [],
  "teamUrls": [],
  "playerIds": [],
  "playerUrls": [],
  "searchQueries": [],
  "fullSearch": false,
  "transferPages": 1,
  "enrichMatchDetails": false,
  "includeStandings": true,
  "includeFixtures": true,
  "includeTopPlayers": true,
  "includeSquad": true,
  "includeTeamStats": true,
  "includeEvents": true,
  "includeLineups": true,
  "includePlayerStats": true,
  "includeH2H": true,
  "includeShotmap": false,
  "includeMomentum": false,
  "includeRaw": false,
  "locale": "en",
  "maxItems": 0,
  "requestDelaySecs": 0.15,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Default dataset items (one record per match, league, team, player, transfer, or search hit).

# 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("crawloop/fotmob-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("crawloop/fotmob-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 crawloop/fotmob-scraper --silent --output-dataset

```

## MCP server setup

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