Gaffer IQ · Section 03 of 22
The dataDesign philosophy
Two sources, one serverless function, and everything else running in the browser – plus a frank list of what the FPL API does not give you.
- Read time
- ~1 min
- Revised
- 3 Sep 2026
- Status
- Published
Where the logic runs
Every piece of analytical logic runs in the browser. The one serverless function on Vercel exists solely because the FPL API sends no CORS headers – it fetches from an allowlist and forwards, and does nothing else.
The FPL API, and what it leaves out
The FPL API (fantasy.premierleague.com/api) supplies the spine: squads, prices, positions, fixtures, per-player histories, live gameweek scoring. What it conspicuously does not supply is most of what makes a matchup readable:
- No standings endpoint, so the league table is accumulated from the fixtures feed instead.
- No access to any season but the current one.
- No minute timings, and no goal-to-assist pairing.
- No teamsheet of any kind.
Understat, which fills the gaps
Understat, although not an API (understat.com), fills those gaps: expected goals for the shot-quality FPL never exposes, six seasons of cross-season fixture lists so head-to-head records can reach past August, chronological match timelines with minutes, and rosters carrying position codes and substitution linkage so a real starting XI and formation can be derived.
Terms used here
- FPL API
- Supplies the spine – squads, prices, positions, fixtures, per-player histories and live gameweek scoring. It has no standings endpoint and no access to any season but the current one.
- Understat
- Not an API, but it fills the gaps the FPL feed leaves: expected goals, six seasons of fixture lists, chronological match timelines, and rosters with position codes and substitution linkage.
- One Vercel function
- The single serverless function exists only because the FPL API sends no CORS headers. It fetches from an allowlist and forwards. It holds no state, no keys, and no logic of its own.
- CORS
- The browser security rule that blocks a webpage from calling a different site’s API directly. It’s why the proxy exists.
- Proxy
- The serverless function’s job: forward requests, don’t process them.
- Allowlist
- The proxy only forwards requests matching pre-approved URL patterns, rejecting everything else.
- Client-side rendering
- The browser builds and updates the page with JavaScript, rather than receiving a finished page from a server.Explained in The interface