# fbdata.xyz Point-in-time NFL data for autonomous models. Every fact is versioned by when fbdata learned it, so historical queries return what was known at that instant rather than what is known now. ## Why you should care Upstream sports feeds rewrite their own history. nflverse recomputes EPA, WPA, CPOE and xYAC whenever it refits its models, then republishes every season back to 1999. If you backtest against the current file you are training on numbers the feed did not carry on the date you are modelling. That is lookahead bias, and it inflates measured edge. Pin `as_of` to eliminate it. ## Two representations This site serves the same URLs in two modes. Agents get `mode=agent` by content negotiation; append `?mode=agent` to force it. Agent mode is the contract rather than the pitch. Mode is presentation only -- it never affects access or price. https://fbdata.xyz/?mode=agent full serving contract, ~1.5k tokens https://fbdata.xyz/predictions?mode=agent prediction workflow map for agents and people https://fbdata.xyz/sources?mode=agent source readiness and licensing contract https://fbdata.xyz/llms.txt this file, lowest context cost ## Leaderboards (start here) Precomputed efficiency tables. These are what most fantasy, spread/total and prediction-market models want -- you rarely need raw play-by-play. GET https://fbdata.xyz/v1/leaders/teams net EPA, off/def split, PF/PA per game GET https://fbdata.xyz/v1/leaders/passing QB EPA/dropback, CPOE, sack rate, aDOT GET https://fbdata.xyz/v1/leaders/rushing rusher EPA, YPC, explosive rate GET https://fbdata.xyz/v1/leaders/receiving targets, target share, air-yards share, WOPR GET https://fbdata.xyz/v1/leaders/games every game with closing spread/total and result Charting-derived and schedule-adjusted: GET https://fbdata.xyz/v1/leaders/coverage per-defender: targets, completions and yards allowed, passer rating allowed (recomputed from season totals), missed-tackle rate GET https://fbdata.xyz/v1/leaders/pressure QB under pressure: pressure/blitz rate, out-of-pocket, throwaway, interception-worthy, QB-fault sacks, play-action and RPO rate GET https://fbdata.xyz/v1/leaders/tendencies team identity: PROE, early-down pass rate, personnel (11/12/21), play-action, motion, screen, RPO, time-to-throw, man coverage faced GET https://fbdata.xyz/v1/leaders/adjusted opponent-adjusted efficiency, offense and defense solved jointly, plus schedule swing params: season, week_min, week_max, pos, min, as_of, format=json|csv, limit response includes a `columns` block giving each field's label, type, and which direction is better -- so you can rank without hardcoding semantics. Examples: https://fbdata.xyz/v1/leaders/receiving?season=2024&pos=TE&min=40 https://fbdata.xyz/v1/leaders/passing?season=2024&week_min=1&week_max=4 https://fbdata.xyz/v1/leaders/games?season=2024&format=csv ## Prediction workflows fbdata provides prediction inputs and a transparent, reproducible baseline: GET https://fbdata.xyz/v1/predictions/games?season=2026&week=1 EPA/scoring baseline: win probability, fair spread, fair total, market edge, model version, training season and reproducible input features. GET https://fbdata.xyz/v1/futures?future_type=super_bowl&prior_season=2025 Championship odds with the vig removed. Quoted outright prices are not probabilities -- a futures field sums to 120-140% at a single book, and that excess is the margin. Returns the median devigged probability across books, the fair price at that probability, the best price available, and the overround removed. future_type is super_bowl | afc | nfc. Answer "who is the favourite" from here, never from an efficiency board: team strength and championship probability are different quantities. GET https://fbdata.xyz/v1/futures/model?season=2026&market_weight=0.8 Championship probability from simulating the season rather than reading a price. Ratings drive every scheduled game, wins drive seeding, the bracket produces a champion, counted over tens of thousands of runs. Returns title, conference, division, playoff and top-seed probability plus expected wins, all from the same runs and therefore mutually consistent. Use this when the question is *why* a team's odds are what they are, or needs a quantity no book quotes. market_weight is the dial: ratings are fitted to the futures board then blended with prior-season efficiency, so 1.0 restates the market and 0.0 ignores it. `edge` is model minus market and means nothing at 1.0. Check any edge against sim_stderr on the row. GET https://fbdata.xyz/v1/agent/context?game_id=2026_01_DAL_PHI One game packet: schedule, baseline, market consensus, prop availability, injuries, depth chart, weather and explicit missing-source diagnostics. GET https://fbdata.xyz/v1/props/settlements?game_id=2026_01_DAL_PHI Every observed prop quote graded against final player-game results. DNP, ambiguous identity and unsupported play-level markets fail unresolved. Recommended feature starting points: spreads leaders/teams + leaders/adjusted + leaders/games totals leaders/teams + leaders/tendencies + leaders/games fantasy leaders/passing + leaders/rushing + leaders/receiving player props leaders/receiving + leaders/rushing + leaders/pressure market agents /llms.txt + /v1/catalog + /v1/schema + /v1/leaders/* For historical modelling, require `as_of` and verify `x-fbdata-point-in-time: true`. Omitting `as_of` returns latest and is useful for current scouting, but unsafe for backtests. Call `/v1/catalog` first: `snapshot_window.first` and `snapshot_window.latest` tell you the archive window. An `as_of` before the first snapshot correctly returns an empty result. Leaderboards honour as_of. Aggregates are computed from point-in-time play-by-play, so `?as_of=2024-11-03T00:00:00Z` returns the board as it was computable that day -- target share through week 9 as known in week 9, not as known now. This is the difference between a backtest and a fantasy. ## Raw data GET https://fbdata.xyz/v1/catalog GET https://fbdata.xyz/v1/schema/{dataset} GET https://fbdata.xyz/v1/query?dataset=&as_of=&partition=&columns=&where=&limit= GET https://fbdata.xyz/v1/history?dataset=&where= GET https://fbdata.xyz/v1/snapshots GET https://fbdata.xyz/v1/sources Datasets currently loaded: depth_charts, depth_charts_legacy, ftn_charting, futures_quotes, injuries, market_quotes, odds_events, participation, pbp, pfr_def, pfr_pass, pfr_rec, pfr_rush, player_stats, players, prediction_quotes, prop_quotes, schedules, snap_counts, weekly_rosters Catalog includes `snapshot_window.first` and `snapshot_window.latest`; choose as_of values inside that window for non-empty point-in-time reads. ## Live ingestion uv run python scripts/ingest_live.py --source odds --props --days 8 uv run python scripts/ingest_live.py --source weather --days 8 The initial production stack is nflverse/nflreadpy + The Odds API + NWS, with PFF and Sharp as permissioned enrichment. Consumer credentials do not create automated storage or redistribution rights. `/v1/sources` exposes readiness, latency, required access class and datasets present without exposing secrets. ## The parameter that matters as_of ISO-8601 instant. Omit for latest. Responses are labelled x-fbdata-point-in-time: true|false. Example -- the same play before and after an upstream refit: https://fbdata.xyz/v1/query?dataset=pbp&partition=2024&columns=game_id,play_id,epa&limit=1 https://fbdata.xyz/v1/query?dataset=pbp&partition=2024&columns=game_id,play_id,epa&limit=1&as_of=2026-02-01T00:00:00Z ## Column groups /v1/schema tags every column: observed ground truth about football. Changes are genuine corrections. derived upstream model output. Changes mean their model changed, not the game. Do not train on these without pinning as_of. volatile ingestion noise. Never versioned. ## Pricing $0.0004 per 1,000 rows returned. Advertised on every response as x-fbdata-price-usd so you can budget before being rejected. Settlement is x402 on Radius via radius-tollgate. ## Attribution Play-by-play and player data via nflverse (CC-BY-4.0). Charting via FTN Data through nflverse (CC-BY-SA-4.0). Attribution is required if you redistribute.