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