fmplayer APIfmplayer.net ↗
Search and filter FM 18–26 player databases, retrieve full profiles with attributes, contract details, best roles, and similar players via 2 endpoints.
What is the fmplayer API?
The fmplayer.net API exposes two endpoints covering Football Manager player data across nine game editions (FM 18 through FM 26). search_players returns paginated result sets of up to 50 players per page, filterable by name, nationality, age, current ability, and potential ability. get_player returns a single player's complete profile including every attribute group, contract terms, best roles with scores, personality badges, and a list of comparable players.
curl -X GET 'https://api.parse.bot/scraper/be792d47-ce5c-4019-826b-1cace8f01386/search_players?name=saka&version=26' \ -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 fmplayer-net-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: fmplayer.net SDK — search FM players, drill into full profiles."""
from parse_apis.fmplayer_net_api import FMPlayer, SortField, GameVersion, InputNotFound
client = FMPlayer()
# Search for high-ability young players, sorted by potential ability descending.
for ps in client.player_summaries.search(
ca_min=150, age_max=23, sort_by=SortField.PA, limit=5
):
print(ps.name, ps.positions, f"CA={ps.current_ability} PA={ps.potential_ability}")
# Drill down: take the top search hit and fetch the full profile via .details().
top = client.player_summaries.search(
ca_min=160, sort_by=SortField.CA, limit=1
).first()
if top is not None:
player = top.details()
print(player.name, player.club, f"Age {player.age}")
# Best roles
for role in player.best_roles:
print(f" {role.role}: {role.score}")
# Similar players listed on the profile
for sp in player.similar_players:
print(f" Similar: {sp.name} CA={sp.current_ability}")
# Point lookup by id discovered from search results
try:
same = client.players.get(player_id=top.player_id)
print(same.name, same.asking_value, same.badges)
except InputNotFound:
print("Player not found")
print("exercised: player_summaries.search / details / players.get")
Searches the Football Manager player database of one game version and returns one page of up to 50 player summary rows (id, name, positions, club, age, nation, wage, contract expiry, value, current/potential ability). All filters are optional and combine with AND; omitting every filter lists the whole database sorted by current ability descending, the site's default. Pagination is by `page` (1-based, 50 rows per page, one upstream round trip plus one form-page load per call); `has_more`/`next_page` are derived from the site's own page-full signal, so the last page reports has_more=false. An unknown nation or attribute name yields a 422; numeric filter values the site rejects (e.g. an attribute threshold outside 1-20) also yield a 422. Zero matches is a valid empty `players` list.
| Param | Type | Description |
|---|---|---|
| name | string | Player name fragment; the site matches it as a substring (e.g. one shape: a surname). |
| page | integer | 1-based result page; each page holds up to 50 rows. |
| ca_max | integer | Maximum current ability. |
| ca_min | integer | Minimum current ability (site scale, roughly 1-200). |
| nation | string | Nationality name exactly as the site lists it (case-insensitive), e.g. one shape: Japan. Unknown names return a 422. |
| pa_max | integer | Maximum potential ability. |
| pa_min | integer | Minimum potential ability. |
| age_max | integer | Maximum age in years. |
| age_min | integer | Minimum age in years. |
| sort_by | string | Column to sort by. Omitted = the site's default ordering (current ability descending). |
| version | string | Football Manager database edition to search. |
| sort_dir | string | Sort direction; only applied when sort_by is given. |
| attribute | string | Name of one player attribute to threshold on, as the site spells it (e.g. one shape: Pace). Unknown names return a 422. Combine with attribute_min and/or attribute_max. |
| value_max | integer | Maximum transfer value in whole euros. |
| value_min | integer | Minimum transfer value in whole euros. |
| attribute_max | integer | Maximum value for `attribute` on the in-game 1-20 scale. Requires `attribute`. |
| attribute_min | integer | Minimum value for `attribute` on the in-game 1-20 scale (the profile pages display the same attributes multiplied by 10). Requires `attribute`. |
| positions_all | string | Comma-separated position codes (same code list as positions_any); a player must play ALL of them. Do not pass an array. |
| positions_any | string | Comma-separated position codes; a player matches if he plays ANY of them. Codes: gk, dc, dr, dl, wbr, wbl, dm, mc, mr, ml, amc, amr, aml, st (e.g. gk,dc). Do not pass an array. |
{
"type": "object",
"fields": {
"page": "integer page number served",
"count": "integer number of rows on this page",
"players": "array of player summary rows: player_id (string, feeds get_player), name, positions (array of codes), club, club_id, age, nation, wage_short/wage_detail (yearly wage, abbreviated and full euro text), contract_expires/contract_expires_detail, value_short/value_detail (or 'Not sale'), current_ability, potential_ability, profile_url",
"version": "game edition label the rows come from, e.g. FM 26",
"has_more": "boolean, true when a further page exists",
"next_page": "integer page to request next, or null on the last page",
"page_size": "integer rows per page (50)"
},
"sample": {
"data": {
"page": 1,
"count": 50,
"players": [
{
"age": 23,
"club": "Arsenal",
"name": "Bukayo Saka",
"nation": "England",
"club_id": "602",
"player_id": "28122642",
"positions": [
"AMR",
"AML"
],
"wage_short": "15M",
"profile_url": "https://fmplayer.net/fm-26/bukayo-saka-28122642",
"value_short": "170M",
"wage_detail": "€ 15.080.000 p/y",
"value_detail": "€ 169.545.610",
"current_ability": 181,
"contract_expires": "06-2027",
"potential_ability": 188,
"contract_expires_detail": "30 June 2027"
}
],
"version": "FM 26",
"has_more": true,
"next_page": 2,
"page_size": 50
},
"status": "success"
}
}About the fmplayer API
Searching Players
search_players accepts up to eight optional filter parameters that combine with AND logic. You can narrow results by name (substring match), nation (exact nationality label), age_max, and ability range filters (ca_min, ca_max, pa_min, pa_max). Each response includes players — an array of summary rows carrying player_id, name, positions, club, club_id, age, nation, wage, contract expiry, and current/potential ability values — plus pagination fields has_more, next_page, and page_size (fixed at 50). The version field in the response confirms which FM database edition was queried.
Player Profiles
get_player takes a player_id (sourced from search_players) and an optional version string to target a specific FM edition. The response covers identity fields (name, age, nation, club, club_id, positions), a contract object with labelled keys for wage, expiry date, and release clause when present, a badges array for personality and hidden-attribute labels, best_roles with per-role scores, every attribute broken out by group, and a similar_players list for scouting adjacent targets. The player_id returned here matches the format used in search_players, so the two endpoints chain cleanly.
Database Coverage
Both endpoints accept a version parameter to target a specific Football Manager edition from FM 18 through FM 26. This lets you compare how a player's current ability or contract terms differ across multiple database snapshots — useful for tracking career progression or verifying historical squad builds. Omitting version defaults to the current edition.
The fmplayer API is a managed, monitored endpoint for fmplayer.net — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when fmplayer.net 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 fmplayer.net 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?+
- Filter players by
pa_minandage_maxto build a shortlist of high-ceiling young prospects for a FM save - Query
ca_minandnationtogether to find the strongest players from a specific country for an international challenge - Retrieve
contractdetails fromget_playerto identify players nearing expiry who could be signed on a free transfer - Use
best_rolesscores fromget_playerto match players to a specific tactical role automatically - Compare
similar_playersreturned byget_playerto discover budget alternatives to an expensive transfer target - Page through
search_playersresults with thenext_pagefield to export a full edition's player database for analysis - Diff
cavalues across FM editions by callingget_playerwith differentversionvalues for the sameplayer_id
| 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 fmplayer.net provide an official developer API?+
How does pagination work in search_players?+
search_players returns up to 50 rows per page. The response includes has_more (boolean) and next_page (integer or null). Pass next_page's value as the page parameter on your next request to walk forward through results. There is no cursor; pages are 1-based integers.Does get_player return staff profiles such as managers and coaches?+
What does the nation filter in search_players accept?+
nation parameter expects the nationality name exactly as fmplayer.net lists it (case-insensitive), for example 'Japan' or 'Brazil'. Unrecognised values return zero results rather than an error, so it is worth verifying the exact label against a known player's nation field before filtering at scale.Does the API expose club squad listings or club-level data beyond what appears on player profiles?+
club and club_id fields on individual player records but has no dedicated club-roster or club-search endpoint. You can fork this API on Parse and revise it to add a club-focused endpoint that aggregates squad data by club_id.