Transfermarkt Scraper
Pricing
from $5.00 / 1,000 successful data requests
Transfermarkt Scraper
FastAPI service scraping Transfermarkt, served as an HTTP API via Apify Standby (scale-to-zero: the container stops when idle and cold-starts on the next request). The OpenAPI schema drives Apify's automatic MCP tool generation.
Pricing
from $5.00 / 1,000 successful data requests
Rating
0.0
(0)
Developer
Bob The Builder
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
7 hours ago
Last modified
Categories
Share
Extract Transfermarkt football data: player profiles, market values, transfer fees, club squads, national-team call-ups, match line-ups, league standings and top scorers. Query it as a REST API or call it directly from an AI agent as 33 named tools. No login, no API key on the target site, JSON out.
What Transfermarkt API can do
| ⚽ Players | Profiles, market-value history, full transfer record, career, achievements, injuries, shirt numbers, per-season stats |
| 🏟 Clubs | Squads, profiles, transfers in and out, season fixtures across every competition |
| 🏆 Competitions | Standings, member clubs, top scorers, assists, goal contributions, clean sheets, attendance, past champions |
| 📋 Matches | Starting XI, substitutes and manager for both sides of any match |
| 💶 Market | Most valuable players, latest transfers, all-time transfer records, market-value movers, free agents, expiring contracts |
| 🌍 Rankings | FIFA world ranking, UEFA club coefficients, available coaches |
| 🤖 AI agents | Every endpoint is published as an individually named MCP tool, so an agent can call get_player_transfers directly |
What data you get
Every response carries an updatedAt timestamp and the absolute Transfermarkt url it came from, so any number can be traced back to the page it was read off.
Player search:
{"updatedAt": "2026-08-12T10:43:59Z","query": "haaland","url": "https://www.transfermarkt.com/schnellsuche/ergebnis/schnellsuche?query=haaland","pageNumber": 1,"lastPageNumber": 2,"results": [{"id": "418560","name": "Erling Haaland","position": "CF","club": { "id": "281", "name": "Manchester City" },"age": 26,"nationalities": ["Norway"],"marketValue": 220000000}]}
A player inside a match line-up, carrying the club he was registered with on that date:
{"id": "565093","name": "Bart Verbruggen","shirtNumber": "1","position": "Goalkeeper","nationality": ["Netherlands"],"marketValue": 40000000,"clubId": "1237","clubName": "Brighton & Hove Albion"}
How to use it
The actor runs in Standby mode, so it behaves like a normal HTTP API. There is no run to start and no dataset to poll.
BASE=https://toned-jade--transfermarkt-scraper.apify.actorcurl -H "Authorization: Bearer $APIFY_TOKEN" "$BASE/players/search/haaland"curl -H "Authorization: Bearer $APIFY_TOKEN" "$BASE/players/418560/transfers"curl -H "Authorization: Bearer $APIFY_TOKEN" "$BASE/competitions/GB1/standings"
Browsable docs at /docs, machine-readable schema at /openapi.json.
For AI agents, point an MCP client at the actor and the 33 endpoints arrive as named tools with typed arguments. No glue code.
Use https://toned-jade--transfermarkt-scraper.apify.actor/mcp/ as the MCP URL
with your Apify token in the Authorization: Bearer ... header.
Pricing and request limits
Each successful data request costs $0.005 ($5 per 1,000 requests), whether made through REST or an MCP tool. Cached answers and statistics endpoints have the same price. Failed requests, documentation and tool discovery have no data-event charge. Apify charges Standby compute and storage separately. Live data requires a paid Apify plan; free-plan accounts can browse documentation.
A run processes one data request at a time, with a maximum of 1,000 attempts and $5 in data events, or the lower spending limit you set on Apify. Five consecutive failed requests stop further work in that run. HTTP 429 means retry after the indicated delay or start a new run if its allowance is exhausted; HTTP 402 means the run's spending limit is exhausted. Each page requested counts separately.
Successful answers are saved in the run's default key-value store before charging.
The REST response header X-Apify-Result-Key identifies the saved answer. If billing
is temporarily unavailable, HTTP 503 includes an operationId; check the record
RESULT-<operationId> in that run's store before repeating the data request.
Reading an existing record through Apify's storage API incurs no new data event.
Storage retention follows your Apify account settings. A new data call, including
a repeated call for the same resource, is a new billable operation.
Large or repeatedly failing upstream responses may return HTTP 502. Results reflect the source page available at collection time; missing source fields remain missing.
Two things that will bite you if you skip them
fee and marketValue are not the same number. fee is what a transfer actually cost. marketValue is Transfermarkt's own estimate. They disagree routinely, and fee is legitimately 0 or missing for a free transfer, a loan, or an undisclosed sum. Substituting one for the other quietly corrupts anything you calculate downstream.
National-team line-ups resolve each player to his club on the match date, not today's club. Ask a squad endpoint who played for Norway in a March qualifier and you get their current clubs, which is wrong for anything retrospective. Chain /clubs/{id}/fixtures into /matches/{id}/lineups and every player carries clubId and clubName as they stood on the day. Qualifying campaigns run across several seasons, so enumerate seasons rather than assuming one.
Notes and exceptions
- Club endpoints detect a national team and return the call-up list with caps, goals and debut, rather than a club squad.
- A player who has retired returns
club: "Retired"and no market value. - Upstream 404s come back as 404. Transient upstream failures are retried before surfacing as an error.
- Season parameters are 4-digit start years:
2025means 2025/26. Omit for the current season. - Responses are cached briefly, so repeat calls for the same resource return without re-fetching.
FAQ
Do I need a Transfermarkt account? No. It reads public pages.
How current is the data? Live at request time, with a short cache. updatedAt tells you exactly when.
Can I get historical transfers? Yes, /players/{id}/transfers returns the full career record with fees, dates and both clubs.
What identifies a player or club? The Transfermarkt numeric ID as a string. Get it from the search endpoints, then reuse it everywhere.
Is it rate limited? Each run accepts one data request at a time. Honor Retry-After and spread bulk work out rather than firing it in parallel.
Is scraping Transfermarkt legal? It reads publicly available pages. You are responsible for how you use and redistribute the data, and for complying with Transfermarkt's terms. Check them before building on this commercially.