# Football Stats & Elo Ratings API (`smoked_drift/football-team-stats-elo`) Actor

Team stats and Elo ratings for 22 European leagues. One row per club: Elo, points, goals for and against, home and away splits, clean sheets, recent form and last results. Computed chronologically with no result leakage.

- **URL**: https://apify.com/smoked\_drift/football-team-stats-elo.md
- **Developed by:** [Titouan MARTY](https://apify.com/smoked_drift) (community)
- **Categories:** Sports
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 team profiles

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

## Football Stats & Elo Ratings API

**Team stats and Elo ratings** for 22 European leagues. One row per club: its Elo rating, points, goals for and against, home and away splits, clean sheets, recent form, and its last ten results.

This is a **football stats API** for anyone who would otherwise spend an evening on `groupby`: fantasy players comparing squads, modellers needing a rating that is comparable *across* leagues, and content teams building tables and form guides.

***

### Why Elo and not just points

League points are not comparable between competitions. 85 points in the Premier League and 85 points in the Eredivisie are different achievements, and neither number tells you how a team is playing *right now*.

Elo fixes both problems. It is computed chronologically across every match in scope, adjusts for the quality of the opponent, and carries a single scale you can compare across leagues:

```
Barcelona    1669.4     (LaLiga)
Arsenal      1622.4     (Premier League)
Man City     1621.5     (Premier League)
Paris SG     1621.2     (Ligue 1)
Real Madrid  1619.4     (LaLiga)
```

That table is real output from a single season across three leagues — and it is exactly the comparison league tables cannot make.

**Nothing leaks the future.** Ratings are computed strictly before the match being described, so a team's value never encodes a result it has not played yet. That is what makes this safe to backtest on.

***

### What you get

One dataset item per team:

| Group | Fields |
| --- | --- |
| **Identity** | team, league, league details, league rank |
| **Rating** | current Elo |
| **Record** | played, won, drawn, lost, points |
| **Goals** | for, against, difference, per game, goals for and against per game |
| **Splits** | home and away played / won / drawn / lost / points |
| **Discipline of result** | clean sheets, failed to score |
| **Form** | last five as a W/D/L string, points from those five |
| **Recent results** | the last ten matches with opponent, venue, result and score |

Consistency is guaranteed by construction: played always equals won + drawn + lost, points always equals 3×won + drawn, and home plus away always equals the total. The Actor verifies this across **1,066 real matches** before release.

***

### Sample output

Real row, LaLiga, after five matchdays:

```json
{
  "team": "Barcelona",
  "league": "SP1",
  "leagueRank": 1,
  "elo": 1537.3,
  "played": 5, "won": 5, "drawn": 0, "lost": 0, "points": 15,
  "goalsFor": 21, "goalsAgainst": 4, "goalDifference": 17,
  "goalDifferencePerGame": 3.4,
  "pointsPerGame": 3,
  "goalsForPerGame": 4.2,
  "goalsAgainstPerGame": 0.8,
  "home": { "played": 2, "won": 2, "drawn": 0, "lost": 0, "points": 6 },
  "away": { "played": 3, "won": 3, "drawn": 0, "lost": 0, "points": 9 },
  "cleanSheets": 3,
  "failedToScore": 0,
  "form": { "last5": "WWWWW", "pointsLast5": 15 },
  "results": [
    { "date": "2026-08-23", "opponent": "Elche",      "venue": "away", "result": "W", "score": "5-0" },
    { "date": "2026-08-27", "opponent": "Ath Bilbao", "venue": "home", "result": "W", "score": "2-0" },
    { "date": "2026-08-31", "opponent": "Vallecano",  "venue": "home", "result": "W", "score": "5-2" },
    { "date": "2026-09-06", "opponent": "Valencia",   "venue": "away", "result": "W", "score": "5-0" },
    { "date": "2026-09-13", "opponent": "Levante",    "venue": "away", "result": "W", "score": "4-2" }
  ]
}
```

Note that `played` equals `won + drawn + lost` (5), `points` equals `3×won + drawn` (15), and `home.played + away.played` equals `played` (2 + 3 = 5). Those three identities hold on every row the Actor returns.

***

### Usage

#### Profile the big five leagues

```json
{ "leagues": ["big-five"], "seasonsBack": 1, "minMatches": 10 }
```

#### One team, across several seasons

```json
{ "leagues": ["all"], "teams": ["Marseille"], "seasonsBack": 5 }
```

#### Only the current season, sorted by goal difference

```json
{ "leagues": ["france", "england"], "sortBy": "gd", "dateFrom": "01/07/2026" }
```

#### Strongest clubs in Europe right now

```json
{ "leagues": ["all"], "seasonsBack": 1, "sortBy": "elo", "minMatches": 5, "maxItems": 30 }
```

***

### Leagues

`E0` `E1` `E2` `E3` `EC` (England) · `SC0`–`SC3` (Scotland) · `D1` `D2` (Germany) · `I1` `I2` (Italy) · `SP1` `SP2` (Spain) · `F1` `F2` (France) · `N1` (Netherlands) · `B1` (Belgium) · `P1` (Portugal) · `T1` (Turkey) · `G1` (Greece)

**Presets:** `big-five` · `big-five-plus-second` · `france` · `england` · `all`

***

### Pricing

| Event | Charged | Covers |
| --- | --- | --- |
| `team-profile` | once per team returned | the full team row |
| `league-ranking` | once per league in scope | ranking each team inside its league |

A five-league run is roughly 100 team rows, so `maxItems` and `minMatches` are the two dials that control spend.

***

### Reliability

Built on the same engine as the [Football Data API](https://apify.com/smoked_drift/european-football-results-odds) Actor:

- The source is a **downloadable CSV**, not a web page — no browser, no proxy, no selectors to break.
- Elo is computed over the full history and then filtered, so a rating never depends on which filter the caller chose.
- Every row carries its source URL.

***

### Notes and limits

- **Elo starts at 1500.** With a single season the numbers are still converging; use `seasonsBack: 3` or more for ratings that reflect real strength rather than a good start.
- **Teams are profiled per league.** A club that changes division produces one row per league it appears in.
- **Team names are the provider's**, in English where a common English name exists (`Bayern Munich`, not `Bayern München`).
- This Actor provides **data and analysis only**, not predictions or betting advice.

***

### Related

- [Football Data API](https://apify.com/smoked_drift/european-football-results-odds) — the underlying match dataset, with closing odds and market analytics
- [Football Odds Comparison](https://apify.com/smoked_drift/football-odds-comparison) — best available price per outcome and line movement across 9+ bookmakers

***

### Support

Report a broken row or a missing league in the **Issues** tab of this Actor.

# Actor input Schema

## `leagues` (type: `array`):

Competitions to profile. Use a preset ('big-five', 'big-five-plus-second', 'france', 'england', 'all') or explicit codes: E0-E3, EC, SC0-SC3, D1-D2, I1-I2, SP1-SP2, F1-F2, N1, B1, P1, T1, G1.

## `seasonsBack` (type: `integer`):

How many seasons to aggregate, starting from the current one. More seasons give Elo time to converge and make the totals more meaningful.

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

Optional. Profile only these teams. Case-insensitive partial match, so 'Marseille' also matches 'Olympique Marseille'.

## `minMatches` (type: `integer`):

Skip teams with fewer matches than this in scope. Useful early in a season to filter out one-game samples.

## `sortBy` (type: `string`):

Order of the output rows. Elo is the default because it is comparable across leagues; points are not.

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

Optional. Only count matches on or after this date.

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

Optional. Only count matches on or before this date.

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

Hard cap on returned team profiles.

## Actor input object example

```json
{
  "leagues": [
    "big-five"
  ],
  "seasonsBack": 1,
  "minMatches": 1,
  "sortBy": "elo",
  "maxItems": 2000
}
```

# Actor output Schema

## `teams` (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 = {
    "leagues": [
        "big-five"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("smoked_drift/football-team-stats-elo").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 = { "leagues": ["big-five"] }

# Run the Actor and wait for it to finish
run = client.actor("smoked_drift/football-team-stats-elo").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 '{
  "leagues": [
    "big-five"
  ]
}' |
apify call smoked_drift/football-team-stats-elo --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,smoked_drift/football-team-stats-elo"
        }
    }
}
```

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/XAhBOyRtnwcBnYafi/builds/VKNZKJgLvJ3eLiI74/openapi.json
