5,390,919 rows of NFL history, 1999–2025, versioned by when we learned it. Type a question — a player, a team, a metric.
play_by_play_1999.parquet in nflverse-data was last modified
2025-04-30. A twenty-six-year-old season, rewritten, because
nflverse refit the EPA/WPA models behind 57 of its 372
columns. Every model backtested on it today reads values the feed never
published at the time.
Sortable efficiency tables for fantasy, spreads, totals and prediction markets. Every board is computed from point-in-time play-by-play, so any of them can be asked for as they stood on a past date — target share through week 9 as known in week 9, not as known now.
| board | what it answers |
|---|---|
| Teams | net EPA per play, offense/defense split, PF and PA per game |
| Passing | QB EPA/dropback, CPOE, sack rate, aDOT, explosive rate |
| Rushing | rusher EPA, yards per carry, explosive and first-down rate |
| Receiving | targets, target share, air-yards share, WOPR, half-PPR |
| Games | every game with closing spread and total, and how each resolved |
| Coverage | per-defender results in coverage — targets, yards allowed, passer rating allowed, missed tackles |
| Pressure | QB under pressure — out-of-pocket, throwaway, interception-worthy, QB-fault sacks |
| Tendencies | team identity — personnel, play-action, motion, RPO, time-to-throw, man coverage faced |
| Adjusted | opponent-adjusted efficiency, offense and defense solved jointly |
The last four are built from charting data fbdata may lawfully redistribute — FTN charting (play-action, RPO, screen, motion, blitzers) and NGS participation (personnel groupings, man/zone, coverage shell) — not from any subscription feed. See provenance.
Filter by season, week range and position; sort any column;
export CSV. Same numbers via /v1/leaders/{board} for models.
# what the feed says now
curl 'localhost:8000/v1/query?dataset=pbp&partition=2024&columns=epa,wpa,yards_gained'
# what the feed said on 1 Feb 2026 — before the refit
curl 'localhost:8000/v1/query?dataset=pbp&partition=2024&columns=epa,wpa,yards_gained&as_of=2026-02-01T00:00:00Z'
Same play, two vantage points. In the verification run: EPA
-0.200602 → -0.207623,
with yards_gained independently corrected 3→6 by the league.
One is a model artifact, the other is a fact about football, and fbdata records
them as different revision classes.
Hit agent mode to see the contract instead of the pitch — same facts, selected for a machine reader. Agents get it by default via content negotiation.
/v1/schema/pbp tags every column
observed or derived. An agent decides for itself
what is safe to train on without pinning a date.
Failures explain the fix in prose and link /llms.txt, because the client reading them is a language model.
Every response carries x-fbdata-price-usd, so an agent budgets
before the 402 rather than discovering price by rejection. Metering rides
radius-tollgate.
| route | purpose |
|---|---|
| /llms.txt | agent manifest — the front door for a non-human client |
| /v1/catalog | datasets, partitions, revision counts |
| /v1/schema/{dataset} | columns with revision group |
| /v1/query | history as of any instant |
| /v1/history | every revision of one entity — the audit trail |
| /v1/snapshots | ingestion log; every byte traces to a row here |
Everything served traces to a source we may lawfully redistribute. Connected:
nflverse (CC-BY-4.0), FTN charting via nflverse (CC-BY-SA-4.0), NGS public endpoints.
Interfaces exist but are deliberately not connected for Sportradar, StatsBomb,
FTN premium and PFF — each raises NotConnected with the specific
contract required.
No scraper is written against a paywalled source. A feed that can be switched off by a letter is not a foundation a customer will build a model on.