Transfermarkt APItransfermarkt.nl ↗
Access Transfermarkt.nl club lists, squad rosters with market values, and full player transfer histories via 3 structured JSON endpoints.
What is the Transfermarkt API?
This API exposes 3 endpoints covering Transfermarkt.nl league and club data: league club listings with squad market values, full club squad rosters with per-player contract and loan details, and complete transfer histories. The get_club_squad endpoint alone returns over 15 fields per player including market value, contract end date, and the club a player was signed from. It defaults to the Danish Superliga but accepts any Transfermarkt competition code.
curl -X GET 'https://api.parse.bot/scraper/a26f2bdb-2793-4d61-b7ce-9f54b13fd7b0/list_league_clubs?competition_id=DK1' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace transfermarkt-nl-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Transfermarkt SDK — league → club squad → player transfers."""
from parse_apis.transfermarkt_nl_api import Transfermarkt, InputNotFound
client = Transfermarkt()
# Fetch the Danish Superliga's current-season overview.
league = client.leagues.get(competition_id="DK1")
print(f"{league.competition_name} ({league.season_label}) — {len(league.clubs)} clubs")
# Pick the first club and browse its squad.
club = league.clubs[0]
print(f"\n{club.name} (squad size {club.squad_size}, value {club.total_market_value_display})")
# Construct a Club from the discovered id, then list players (capped).
squad = client.club(club_id=club.club_id)
for player in squad.players.list(limit=5):
loan_tag = " [on loan]" if player.on_loan else ""
print(f" {player.name} — {player.position}, {player.market_value_display}{loan_tag}")
# Drill into one player's full transfer history.
first_player = squad.players.list(limit=1).first()
if first_player is not None:
try:
detail = client.player(player_id=first_player.player_id)
for transfer in detail.transfers.list(limit=5):
print(f" {transfer.date}: {transfer.from_club} → {transfer.to_club} ({transfer.fee})")
except InputNotFound:
print(f" Player {first_player.player_id} not found")
print("\nexercised: leagues.get / club().players.list / player().transfers.list")
Lists the clubs of one league season with squad size, average age, foreigner count and total/average squad market value in EUR, plus the list of seasons available for that league. One page fetch, no pagination. Defaults to the Danish Superliga and the current season when season_id is omitted. An unknown competition code returns a stale_input (input_not_found) error.
| Param | Type | Description |
|---|---|---|
| season_id | string | Season identifier as the year the season starts (e.g. 2024 for 24/25); values come from available_seasons[*].season_id. Omitted = the current season. |
| competition_id | string | Transfermarkt competition code (short alphanumeric, e.g. DK1 for the Danish Superliga). |
{
"type": "object",
"fields": {
"clubs": "array of clubs: club_id (use with get_club_squad), name, squad_size, average_age, foreigners, average_market_value_eur, total_market_value_eur (integers in EUR, null when the site shows '-'), total_market_value_display",
"season_id": "season actually returned (year the season starts)",
"season_label": "season label such as 26/27",
"competition_id": "competition code echoed as resolved",
"competition_name": "league name as shown on the site",
"available_seasons": "array of {season_id, label} selectable for this league"
},
"sample": {
"data": {
"clubs": [
{
"name": "FC Midtjylland",
"club_id": "865",
"foreigners": 18,
"squad_size": 29,
"average_age": 24.9,
"total_market_value_eur": 76700000,
"average_market_value_eur": 2640000,
"total_market_value_display": "€76.70m"
},
{
"name": "FC Copenhagen",
"club_id": "190",
"foreigners": 17,
"squad_size": 25,
"average_age": 25.1,
"total_market_value_eur": 64050000,
"average_market_value_eur": 2560000,
"total_market_value_display": "€64.05m"
}
],
"season_id": "2026",
"season_label": "26/27",
"competition_id": "DK1",
"competition_name": "Superliga",
"available_seasons": [
{
"label": "26/27",
"season_id": "2026"
},
{
"label": "25/26",
"season_id": "2025"
}
]
},
"status": "success"
}
}About the Transfermarkt API
League and Club Listings
The list_league_clubs endpoint returns all clubs in a given league season, identified by a competition_id (e.g. DK1 for the Danish Superliga). Each club entry includes squad_size, average_age, foreigners count, and both average_market_value_eur and total_market_value_eur. The response also includes an available_seasons array of {season_id, label} pairs, so you can discover which seasons exist for a league before making further calls. If no season_id is supplied, the current season is returned.
Squad Data
Passing a club_id from list_league_clubs into get_club_squad returns a full roster for that club and season. Each player object includes position, shirt_number, date_of_birth, age, nationalities, height, foot, join_date, the club the player was signed from, the fee paid on arrival, contract_end, market_value_eur, previous_market_value_eur, captaincy flag, and loan status. The player_count field confirms how many rows the squad table contained. Use player_id values from this response to call the transfer history endpoint.
Player Transfer History
The get_player_transfers endpoint accepts a numeric player_id and returns the player's full recorded transfer history, newest first. Each transfer record carries season, date (YYYY-MM-DD), from_club and to_club with their respective IDs, market_value_display at the time of the move, and a fee field that can be a monetary amount, loan transfer, End of loan, free transfer, or - when no fee is recorded. The transfer_count field gives the total number of moves on record.
The Transfermarkt API is a managed, monitored endpoint for transfermarkt.nl — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when transfermarkt.nl changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official transfermarkt.nl API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Track squad market value changes across seasons for a given club using
total_market_value_eurfromlist_league_clubs. - Identify out-of-contract players by filtering
contract_enddates inget_club_squadresponses. - Map loan networks by collecting
loan_statusfields across multiple clubs in a league. - Build a player career timeline from
get_player_transfers, showing each club move with fee and market value context. - Compare foreigner ratios across a league by aggregating the
foreignersfield fromlist_league_clubs. - Monitor market value trends for a player by comparing
market_value_eurandprevious_market_value_eurfrom squad data. - Identify free transfer or end-of-loan acquisitions by filtering the
feefield in transfer histories.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Transfermarkt have an official developer API?+
Which leagues can I query with `list_league_clubs`?+
competition_id parameter (e.g. DK1 for the Danish Superliga, GB1 for the English Premier League). The endpoint defaults to the Danish Superliga if no competition_id is supplied. Use the available_seasons array in the response to confirm which season identifiers are valid for that competition.What does the `fee` field in transfer history actually contain?+
fee field reflects exactly what Transfermarkt records for that move. It can be a numeric amount, or one of the text labels loan transfer, End of loan, free transfer, or -. There is no separate boolean flag distinguishing loans from permanent transfers; you need to parse the label itself.Does the API cover individual match statistics or goal tallies for players?+
Is historical squad data available, or only the current season?+
list_league_clubs and get_club_squad accept a season_id parameter (the year the season starts, e.g. 2019). The available_seasons array returned by list_league_clubs lists every season Transfermarkt exposes for that competition, so you can iterate over past seasons programmatically.