FPL API Endpoints: Complete Reference for 2026/27
Every public Fantasy Premier League API endpoint, checked live in 2026/27: bootstrap-static, fixtures, live, entry, picks, leagues, with key fields and errors.
Published · Updated · By Omar Eldeeb
The Fantasy Premier League API is a free, keyless JSON API at https://fantasy.premierleague.com/api/. Its main endpoints are bootstrap-static/ (all players, teams and gameweeks), fixtures/, element-summary/{player_id}/, event/{gw}/live/, entry/{manager_id}/ with /history/, /event/{gw}/picks/ and /transfers/, and leagues-classic/{league_id}/standings/. It has no official documentation and no CORS header.
The Premier League doesn't document this API, so this reference comes from live responses. I called every endpoint below on 2026-10-14, during the 2026/27 season, between gameweek 6 (finished) and gameweek 7 (deadline 2026-10-17 10:00 UTC). Each returned HTTP 200 unless marked otherwise.
The endpoints at a glance
| Endpoint | Returns | Status on 2026-10-14 |
|---|---|---|
bootstrap-static/ |
Every player, team and gameweek, plus game rules | 200, 1.7 MB |
fixtures/ |
All 380 fixtures of the season | 200 |
fixtures/?event={gw} |
One gameweek's fixtures | 200 (10 for GW6) |
fixtures/?future=1 |
Only fixtures not yet played | 200 (320) |
element-summary/{player_id}/ |
One player's remaining fixtures, this season's matches, past seasons | 200; unknown ID: 404 |
event/{gw}/live/ |
Every player's stats and points for a gameweek | 200; a future gameweek returns {"elements":[]} |
event-status/ |
Whether bonus points are added and leagues updated | 200 |
dream-team/{gw}/ |
The best XI of a gameweek | 200 |
entry/{manager_id}/ |
A manager's profile, rank and leagues | 200; unknown ID: 404 |
entry/{manager_id}/history/ |
Points and rank per gameweek, past seasons, chips used | 200 |
entry/{manager_id}/event/{gw}/picks/ |
The 15 players picked in a gameweek, captain, chip, auto-subs | 200; a future gameweek: 404 |
entry/{manager_id}/transfers/ |
Every transfer this season | 200 |
leagues-classic/{league_id}/standings/ |
A classic league table, 50 per page | 200 |
team/set-piece-notes/ |
Set-piece notes per team | 200 |
regions/ |
Countries and regions for manager profiles | 200 (255) |
stats/most-valuable-teams/ |
The 10 highest team values | 200 |
my-team/{manager_id}/ |
Your own team before the deadline | 403 without login |
entry/{manager_id}/transfers-latest/ |
Your latest transfers | 403 without login |
The paths end with a slash. Two paths that older tutorials mention, set-piece-notes/ and bootstrap-dynamic/, returned 404 HTML pages. The base URL itself (/api/) also returns 404.
Check them yourself
import time
import requests
API = "https://fantasy.premierleague.com/api/"
s = requests.Session()
s.headers["User-Agent"] = "fpl-endpoint-check/1.0 (personal script)"
def get(path):
r = s.get(API + path, timeout=30)
return r.status_code, (r.json() if r.headers.get("content-type", "").startswith("application/json") else None)
_, boot = get("bootstrap-static/")
gw = next(e["id"] for e in boot["events"] if e["is_current"]) # latest started gameweek
player = max(boot["elements"], key=lambda p: p["total_points"])["id"] # any player id works
_, overall = get("leagues-classic/314/standings/") # 314 = the Overall league
manager = overall["standings"]["results"][0]["entry"] # any manager id works
paths = [
"bootstrap-static/",
"fixtures/",
f"fixtures/?event={gw}",
f"element-summary/{player}/",
f"event/{gw}/live/",
"event-status/",
f"dream-team/{gw}/",
f"entry/{manager}/",
f"entry/{manager}/history/",
f"entry/{manager}/event/{gw}/picks/",
f"entry/{manager}/transfers/",
"leagues-classic/314/standings/?page_standings=2",
"team/set-piece-notes/",
"regions/",
"stats/most-valuable-teams/",
"my-team/1/",
]
for p in paths:
status, body = get(p)
shape = list(body)[:4] if isinstance(body, dict) else f"list of {len(body)}" if isinstance(body, list) else "-"
print(f"{status} {p:<45} {shape}")
time.sleep(0.5)Output on 2026-10-14:
200 bootstrap-static/ ['chips', 'events', 'game_settings', 'game_config']
200 fixtures/ list of 380
200 fixtures/?event=6 list of 10
200 element-summary/115/ ['fixtures', 'history', 'history_past']
200 event/6/live/ ['elements']
200 event-status/ ['status', 'leagues']
200 dream-team/6/ ['top_player', 'team']
200 entry/895045/ ['id', 'joined_time', 'started_event', 'favourite_team']
200 entry/895045/history/ ['current', 'past', 'chips']
200 entry/895045/event/6/picks/ ['active_chip', 'automatic_subs', 'entry_history', 'picks']
200 entry/895045/transfers/ list of 36
200 leagues-classic/314/standings/?page_standings=2 ['league', 'standings', 'last_updated_data', 'new_entries']
200 team/set-piece-notes/ ['last_updated', 'teams']
200 regions/ list of 255
200 stats/most-valuable-teams/ list of 10
403 my-team/1/ ['detail']Key fields, endpoint by endpoint
bootstrap-static/
Top-level keys: events, game_settings, game_config, phases, teams, total_players, element_stats, element_types, elements, chips. On 2026-10-14 it held 667 players, 20 teams, 38 gameweeks and total_players: 11085989.
| Array | Key fields |
|---|---|
elements (players, 109 fields each) |
id, web_name, team, element_type (1 GKP, 2 DEF, 3 MID, 4 FWD), now_cost (tenths of £m), total_points, event_points, form, selected_by_percent, status, chance_of_playing_next_round, news, minutes, goals_scored, assists, expected_goals, expected_assists, defensive_contribution, ep_next, transfers_in_event, price_change_percent |
teams |
id, name, short_name, strength_overall_home, strength_overall_away, played, win, draw, loss, points, position |
events (gameweeks) |
id, name, deadline_time, is_previous, is_current, is_next, finished, data_checked, average_entry_score, highest_score, most_captained, top_element |
element_types |
squad_select (2/5/5/3), squad_min_play, squad_max_play |
game_settings |
squad_squadsize (15), squad_team_limit (3 per club), squad_total_spend (1000 = £100.0m), transfers_cap, max_extra_free_transfers |
Several numbers arrive as strings: form, selected_by_percent, expected_goals, price_change_percent. Cast them before comparing. The response carried cache-control: max-age=300, so it changes at most every five minutes.
fixtures/
Each fixture: id, event (gameweek), kickoff_time, team_h, team_a, team_h_score, team_a_score, team_h_difficulty, team_a_difficulty, started, finished, minutes, stats. For a finished match, stats lists goals_scored, assists, own_goals, penalties_saved, penalties_missed, yellow_cards, red_cards, saves, bonus, bps and defensive_contribution, each split into h and a with {value, element} pairs. Difficulty is covered in FPL fixture difficulty from the API.
element-summary/{player_id}/
fixtures (remaining matches, with difficulty and is_home from that player's side), history (one row per match this season: round, opponent_team, minutes, total_points, bps, expected_goals, value, selected, transfers_balance, and more) and history_past (one row per earlier season: season_name, start_cost, end_cost, total_points, minutes).
event/{gw}/live/
elements is a list of every player with id, stats (the same counters as above plus total_points, in_dreamteam and played) and explain, which breaks the points down per fixture: {"identifier": "goals_scored", "points": 10, "value": 2}. Pair it with a manager's picks to compute their score; see FPL live gameweek points from the API.
entry/{manager_id}/ and its sub-paths
| Endpoint | Key fields |
|---|---|
entry/{id}/ |
id, name (team name), started_event, summary_overall_points, summary_overall_rank, summary_event_points, current_event, last_deadline_value, last_deadline_bank, leagues (classic, h2h, cup) |
entry/{id}/history/ |
current (per gameweek: points, total_points, overall_rank, bank, value, event_transfers, event_transfers_cost, points_on_bench), past (season_name, total_points, rank), chips (name, event, time) |
entry/{id}/event/{gw}/picks/ |
picks (15 rows: element, position, multiplier, is_captain, is_vice_captain), active_chip, automatic_subs, entry_history |
entry/{id}/transfers/ |
element_in, element_in_cost, element_out, element_out_cost, event, time |
How to find a manager ID, and a full history script: Find your FPL manager ID and pull your team history.
leagues-classic/{league_id}/standings/
league (id, name, ...), standings (page, has_next, results: entry, entry_name, player_name, rank, last_rank, total, event_total), new_entries and last_updated_data. Fifty rows per page; add ?page_standings=2 and keep going while has_next is true. League 314 is the Overall league.
Small endpoints
event-status/returned{"status": [{"bonus_added": true, "date": "2026-10-10", "event": 6, "points": "r"}, ...], "leagues": "Updated"}. Checkbonus_addedandleaguesbefore you treat a gameweek's numbers as final.dream-team/{gw}/returnstop_player(id,points) andteam(11 rows ofelement,points,position).
Errors
| Situation | Status | Body |
|---|---|---|
| Unknown manager | 404 | {"detail":"No Entry matches the given query."} |
| Unknown player | 404 | {"detail":"No Element matches the given query."} |
| Picks for a gameweek that hasn't started | 404 | {"detail":"Not found."} |
| Your own team without login | 403 | {"detail":"Authentication credentials were not provided."} |
me/ without login |
200 | {"player":null,"watched":[]} |
Rules of the road
- No browser calls. The responses I checked (
bootstrap-static/,fixtures/,entry/{id}/) carried noAccess-Control-Allow-Originheader, so a web page can'tfetch()them. Use a server, a script or a scheduled job. - No published rate limit. FPL documents none. Cache
bootstrap-static/(it's 1.7 MB and only changes every five minutes), pause between requests, and back off on errors. My scripts send a descriptiveUser-Agent; the API also answered without one. - The API only shows now. It doesn't keep yesterday's prices, ownership or price-change progress. Save snapshots if you need history; for past seasons, the community vaastav/Fantasy-Premier-League archive on GitHub is the usual source.
- Prices are in tenths.
now_cost: 61is £6.1m, andsquad_total_spend: 1000is £100.0m.
Related guides for this API
- Find your FPL manager ID and pull your team history.
- FPL live gameweek points from the API.
- FPL fixture difficulty from the API.
- FPL API price change data in Python, for the official price-change fields.
Do it without code
The free FPL query builder lets you pick a mode (gameweek picks, mini-league intel, manager dashboard, price-change predictor and others), a gameweek and manager IDs, and gives you a ready-to-run input with a fixed example of the output. It's a query builder, not a live tool: because of the missing CORS header, it can't call the FPL API from your browser.
At scale
The FPL Intelligence actor on Apify calls these endpoints server-side and turns them into ready answers: captain, transfer and differential picks, a wildcard optimizer, mini-league intel, a manager dashboard, live gameweek tracking, a price-change predictor, and past seasons from the vaastav archive. It exports JSON, CSV or Excel and runs on a schedule. It's free to start, then pay-as-you-go.
Disclosure: I build the datatooly query builder and the Apify actor. Every endpoint above works without either.
Sources: live responses from fantasy.premierleague.com/api/ on 2026-10-14. FPL publishes no API documentation.
Quick answers
Is there an official Fantasy Premier League API?
There is a public, unauthenticated JSON API at https://fantasy.premierleague.com/api/ that the FPL website itself uses, but the Premier League publishes no documentation for it. Everything known about it comes from reading its live responses. The base URL with no path returns 404, so start from bootstrap-static/.
Is the FPL API free?
Yes. The public endpoints need no key, no account and no payment. Only endpoints about your own logged-in team, such as my-team/{id}/, need authentication; without it they return 403 with Authentication credentials were not provided.
Can I call the FPL API from JavaScript in the browser?
Not directly. The responses carry no Access-Control-Allow-Origin header, so the browser blocks a cross-origin fetch(). Call the API from a server, a script, a serverless function or a scheduled job, and serve the result to your page.
How do I build a fantasy platform using FPL data?
Load bootstrap-static/ once (players, teams, gameweeks) and cache it, read fixtures/ for the schedule and difficulty, event/{gw}/live/ for points, and entry/{id}/... for managers' teams. Call everything server-side because there is no CORS header, store snapshots yourself (the API only shows the current state), and respect the 300-second cache on bootstrap-static/.
What is league 314 in the FPL API?
League 314 is the Overall league, the global ranking of every FPL manager. leagues-classic/314/standings/ returned it on 2026-10-14 with 50 managers per page; add ?page_standings=2 for the next page.