# Transfermarkt Scraper (`parsebird/transfermarkt-scraper`) Actor

Scrape Transfermarkt player profiles, market values, transfer history, club squads, and league-wide transfer windows. Search by name or paste a Transfermarkt URL.

- **URL**: https://apify.com/parsebird/transfermarkt-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:** News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 records

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/platform/actors/running/actors-in-store#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

### Transfermarkt Scraper

Scrape [Transfermarkt](https://www.transfermarkt.com/) — player profiles, market values, transfer history, club squads, and league-wide transfer windows — by searching a name or pasting a Transfermarkt URL.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Pull a player's full transfer history, market value timeline, agent contacts, and season-by-season performance stats, or a club's squad and current transfer window, or an entire competition's transfer activity in one run.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
parsebird/transfermarkt-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/transfermarkt-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: scrapeType (string, "players"/"clubs"/"transfersPlayer"/"transfersClub"/"transfersCompetition", default "players"), items (string array, max 100 — player/club/competition names or Transfermarkt URLs, matched to the entity type implied by scrapeType), playersWithoutStatistics (boolean, default false, players only — skip seasonal stats for a faster run), playerStatsSelection (string array, default ["last_6"] — "last_6" or specific seasons like "2025"/"2024", players only), playerMarketValueHistory (boolean, default false, players only — full historical market value timeline), playerAgentDetails (boolean, default false, players only — agent/agency contact info), proxyConfig (object, default residential Apify proxy — datacenter IPs are blocked by Transfermarkt). Output fields vary by scrapeType: players → playerName, jerseyNumber, currentClub, playerLeague, marketValue, arrivalDate, contractEnd, transferHistory, trophies, playerDetails, playerAgent (optional), marketValueHistory (optional), playerStats (optional), profileUrl; clubs → clubName, clubLeague, totalMarketValue, clubTrophies, clubDetails, staff, clubSquad, topArrivals, topDepartures; transfersPlayer → ptPlayerName, ptTransfers, ptTotalFees, ptSourceUrl; transfersClub → ctClubName, ctSeason, ctArrivals, ctDepartures, ctSummary; transfersCompetition → competitionName, totalClubs, totalArrivals, totalDepartures, clubs (per-club arrivals/departures). Full actor spec: fetch build via GET https://api.apify.com/v2/acts/parsebird~transfermarkt-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
```

### What does Transfermarkt Scraper do?

This Actor scrapes [Transfermarkt](https://www.transfermarkt.com/), the reference database for football player valuations, transfer records, and squad data, combining its public pages with the same internal API its own site widgets use for stats, market value history, and transfer records — giving you clean, structured data without a browser.

- 🔎 **Five scrape modes** — full player profiles, club profiles, a player's complete transfer history, a club's transfer window, or a whole competition's transfer window
- 💰 **Market value tracking** — current market value on every player, plus an optional full historical timeline (date, season, age, club, value)
- 📋 **Deep player data** — bio, position, contract, current club and league, trophies, transfer history with fees, and season-by-season performance stats (appearances, goals, assists, cards, minutes) across up to 6 recent seasons or any specific season back to 2021/22
- 🧑‍💼 **Agent contacts, opt-in** — agency name, location, email, website, and portfolio size for a player's agent
- 🏟️ **Club and league transfer windows** — squad, coaching staff, trophies, and top transfer activity for a club, or every arrival and departure across an entire competition in one call
- 🔗 **Flexible input** — search by name or paste a Transfermarkt URL directly, mixed freely in the same run
- ⏱️ **Scheduling** — run this Actor on a timer via Apify Scheduler to track market value and transfer-window changes over a season
- 🔌 **API access** — trigger runs and pull results programmatically via the Apify API or client libraries
- 📊 **Flexible export** — download results as JSON, CSV, or Excel, or query them via API

### What data can you extract from Transfermarkt?

| Field | Description |
|-------|-------------|
| `playerName` / `currentClub` / `playerLeague` | Player identity and current team context |
| `marketValue` / `marketValueHistory` | Current market value, and its full historical timeline when enabled |
| `transferHistory` / `contractEnd` / `arrivalDate` | Career transfer moves, contract expiry, and join date |
| `playerStats` | Season-by-season performance per competition: appearances, goals, assists, cards, minutes played |
| `trophies` / `playerDetails` | Honors won, and bio fields (date of birth, citizenship, position, foot, height, agent) |
| `playerAgent` | Agency name, contact info, and portfolio size, when enabled |
| `clubSquad` / `staff` / `clubTrophies` | Full roster, coaching staff, and honors for a club |
| `ctArrivals` / `ctDepartures` / `ctSummary` | A club's transfer-window activity and net spend |
| `clubs` (per-competition) | Every club's arrivals and departures across a whole league's transfer window |

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `scrapeType` | string | No | `players` | `players`, `clubs`, `transfersPlayer`, `transfersClub`, or `transfersCompetition` |
| `items` | string array | **Yes** | sample names | Names or Transfermarkt URLs, max 100. Interpreted as players, clubs, or competitions depending on `scrapeType` |
| `playersWithoutStatistics` | boolean | No | `false` | Players only — skip seasonal stats for a faster, lighter run |
| `playerStatsSelection` | string array | No | `["last_6"]` | Players only — `last_6` or specific seasons (`"2025"`, `"2024"`, ...) |
| `playerMarketValueHistory` | boolean | No | `false` | Players only — full historical market value timeline |
| `playerAgentDetails` | boolean | No | `false` | Players only — fetch the agent's contact page (occasionally unavailable, so off by default) |
| `proxyConfig` | object | No | Residential Apify proxy | Transfermarkt blocks Apify's datacenter IP range, so residential is required |

### Output example

**Player** (`scrapeType: "players"`)

```json
{
  "playerName": "Dilane Bakwa",
  "jerseyNumber": "29",
  "currentClub": "Nottingham Forest",
  "playerLeague": { "name": "Premier League", "country": "England", "division": "First Tier" },
  "marketValue": "€28.00m",
  "arrivalDate": "2025-09-01",
  "contractEnd": "2030-06-30",
  "transferHistory": [
    { "season": "25/26", "date": "2025-09-01", "market_value": "€25.00M", "fee": "€35.00M", "left": "RC Strasbourg Alsace", "joined": "Nottingham Forest" }
  ],
  "trophies": [],
  "playerDetails": {
    "Date of birth": "2002-08-26",
    "Age": "23",
    "Citizenship": "France, DR Congo",
    "Position": "Attack - Right Winger",
    "Foot": "left",
    "Height": "1,80m",
    "Player agent": "Sport Cover"
  },
  "playerStats": [
    { "season": "25/26", "stats": [{ "appearances": "14", "minutes_played": "553", "assists": "2", "competition": "Premier League" }] }
  ],
  "profileUrl": "https://www.transfermarkt.com/x/profil/spieler/540664"
}
```

**Club transfer window** (`scrapeType: "transfersClub"`)

```json
{
  "ctClubName": "Paris Saint-Germain",
  "ctSeason": "25/26",
  "ctArrivals": [
    { "playerName": "Maghnes Akliouche", "age": "24", "nationalities": ["France", "Algeria"], "position": "Right Winger", "marketValue": "€50.00m", "fee": "€50.00m", "fromClub": "Monaco", "fromClubCountry": "France" }
  ],
  "ctDepartures": [
    { "playerName": "Gonçalo Ramos", "age": "25", "nationalities": ["Portugal"], "position": "Centre-Forward", "marketValue": "€30.00m", "fee": "€74.00m", "toClub": "AC Milan", "toClubCountry": "Italy" }
  ],
  "ctSummary": { "departuresCount": "9", "income": "€159.30m", "arrivalsCount": "11", "expenditure": "€152.00m", "transferRecord": "+€7.30m" },
  "ctSourceUrl": "https://www.transfermarkt.com/paris-saint-germain/startseite/verein/583"
}
```

Download results in **JSON, CSV, or Excel** directly from the Apify Console, or pull them programmatically via the API.

### Use cases

- **Scouting and analytics** — pull performance stats, market value trends, and contract situations for a shortlist of players
- **Transfer-window tracking** — run `transfersClub` or `transfersCompetition` on a schedule during a transfer window to monitor spending and arrivals/departures across a league
- **Market value monitoring** — track `playerMarketValueHistory` over time for valuation research or fantasy-football tools
- **Squad research** — pull a club's full roster, coaching staff, and trophy cabinet in one call
- **Agent/intermediary research** — resolve agency contacts and portfolio size behind a set of players

### How to scrape Transfermarkt with this Actor

1. Go to the [Transfermarkt Scraper](https://apify.com/parsebird/transfermarkt-scraper) page on Apify Store
2. Click **Try for free** — new users get a free trial to test the Actor before paying
3. Pick a **Scrape type** — players, clubs, player transfer history, club transfer window, or competition-wide transfer window
4. Add player, club, or competition **names or Transfermarkt URLs** to `items` (up to 100)
5. For players, toggle **seasons, market value history, and agent details** as needed
6. Click **Start** — the Actor resolves each item, fetches the relevant Transfermarkt pages, and normalizes every result
7. When the run finishes, download your data as **JSON, CSV, or Excel**, or fetch it via the API

### Use with the Apify API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("parsebird/transfermarkt-scraper").call(run_input={
    "scrapeType": "players",
    "items": ["Kylian Mbappé", "Erling Haaland"],
    "playerMarketValueHistory": True,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['playerName']} - {item['marketValue']} ({item['currentClub']})")
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('parsebird/transfermarkt-scraper').call({
    scrapeType: 'players',
    items: ['Kylian Mbappé', 'Erling Haaland'],
    playerMarketValueHistory: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.log(`${item.playerName} - ${item.marketValue} (${item.currentClub})`);
});
```

See the [Apify API documentation](https://docs.apify.com/api/v2) for full reference, or the Actor's **API** tab for ready-to-run request snippets in more languages.

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

This Actor uses **Pay-per-event** pricing with a single event — you only pay for records actually returned, with no separate platform rental fee.

| Event | Price per event (Free plan) | Price per 1,000 |
|-------|------------------------------|------------------|
| `record-scraped` | $0.00125 | $1.25 |

`record-scraped` is charged once per player, club, or transfer-window record pushed to the dataset — a `transfersCompetition` run charges once per competition, not per club inside it. Pricing per 1,000 events drops on paid Apify plans (Bronze $1.20, Silver $1.15, Gold $1.10). A 500-player run on the Free plan costs about $0.63. Start with the free trial and a short `items` list to preview results before scaling up.

### FAQ

**Why does this Actor require a residential proxy?**
Transfermarkt returns an empty challenge response to Apify's datacenter proxy range — confirmed by direct testing. The `proxyConfig` input defaults to a residential Apify proxy for this reason; switching it to datacenter will cause runs to fail.

**Where does the data come from?**
Player and club pages, search results, and transfer-window tables are scraped directly from transfermarkt.com. Transfer history, market value history, and season-by-season stats come from the same internal JSON endpoints Transfermarkt's own site loads when you view those pages — not a separate or unofficial third-party source.

**Why is `playerStats` sometimes missing a competition name or logo?**
Competition and club names are resolved in a single batched lookup per player. If that lookup fails (rare, transient upstream issue), the numeric stats still return but `competition`/`competition_img` may be `null` for that run — retrying usually resolves it.

**What counts as "last 6 seasons" in `playerStatsSelection`?**
The 6 most recent seasons that appear in the player's own game log, matching what Transfermarkt's profile page shows by default. Use explicit season values (e.g. `"2025"`, `"2022"`) to pin specific seasons instead.

**Why is `playerAgentDetails` off by default?**
It requires an extra request to the agent's own Transfermarkt page, which is occasionally unavailable for players without a fully set-up agency profile. Turn it on when you specifically need agent contact info.

**Can I mix names and URLs in the same run?**
Yes. `items` accepts a mix of plain names and Transfermarkt URLs in any order; each is resolved independently.

**Is it legal to scrape Transfermarkt?**
Transfermarkt's player, club, and transfer pages are publicly viewable without a login. You're responsible for complying with Transfermarkt's Terms of Service for your specific use case. See Apify's [blog post on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for general background.

**Can I access results via API?**
Yes. Every run's dataset is available through the [Apify API](https://docs.apify.com/api/v2) and client libraries (Python, JavaScript) — see the Actor's **API** tab for ready-made snippets.

**Can I schedule recurring runs?**
Yes. Use Apify's [Scheduler](https://docs.apify.com/platform/schedules) to run this Actor on a timer — useful for tracking market value or transfer-window changes over a season.

**Something not working?**
Open an issue on the Actor's **Issues** tab in Apify Console — the ParseBird team monitors it directly.

### Related Actors

Other data Actors from ParseBird:

- [SofaScore Scraper](https://apify.com/parsebird/sofascore-scraper) — live scores, fixtures, lineups, and standings
- [Polymarket Scraper](https://apify.com/parsebird/polymarket-scraper) — prediction-market odds and pricing data
- [HTTP Request Actor](https://apify.com/parsebird/http-request-actor) — general-purpose API/webhook integration

# Actor input Schema

## `scrapeType` (type: `string`):

What to scrape from Transfermarkt.

## `items` (type: `array`):

Player, club, or competition names, or Transfermarkt URLs. Max 100 items. What counts as a match depends on Scrape type (a player name for "players"/"Player transfer history", a club name for "clubs"/"Club transfer window", a competition name for "Competition-wide transfer window").

## `playersWithoutStatistics` (type: `boolean`):

Fetch only profile information, no seasonal statistics. Faster when you only need bio and market value data.

## `playerStatsSelection` (type: `array`):

Select one or more seasons of statistics to return. "Most recent 6 seasons" is the default and matches what Transfermarkt shows on a player's profile page.

## `playerMarketValueHistory` (type: `boolean`):

Return the complete historical market value timeline: dates, seasons, ages, values, and clubs. Adds one extra request per unique historical club.

## `playerAgentDetails` (type: `boolean`):

Fetch the player's agent/agency page for contact info and portfolio size. Off by default because the agent page is occasionally unavailable.

## `proxyConfig` (type: `object`):

Residential proxies are required — Transfermarkt blocks Apify's datacenter IP range outright.

## Actor input object example

```json
{
  "scrapeType": "players",
  "items": [
    "Lionel Messi",
    "Kylian Mbappé",
    "Cristiano Ronaldo"
  ],
  "playersWithoutStatistics": false,
  "playerStatsSelection": [
    "last_6"
  ],
  "playerMarketValueHistory": false,
  "playerAgentDetails": false,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "scrapeType": "players",
    "items": [
        "Lionel Messi",
        "Kylian Mbappé",
        "Cristiano Ronaldo"
    ],
    "playersWithoutStatistics": false,
    "playerStatsSelection": [
        "last_6"
    ],
    "playerMarketValueHistory": false,
    "playerAgentDetails": false,
    "proxyConfig": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/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 = {
    "scrapeType": "players",
    "items": [
        "Lionel Messi",
        "Kylian Mbappé",
        "Cristiano Ronaldo",
    ],
    "playersWithoutStatistics": False,
    "playerStatsSelection": ["last_6"],
    "playerMarketValueHistory": False,
    "playerAgentDetails": False,
    "proxyConfig": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/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 '{
  "scrapeType": "players",
  "items": [
    "Lionel Messi",
    "Kylian Mbappé",
    "Cristiano Ronaldo"
  ],
  "playersWithoutStatistics": false,
  "playerStatsSelection": [
    "last_6"
  ],
  "playerMarketValueHistory": false,
  "playerAgentDetails": false,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call parsebird/transfermarkt-scraper --silent --output-dataset

```

## MCP server setup

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