Methodology

Match data — every source, every refresh cadence

Match Centre v3 sources every number on the page from a named public dataset. This page documents which one and how often we refresh it. We never fabricate, we never guess; when a source fails, the surface degrades to an honest empty state rather than show invented data.

Match Centre v2 inferred lineups from FPL minutes > 0, which during a live-GW transition returned yesterday's XI. That is the class of bug v3 explicitly fixes. The four sources below replace it.

Source 1

Confirmed lineups

Who starts, who is on the bench, what formation, who has the armband.

Source
premierleague.com
Refresh
every 5 min during live, 30 min pre-match, 24h post-match
Pre-match
Lineup typically drops ~60 minutes before kickoff. Until then the surface renders an honest "lineup not yet published" state — no fabricated XI.
Live
We refresh every 5 minutes during the match in case the page mutates (rare, but happens for tactical formation re-labels).
Post-match
Once the match is finished the lineup is frozen and cached for 24 hours.
If it fails
If premierleague.com is unreachable or the page structure has drifted, the surface degrades to the FPL minutes-derived participant list for FINISHED fixtures only. For pre-match and live fixtures we show "Lineup confirms about 60 minutes before kick-off" rather than guess.

Caveats

  • Premier League's __NEXT_DATA__ payload shape has changed twice in the past 12 months. We accept multiple shapes; if a third revision lands we'll patch the parser.
  • Captain and penalty-taker flags depend on what PL publishes; not every match exposes a pen-taker in the payload.

Source 2

Live commentary + team stats

Minute-by-minute text, possession %, shots, shots on target, corners, fouls, offsides.

Source
bbc.co.uk · Sport · Football live text
Refresh
every 60 seconds during live, 30 min pre-match, 24h post-match
Pre-match
The page exists pre-match (with build-up posts), so commentary may include "Team news in 5 minutes" before kick-off. We surface that as commentary, not as match action.
Live
BBC re-fetches the same JSON envelope they ship inline on the live page. Our 60s cadence matches theirs; we never poll faster than the source updates.
Post-match
Final stats and the full text feed are cached for 24 hours.
If it fails
If BBC has no live page yet, or if their structure has changed, the surface degrades to FPL-cumulative cards + bonus (which are real) and leaves possession + shots + corners blank with an honest "BBC text not yet available" caption.

Caveats

  • BBC stats lag the wire by 30-60 seconds, which is faster than xG providers but slower than the broadcaster overlay.
  • Yellow / red counts cross-checked against FPL bootstrap; if they disagree, BBC wins (we surface their numbers as the most up-to-date).

Source 3

Shot map + xG per shot

Every shot location, the shooter, the expected-goals value, and the outcome.

Source
understat.com
Refresh
every 60 seconds during live, 6 hours pre-match, 24h post-match
Pre-match
Understat does not publish shots until the match begins. The shot map renders an empty pitch with "Shot map will appear once Understat publishes, usually within 5 minutes of kick-off".
Live
Understat updates the shotsData payload every minute or two. We refresh every 60 seconds — matching their fastest cadence.
Post-match
Final shot list is frozen and cached for 24 hours.
If it fails
Understat occasionally rate-limits scrapers; on failure the shot map shows an honest "Understat unreachable" caption and the rest of the page renders as normal.

Caveats

  • Understat coordinates are 0..1 normalised across the team's attacking half. We map to StatsBomb 120×80 so the dots align with the rest of our pitch visualisations.
  • Understat's xG model is publicly documented and broadly agreed to be solid; it is NOT identical to Opta xG, which differs by 5-10% on individual shots.
  • Own goals are excluded from Understat shot data and so do not appear on the map; they DO appear in the BBC commentary feed.

Source 4

FPL cumulative stats (fallback for cards + bonus)

Yellow / red cards, bonus points, goals + assists by element id, BPS, minutes.

Source
fantasy.premierleague.com · official API
Refresh
every 30 seconds during live, 5 minutes post-match
Pre-match
No live stats yet.
Live
FPL is the authoritative source for cards and bonus race because the FPL game must score them in real time. We trust this number over any scraper.
Post-match
Bonus points are awarded ~30 minutes after final whistle. We respect the official FPL bonus race timeline.
If it fails
FPL is the canonical source — it never empty-states. If FPL is down we fall back to BBC card counts.

Caveats

  • FPL leaves `is_current` pointing at a finished GW for hours after final whistle. Match Centre always reads the live event via `pickLiveEvent()`, not `is_current`, to avoid stale-GW headlines.

Contract

Our honesty bar

  1. Every data block on a match page exposes its source and freshness — hover the attribution tag to see "Lineup from premierleague.com · 14s ago".
  2. If a source fails, the surface renders a designed empty state, never a placeholder dressed up as real data.
  3. Scrapers never throw inside the snapshot pipeline. They return empty results and the page renders gracefully. Sentry breadcrumbs capture the failure for triage.
  4. This page is the public record. If we add a source, it lands here before it lands in the UI.