Endpoint reference¶
This page documents EA's raw responses, which is what you get with
output="raw" or api.get_json(...). For the cleaned formats see
Output formats.
All endpoints are GET https://proclubs.ea.com/api/fc/<endpoint> and need
platform=common-gen5 plus the browser-style headers in
fc_clubs_api.HEADERS. Without them EA's edge (Akamai) answers 403 or never answers
(the request hangs until it times out). Plain curl is blocked even with the
headers, while Python (urllib or requests) gets through.
Observed on 2026-09-19 against a real club, and re-checked on 2026-10-02
against another (every endpoint and field below still matched). The structure is real, but all names,
ids, dates, kit values and club totals below are placeholders ("Example FC" = 1001,
"Opponent A" = 2001, "Player1", ...). The same anonymized responses are in
tests/fixtures/.
Community findings from the EA FC Pro Clubs API research
project are credited where they are used.
General quirks:
- Almost every value is a string, including numbers (
"25","7.4"). Therecordsanddataframeformats convert numeric fields for you. - Some parameters are singular (
clubId) and some plural (clubIds). Only single ids have been tested. - Empty results are
[]. JSONnullhas also been reported for matches.
| Endpoint | Club parameter | Python method |
|---|---|---|
allTimeLeaderboard/search |
clubName |
search_club_by_name, find_club_id |
currentSeasonLeaderboard/search |
clubName |
search_club_by_name(scope="current_season") |
clubs/info |
clubIds |
get_club_details |
clubs/overallStats |
clubIds |
get_club_overall_stats |
members/stats |
clubId |
get_member_stats |
members/career/stats |
clubId |
get_member_career_stats |
clubs/matches |
clubIds |
get_club_matches, get_match_players |
club/playoffAchievements |
clubId |
get_playoff_achievements |
allTimeLeaderboard/search¶
?platform=common-gen5&clubName=example
Returns a list of clubs whose name contains the text (case-insensitive). Each item
has all-time league totals plus a nested clubInfo, which is the same object
clubs/info returns.
[
{
"clubId": "1001",
"wins": "20", "losses": "3", "ties": "2",
"gamesPlayed": "25", "gamesPlayedPlayoff": "0",
"goals": "60", "goalsAgainst": "25", "cleanSheets": "10",
"points": "62", "reputationtier": "1",
"promotions": "3", "relegations": "0", "bestDivision": "2",
"clubInfo": {
"name": "Example FC", "clubId": 1001, "regionId": 1000000, "teamId": 100,
"customKit": { "stadName": "Example Stadium", "kitId": "0", "...": "..." }
},
"platform": "common-gen5",
"clubName": "Example FC",
"currentDivision": "2"
}
]
reputationtieris0–3; EA serves an icon per tier (see Images and crests).currentDivision/bestDivisionare1(top) to6.
maxResultCount (optional) is not an exact limit. Checked on 2026-10-02 with
two search terms on both leaderboards, asking for N returned:
maxResultCount |
1 | 2 | 3 | 5 | 10 | 50 | omitted |
|---|---|---|---|---|---|---|---|
| clubs returned | 0 | 1 | 1 | 2 | 3–4 | 11–18 | same as 10 |
EA seems to fetch N leaderboard rows and then filter them, so treat it as "search
deeper" rather than "return at most N". search_club_by_name(max_result_count=...)
passes it through unchanged.
currentSeasonLeaderboard/search¶
?platform=common-gen5&clubName=example
Same parameters and exactly the same shape as allTimeLeaderboard/search (checked
field by field on 2026-10-02), but the totals cover the running season only. Early in
FC 27 the two return identical numbers, because only one season has been played.
Fixture: search_current_season.json.
clubs/info¶
?platform=common-gen5&clubIds=1001
Returns a dict keyed by club id (string).
{
"1001": {
"name": "Example FC",
"clubId": 1001,
"regionId": 1000000,
"teamId": 100,
"customKit": {
"stadName": "Example Stadium",
"kitId": "0", "seasonalTeamId": "0", "seasonalKitId": "0",
"selectedKitType": "0", "customKitId": "0",
"kitColor1": "16777215", "kitColor2": "0", "kitColor3": "0", "kitColor4": "0",
"customAwayKitId": "0",
"kitAColor1": "16777215", "kitAColor2": "0", "kitAColor3": "0", "kitAColor4": "0",
"customThirdKitId": "0",
"kitThrdColor1": "16777215", "kitThrdColor2": "0", "kitThrdColor3": "0", "kitThrdColor4": "0",
"dCustomKit": "0", "customKeeperKitId": "0",
"crestColor": "0", "crestAssetId": "0"
}
}
}
- Kit and crest colours are decimal RGB:
16777215=0xFFFFFF(white).fc_clubs_api.assets.kit_color_hex("16777215")returns"#ffffff". teamIdis the real-world badge id,crestAssetIdthe custom crest id. Which one the club displays: see Images and crests. In every club checked,selectedKitType"1"went with a custom crest and"0"with a real badge.
clubs/overallStats¶
?platform=common-gen5&clubIds=1001
Returns a list with one item.
[
{
"clubId": "1001",
"bestDivision": null,
"bestFinishGroup": null,
"finishesInDivision1Group1": "0", "...": "... up to finishesInDivision6Group1",
"gamesPlayed": "25", "gamesPlayedPlayoff": "0",
"goals": "60", "goalsAgainst": "25",
"promotions": "3", "relegations": "0",
"wins": "20", "losses": "3", "ties": "2",
"lastMatch0": "1", "...": "... up to lastMatch9",
"lastOpponent0": "2001", "...": "... up to lastOpponent9",
"wstreak": "3",
"unbeatenstreak": "8",
"skillRating": "1500",
"reputationtier": "1",
"leagueAppearances": "25"
}
]
bestDivision/bestFinishGroupcan benull.lastOpponent0–9are the club ids of the last 10 opponents, newest first.lastMatch0–9is the result against that opponent:1= win,2= loss,3= draw (checked againstclubs/matches). Older entries can be-1; what that means is unconfirmed.- These lists don't always line up with
clubs/matches: in one check a league match was missing from them. Useclubs/matchesfor match history.
members/stats¶
?platform=common-gen5&clubId=1001
Current-season stats. Returns {members: [...], positionCount: {...}}.
{
"members": [
{
"name": "Player1",
"gamesPlayed": "18", "winRate": "94",
"goals": "2", "assists": "0",
"cleanSheetsDef": "7", "cleanSheetsGK": "0",
"shotSuccessRate": "50", "passesMade": "138", "passSuccessRate": "84",
"ratingAve": "7.4",
"tacklesMade": "24", "tackleSuccessRate": "26",
"proName": "Pro 1", "proPos": "5", "proStyle": "0", "proHeight": "187",
"proNationality": "165", "proOverall": "78", "proOverallStr": "78",
"manOfTheMatch": "1", "redCards": "0",
"prevGoals": "0", "prevGoals1": "0", "...": "... up to prevGoals10",
"favoritePosition": "defender"
}
],
"positionCount": { "midfielder": 4, "goalkeeper": 1, "forward": 6, "defender": 3 }
}
nameis the platform gamertag.proNameis the in-game player name and can be"".proPos,proStyleandproNationalityare numeric EA ids. No lookup table has been published.- Members who haven't played this season (
gamesPlayed"0") are still listed, butfavoritePosition,proName,proPos,proStyle,proHeight,proNationalityandproOverallStrare""for them. positionCountcountsfavoritePosition, leaving out those""members. The client drops it; count thepositioncolumn ofget_member_statsinstead, e.g.Counter(m["position"] for m in members)(it counts""too).
members/career/stats¶
?platform=common-gen5&clubId=1001
Career totals at this club. The wrapper is the same as members/stats, with fewer fields:
{
"members": [
{
"name": "Player1",
"proPos": "25",
"gamesPlayed": "29", "goals": "5", "assists": "3",
"manOfTheMatch": "1", "ratingAve": "7.3", "prevGoals": "0",
"favoritePosition": "forward"
}
],
"positionCount": { "midfielder": 4, "goalkeeper": 1, "forward": 7, "defender": 2 }
}
As in members/stats, proPos and favoritePosition are "" for members with no games.
clubs/matches¶
?platform=common-gen5&clubIds=1001&matchType=leagueMatch&maxResultCount=10
matchType is leagueMatch, friendlyMatch or playoffMatch. Returns a list of
matches, newest first. playoffMatch returned [].
maxResultCount is capped at 10: asking for more still returns 10. Leaving it
out returns 5. There is no paging parameter, so older matches can't be fetched.
[
{
"matchId": "1000000000001",
"timestamp": 1767297600,
"timeAgo": { "number": 4, "unit": "hours" },
"clubs": {
"1001": {
"date": "1767297600", "gameNumber": "0", "season_id": "0",
"matchType": "1",
"goals": "4", "goalsAgainst": "0", "score": "4",
"wins": "1", "ties": "0", "losses": "0",
"result": "16385", "winnerByDnf": "1",
"TEAM": "100",
"details": { "name": "Example FC", "clubId": 1001, "...": "same as clubs/info" }
},
"2001": { "...": "opponent, same shape" }
},
"players": {
"1001": {
"<playerId>": {
"playername": "...", "pos": "midfielder", "rating": "6.10",
"goals": "0", "assists": "0", "shots": "0",
"passattempts": "0", "passesmade": "0",
"tackleattempts": "0", "tacklesmade": "0",
"saves": "0", "goalsconceded": "0",
"cleansheetsany": "0", "cleansheetsdef": "0", "cleansheetsgk": "0",
"mom": "0", "redcards": "0",
"secondsPlayed": "635", "gameTime": "635",
"wins": "0", "losses": "1", "userResult": "6",
"archetypeid": "11", "vproattr": "NH", "vprohackreason": "0",
"ballDiveSaves": "0", "crossSaves": "0", "goodDirectionSaves": "0",
"parrySaves": "0", "punchSaves": "0", "reflexSaves": "0",
"SCORE": "0", "namespace": "2", "realtimegame": "104", "realtimeidle": "1",
"match_event_aggregate_0": "0:1,1:1,100:1,106:2,...",
"match_event_aggregate_1": "", "match_event_aggregate_2": "", "match_event_aggregate_3": ""
}
},
"2001": { "...": "..." }
},
"aggregate": {
"1001": { "...": "same fields as a player, summed over the club (no playername)" },
"2001": { "...": "..." }
}
}
]
clubs,playersandaggregateare keyed by club id.players[clubId]is keyed by player id.timestampis Unix seconds, UTC.resultcodes seen in league matches:1= win,2= loss,4= draw,16385= win by opponent DNF (quit),10= loss by DNF.winnerByDnfis"1"for the club that was awarded the win.- Friendlies set
wins/ties/losses/resultto"0"for both clubs, so work out the result fromgoalsvsgoalsAgainst.get_club_matchesdoes this. clubs[id].matchTypewas"1"for league matches and"5"for friendlies.TEAMis the crest id the club played with: itsteamId(real badge) or itscustomKit.crestAssetId(custom crest). Therecords/dataframeoutput turns it intocrestUrl/opponentCrestUrl.match_event_aggregate_*areeventId:countlists ("215:21,216:5"). EA does not document the ids; Match events lists what the community has decoded, andget_match_players(include_events=True)adds them as named columns.- Named fields and events don't always agree.
passesmadeincludes offside passes (event_215+event_153), whileevent_215excludes them.
club/playoffAchievements¶
?platform=common-gen5&clubId=1001
Returned []. The shape of a populated item is unknown.
Image endpoints¶
Crests, division badges and reputation icons are plain PNGs on EA's CDN, outside this API. See Images and crests.