Transfermarkt Scraper — Market Values & Transfers | $3/1K
Pricing
from $2.91 / 1,000 player records
Transfermarkt Scraper — Market Values & Transfers | $3/1K
Scrape public Transfermarkt player data for profiles, squads, rankings, values, and transfers. Get structured player records. Run with supported inputs; no login or API key. Pricing: $0.003 per player record plus $0.00005 per Actor Start event.
Pricing
from $2.91 / 1,000 player records
Rating
0.0
(0)
Developer
Vitalii Bondarev
Maintained by CommunityActor stats
0
Bookmarked
17
Total users
2
Monthly active users
44 days
Issues response
5 days ago
Last modified
Categories
Features
Share
Transfermarkt Player Data Scraper
This Actor reads public Transfermarkt pages and the site's own JSON data (ceapi) to extract player profiles, squads, rankings, market values and transfers.
- Scrape individual player profiles, club squads or whole leagues.
- Extract current and peak market values, contracts, biographies and transfer history (profile mode; club, league and ranking rows lack these fields).
- Search player names or collect the most-valuable-players ranking.
- Use
market_value_source,parse_confidenceandwarningsto inspect data quality. - No login or API key is required; Apify Proxy is optional.
What you get
Each player record can include the following fields. null means the source does not provide a value; warnings is [] when there are no warnings.
| Field family | Fields | Type | Empty value |
|---|---|---|---|
| Identity | player_id, name, full_name, shirt_number | string | null when missing or empty |
| Club and role | current_club, league, position | string | null when absent |
| Biography | age | integer | null |
| Biography | date_of_birth | string (DD/MM/YYYY) | null |
| Biography | place_of_birth, height, foot | string | null when absent |
| Biography | nationality | array of strings | null |
| Contract and representation | contract_until, agent, outfitter | string | null when absent |
| Links | profile_url, image_url | string | null when absent |
| Numeric values | market_value, market_value_peak | integer | null |
| Display values | market_value_str, market_value_currency, market_value_peak_str | string | null |
| Peak date | market_value_peak_date | string (DD/MM/YYYY) | null |
| Value provenance | market_value_source | string (html, ceapi, html+ceapi) | null when there is no value |
| Value history | market_value_history | array of objects | null when not included or unavailable |
| Transfers | transfers | array of objects | null in club, league and rankings rows; [] in profile mode when there are none |
| Quality | parse_confidence | number, 0 to 1 | never null |
| Quality | warnings | array of strings | [] |
| Metadata | scraped_at | ISO 8601 string | never null |
market_valueis an integer in the currency shown inmarket_value_currency; no conversion is applied.market_value_historyis included in profile mode whenincludeMarketValueHistoryis enabled, withdate,value,value_strandclub.- Profile URLs and profiles resolved from
searchprovide transfer data when available. Transfer entries containseason,date,from_club,to_club,fee,fee_str,fee_typeandmarket_value_str.fee_typeisfee,free,loan,end_of_loanorunknown, ornullwhen there is no fee text.
Sample output
This club-squad row is from a leagueCodes run (TDeC, maxResults: 3) and shows 17 of 30 fields. Club, league and rankings rows have the three peak fields, market_value_history and transfers as null; profile mode fills peak fields and transfers, and fills history only with includeMarketValueHistory: true.
{"player_id": "643063","name": "Diego Romero","current_club": "Universitario de Deportes","league": "Liga 1 Clausura","position": "Goalkeeper","age": 25,"nationality": ["Peru"],"market_value": 1000000,"market_value_str": "€1.00m","market_value_source": "html","market_value_peak": null,"market_value_peak_date": null,"market_value_history": null,"transfers": null,"parse_confidence": 1,"warnings": [],"scraped_at": "2026-10-27T07:07:01.630603+00:00"}
Pricing
This is Pay per event. The listed events are the Actor Start event and the primary dataset-item event for each football player record. Platform usage is not billed separately because this Actor does not use the Pay per event + usage option.
| Event | When it applies |
|---|---|
apify-actor-start — Actor Start | Charged once per GB of run memory, minimum one event |
apify-default-dataset-item — player record | For one football player profile pushed to the dataset |
On the Free plan, 500 records cost 500 × $0.003 + $0.00005 = $1.50005, with one Actor Start event.
| Plan | Player-record event | Actor Start event |
|---|---|---|
| Free | $0.003 per record | Free plan: $0.00005 per event |
| Bronze | $0.00297 per record | $0.0000495 per event |
| Silver | $0.00294 per record | $0.000049 per event |
| Gold | $0.00291 per record | $0.0000485 per event |
| Platinum | $0.00288 per record | $0.000048 per event |
| Diamond | $0.00285 per record | $0.0000475 per event |
On the Free plan, 1,000 player records cost 1,000 × $0.003 = $3.00 and 10,000 player records cost 10,000 × $0.003 = $30.00. Each run also adds the Free plan's $0.00005 for the Actor Start event.
The Apify Free plan's $5 monthly platform usage credit covers 1,666 player records after one Actor Start event: floor((5 − 0.00005) / 0.003) = 1,666. This is a billing figure, not a promise that an input returns that many records.
The transfer-record and mv-history-point events have no price, so you are not charged for them.
How to use
- Choose one or more modes:
playerUrls,clubUrls,leagueCodes,searchorrankings. - Enter Transfermarkt profile, squad or competition URLs, or supported bare IDs and codes.
- Clear the prefilled
playerUrlsvalue28003andsearchvalueHaalandunless you want those records; every filled mode runs. - Set
maxResultsfor club, league, rankings and search requests; direct player mode returns one record per supplied URL. - Enable
includeMarketValueHistoryfor complete dated valuation points in profile requests. - Add
proxyConfigurationonly when you want Apify Proxy. - Run the Actor, inspect the returned quality fields, and repeat through Apify Schedules, with weekly as a starting point.
Example input for the first 100 Premier League records:
{"leagueCodes": ["GB1"],"maxResults": 100,"includeMarketValueHistory": false}
Export the resulting dataset as JSON or CSV, or read it through the Apify dataset API.
Input parameters
| Parameter | What it does | Default |
|---|---|---|
playerUrls | Array of Transfermarkt player profile URLs or bare numeric player IDs. Each resolved player is scraped as a profile. | Empty when omitted |
clubUrls | Array of Transfermarkt squad URLs or bare numeric club IDs. Each squad player becomes one record. | Empty when omitted |
leagueCodes | Array of competition codes or URLs. The Actor finds member clubs and processes their squads. | Empty when omitted |
search | Free-text player name query. Matching players are resolved to profiles. | Empty when omitted |
rankings | When true, scrapes the most-valuable-players ranking. | false |
maxResults | Maximum player records for club, league, rankings and search requests. Accepted range: 1–10000. | 100 |
includeMarketValueHistory | Adds full dated market-value history in profile mode for playerUrls and search. | false |
proxyConfiguration | Optional Apify Proxy configuration. | useApifyProxy: false |
disableUsageStats | Set to true to turn off the run summary described in Usage statistics. | false |
Common competition codes include GB1 for the Premier League, ES1 for LaLiga, IT1 for Serie A, L1 for the Bundesliga, FR1 for Ligue 1 and MLS1 for MLS. The Actor also accepts 2–8-character codes starting with a letter or competition URLs, with case preserved.
Limits and edge cases
| Condition | What you see | What to do |
|---|---|---|
| No input mode is filled, or no player is delivered | The run ends Failed. No player-record events are charged, but the Actor Start event is charged when the run starts. OUTPUT contains message, emptyReason (NO_INPUT, NO_MATCH or BLOCKED) and totalItems: 0; NO_MATCH and BLOCKED also contain failures, scrapedAt and failedSources, while NO_INPUT contains error: "no_input". | Fill at least one input mode. For NO_MATCH or BLOCKED, check failedSources. |
| A player is skipped or partly filled | A failed profile fetch, missing identity, or parse_confidence below 0.5 prevents the record from being pushed or charged. A failed ceapi call can still deliver the profile with transfers: [] and null peak fields. | Inspect warnings and the returned fields. |
| A league page or club produces no valid records | The league page and each club get up to three attempts on fresh sessions. A 404 or missing competition is NO_MATCH; otherwise it is BLOCKED. Empty sources appear in failedSources; no overall records means Failed. | Check the competition code or URL and review failedSources. |
| Some sources succeed and others fail | The run ends Succeeded. Delivered records are pushed and OUTPUT contains totals, failures, scrapedAt, failedSources and a message beginning Partial: …. | Use delivered records and inspect failed sources before rerunning. |
| Records are produced during a run | Profile and search rows arrive one player at a time; club and league rows one club at a time; rankings rows after the ranking is read. Each batch is charged after its push. | Use the dataset as rows arrive. |
| An abort, timeout or failure stops a run | Pushed rows remain and stay charged. OUTPUT is written only at the end or when the run fails for lack of results. Aborted or timed-out runs have no OUTPUT; an interrupted rankings run can leave no ranking rows. | Check the dataset and rerun if needed. |
maxResults is reached | It applies per club URL, league code, search and ranking, and is ignored for playerUrls. | Increase it within 1–10000. |
| A league contains many clubs | One competition input processes at most 40 clubs. | Split the work across inputs. |
| Rankings are enabled | Pages contain 25 rows. Reading stops at maxResults, an empty page, a page with fewer than 25 rows, or a fetch failure. Earlier rows remain delivered and the failure appears in failedSources. | Set maxResults to the desired number of ranking rows. |
| Fetch errors occur | HTTP 429, 403, 503, block-like or shorter-than-12,000-character HTML is retried after 10 s, 20 s and 40 s, for up to four requests. HTTP 404, other non-2xx responses, network errors, empty bodies and non-JSON ceapi responses stop without retry. A failed profile is skipped; a failed ceapi call can still deliver the profile with transfers: [] and null peak fields. | Check the input or run again for a transient error. |
FAQ
How much does it cost to scrape player data?
The Free plan charges $0.003 per player record and $0.00005 per Actor Start event. All plan rates are in Pricing.
What happens when no players are returned?
The run ends as Failed and no player-record events are charged. The reason is in OUTPUT.
Why might a player or league not work?
A player can be skipped if its page fails, its identity is missing, or confidence is below 0.5. Blocked responses are retried under the conditions in Limits and edge cases.
Can I use this public data legally?
The Actor reads publicly available player, club and market-value pages from Transfermarkt and requires no authentication. Whether a particular use is allowed depends on the source terms and applicable law for your use case; this README provides no legal guarantee.
Related actors
- Transfermarkt Scraper RU — related football data Actor focused on transfers and market values for players in Russia and the CIS.
Usage statistics
This Actor creates a small, content-free summary at the end of each run, used only to monitor reliability and improve this Actor. No input values, credentials or scraped data are sent.
A copy of the exact record for your run is saved as USAGE_STATS in your own Apify key-value store.
To opt out, set disableUsageStats to true in the input. Nothing is sent then.