# Transfermarkt Scraper: Market Values, Contracts & Injuries (`sports-odds-lab/transfermarkt-scraper`) Actor

Transfermarkt scraper for football players: market value and its full history, contract until, agent, position, foot, height, nationality, club and national team, injury history. Whole leagues (Premier League, LaLiga…), clubs or single players. Fast, no proxy needed.

- **URL**: https://apify.com/sports-odds-lab/transfermarkt-scraper.md
- **Developed by:** [Min Maxxxer](https://apify.com/sports-odds-lab) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 players

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Transfermarkt Scraper: Market Values, Contracts & Injuries

> 💰 **$1 per 1,000 players** — market value history and injuries included, no proxy to pay for. Press **Start**: the prefilled input returns 30 Premier League players in a few seconds.

Get **football player data from Transfermarkt** for whole leagues, clubs or single players: **current market value and its full history**, previous and highest value, **contract until**, last contract renewal, **agent**, position, preferred foot, height, date and place of birth, nationalities, club, shirt number, **national team** and the complete **injury history**. One clean row per player, ready for a spreadsheet, a database or a scouting model.

**Fast and reliable:** the Actor reads Transfermarkt's own app data (JSON) instead of parsing web pages, so it needs **no proxy**, does not break when the website layout changes and reads a whole league in about a minute — the Premier League and LaLiga (1,060 players) with market value histories and injuries took 65 seconds in our test.

### Three ways to choose players

- **Competitions** — every player of every club in the league: a name (`Premier League`, `LaLiga`, `Serie A`, `Bundesliga`, `Ligue 1`, `Eredivisie`, `Liga Portugal`, `Championship`, `MLS`, `Ekstraklasa`, `Champions League` …), the code from the Transfermarkt link (`GB1`, `ES1`, `IT1`, `L1`, `FR1` …) or the link itself
- **Clubs** — whole squads: club links (`…/startseite/verein/281`) or IDs (`281`)
- **Players** — single players: player links (`…/profil/spieler/418560`) or IDs (`418560`)

Mix them freely in one run; every player is saved once.

### What you get for each player

- **Player**: Transfermarkt ID and link, name, full name, photo, date of birth, age, place and country of birth, nationality and second nationality
- **Profile**: position (with short code and group), preferred foot, height in cm, kit supplier
- **Market value** (EUR): current value and date, previous value and date, change in %, **highest value ever** and its date
- **Market value history** *(on by default)*: every valuation of the career with date, club, age and season
- **Club**: club, country, league, shirt number, captain, joined on, debut
- **Contract**: contract until, last contract renewal, **agent / agency**
- **National team**: team and debut date
- **Injury history** *(optional)*: injury, start, end, days out, games missed, season, plus total days injured (overlapping injuries counted once)

### Example input

```json
{
  "competitions": ["Premier League", "LaLiga", "Serie A"],
  "clubs": ["https://www.transfermarkt.com/legia-warschau/startseite/verein/255"],
  "players": ["https://www.transfermarkt.com/erling-haaland/profil/spieler/418560"],
  "includeMarketValueHistory": true,
  "includeInjuries": true
}
```

### Example output (shortened)

```json
{
  "playerId": "418560",
  "name": "Erling Haaland",
  "url": "https://www.transfermarkt.com/erling-haaland/profil/spieler/418560",
  "dateOfBirth": "2000-07-21",
  "age": 26,
  "nationality": "Norway",
  "heightCm": 195,
  "foot": "left",
  "position": "Centre-Forward",
  "marketValueEur": 220000000,
  "marketValueDate": "2026-07-22",
  "highestMarketValueEur": 220000000,
  "club": "Manchester City",
  "shirtNumber": 9,
  "contractUntil": "2034-06-30",
  "agent": "Rafaela Pimenta",
  "nationalTeam": "Norway",
  "marketValueHistory": [{"date": "2016-12-18", "valueEur": 200000, "club": "Bryne FK", "age": 16, "season": 2015}],
  "injuries": [{"injury": "Knock", "start": "2026-02-26", "end": "2026-03-01", "days": 3, "gamesMissed": 1}]
}
```

### Use cases

- **Scouting and recruitment**: every player of a league with value, age, contract end and agent — filter contracts expiring next summer
- **Market value research**: value histories for valuation models, peak values, players whose value jumped this window
- **Fantasy football and betting models**: injury history and days out per player
- **Club and agency analysis**: squad values, agent portfolios across leagues

### Pricing

**$1 per 1,000 players** (pay per event), market value history and injury history included. No proxy and no separate platform usage to pay for. Apify's free plan covers a few thousand players a month.

### Notes

- Data comes from Transfermarkt's public player data. Transfer history and per-season statistics are not included yet.
- Unknown links or IDs are skipped with a note in the log. If the source keeps failing for some players, the run ends as INCOMPLETE and the log lists their IDs to run again; a market value history that could not be read is `null`, while `[]` means the player has no valuations.
- For football **odds and results** (1X2, over/under, closing lines, xG, 1,000+ competitions) see our [Soccer & Football Betting Odds](https://apify.com/sports-odds-lab/football-odds-results) Actor.

# Actor input Schema

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

Every player of every club in these leagues. A name (Premier League, LaLiga, Serie A, Bundesliga, Ligue 1, Eredivisie, Liga Portugal, Championship, MLS, Ekstraklasa, Champions League …), the code from the Transfermarkt link (GB1, ES1, IT1, L1, FR1 …) or the link itself, e.g. https://www.transfermarkt.com/premier-league/startseite/wettbewerb/GB1.

## `clubs` (type: `array`):

Every player of these squads: Transfermarkt club links (…/verein/281) or club IDs (281).

## `players` (type: `array`):

Single players: Transfermarkt player links (…/profil/spieler/418560) or player IDs (418560).

## `includeMarketValueHistory` (type: `boolean`):

Every market value update of each player's career, with the club and age at the time.

## `includeInjuries` (type: `boolean`):

Every recorded injury: type, start, end, days out and games missed, plus the total days injured (overlapping injuries counted once).

## `maxPlayers` (type: `integer`):

Stop after this many players (0 = no limit). A Premier League squad list is about 500–550 players.

## `concurrency` (type: `integer`):

Advanced. Requests in parallel (1–32).

## Actor input object example

```json
{
  "competitions": [
    "Premier League"
  ],
  "includeMarketValueHistory": true,
  "includeInjuries": false,
  "maxPlayers": 30,
  "concurrency": 8
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per player: club, position, market value, contract and agent.

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

Full records with market value history and injuries.

# 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 = {
    "competitions": [
        "Premier League"
    ],
    "maxPlayers": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("sports-odds-lab/transfermarkt-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 = {
    "competitions": ["Premier League"],
    "maxPlayers": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("sports-odds-lab/transfermarkt-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 '{
  "competitions": [
    "Premier League"
  ],
  "maxPlayers": 30
}' |
apify call sports-odds-lab/transfermarkt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sports-odds-lab/transfermarkt-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/C3jI84CxHXsTZkte8/builds/jieebbtwU9wg98oVc/openapi.json
