fc-clubs-api
An unofficial Python client for the EA Sports FC 27 Pro Clubs API, the same endpoints proclubs.ea.com calls from the browser. Find clubs and get their stats, members, match history and per-player match ratings as EA's raw JSON, clean Python records or pandas DataFrames.
from fc_clubs_api import FC27API
api = FC27API()
club_id = api.find_club_id("Your Club Name")
api.get_club_matches(club_id) # last 10 league matches
Documentation · Getting started · API reference · EA endpoints · Changelog
Features
- Three output formats:
rawJSON, typedrecords, or a pandasdataframe, set per client or per call. - No required dependencies. The core is standard library only; pandas is an extra.
- Every known club endpoint: search (all-time and current season), details, overall stats, member and career stats, matches, per-player match stats.
- Matches from your side: opponent, score,
result(win/draw/loss) anddnf, correct for league matches and friendlies. - 80+ decoded match events EA doesn't name: pass direction and length, possession won by pitch third, positioning, in-game feedback.
- Crest, division and reputation images, with the crest fallback rule.
- Timezone-aware timestamps, consistent camelCase columns, fully typed,
a
fc-clubsCLI.
Install
Python 3.9 or newer.
pip install "fc-clubs-api[pandas]" # with DataFrame output (analysis, notebooks)
pip install fc-clubs-api # no dependencies (apps, bots, APIs)
No API key needed; the data is public.
Output formats
The same data, three ways. dataframe is the default.
| Format | Returns | For |
|---|---|---|
"raw" |
EA's JSON exactly as received | storage, proxies, fields not mapped here |
"records" |
list[dict]: flat, typed, renamed, timestamps as datetime |
backends, bots, JSON APIs |
"dataframe" |
pandas.DataFrame with the same columns as records |
analysis, CSV/Excel |
from fc_clubs_api import FC27API
api = FC27API(output="records", timezone="Europe/London") # client default
api.get_member_stats(1001) # list of dicts
api.get_member_stats(1001, output="raw") # {"members": [...], "positionCount": {...}}
api.get_member_stats(1001, output="dataframe") # DataFrame
Methods
| Method | One row per |
|---|---|
find_club_id(name) |
returns the club id (int) |
search_club_by_name(name, scope="all_time") |
matching club; scope="current_season" for this season |
get_club_details(club_id) |
club: name, ids, stadium, crest |
get_club_overall_stats(club_id) |
club: record, goals, streaks, skill rating |
get_member_stats(club_id) |
member: this season's games, goals, assists, rating, pass/tackle rates |
get_member_career_stats(club_id) |
member: career totals at the club |
get_club_matches(club_id, match_type, count) |
match: opponent, score, result, dnf |
get_match_players(club_id, match_type, count) |
player per match: rating, goals, passes, tackles, ... |
get_playoff_achievements(club_id) |
achievement (EA has only returned [] so far) |
get_json(endpoint, params) |
any endpoint, raw |
- Every data method takes
output=. Most takeall_columns=Truefor every field EA sends, with EA's names. match_type:"leagueMatch"(default),"friendlyMatch","playoffMatch", orMatchType.LEAGUEetc.countis capped at 10 by EA, with no paging.get_match_players(..., both_teams=True, include_events=True)adds the opponents and the decoded event stats.
Examples
from fc_clubs_api import FC27API
api = FC27API(timezone="Europe/London")
club_id = api.find_club_id("Your Club Name")
# Top 5 scorers this season
members = api.get_member_stats(club_id)
members.sort_values("goals", ascending=False).head(5)[["name", "goals", "assists"]]
# Average match rating per player, best first
players = api.get_match_players(club_id)
players.groupby("name")["rating"].mean().sort_values(ascending=False)
# Where does each player win the ball back? (decoded match events)
events = api.get_match_players(club_id, include_events=True)
events.groupby("name")[["possessionWonDefensiveThird", "possessionWonMiddleThird",
"possessionWonAttackingThird"]].sum()
More in the recipes and
examples/.
From the terminal:
fc-clubs "Your Club Name" # recent matches and squad, or --json
Errors
All network and response problems raise FC27APIError (subclasses
FC27HTTPError with .status_code, FC27ConnectionError, FC27ResponseError).
find_club_id raises ClubNotFoundError or AmbiguousClubError (with
.candidates), both ValueErrors. Details →
Good to know
- EA blocks non-browser requests. Every request sends browser-like headers
(
fc_clubs_api.HEADERS); without them EA answers 403 or not at all. - No caching or rate limiting. Every call goes straight to EA. Pause between
requests (
time.sleep(1)) when looping over many clubs. - Unofficial. Not affiliated with or endorsed by EA. The endpoints are undocumented and can change without notice.
Contributing
Bug reports are especially welcome when EA changes something and the client breaks. Please open an issue before writing code. See CONTRIBUTING.md.
Acknowledgements
The current-season endpoint, crest rules and match event mappings build on the community EA FC Pro Clubs API research project.
License
MIT, see LICENSE.md.
Metadata
Release files for fc-clubs-api 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fc_clubs_api-0.2.0.tar.gz | 30.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fc_clubs_api-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.1 kB
Release files / fc_clubs_api-0.2.0.tar.gz
| Download URL | fc_clubs_api-0.2.0.tar.gz |
|---|---|
| Size | 30.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c435e8c9b64bea537005e508225dae30b7e84c09463f8d3f0d0bb76241f71422
|
|
BLAKE2b-256 checksum How to use checksums |
477aa130e0f29ae0732b1af9033a0610ce266bedce4fed1d4480b6d1fc384b4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / fc_clubs_api-0.2.0-py3-none-any.whl
| Download URL | fc_clubs_api-0.2.0-py3-none-any.whl |
|---|---|
| Size | 25.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
568510b09016d3419593b42a7c4a15ab4fc972f20518f8be0b1d9d53abaedfed
|
|
BLAKE2b-256 checksum How to use checksums |
49816d55c5404801b52f3902ae41a1e94828297ca0ab73d58ef4ede984022748
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log