Stat Explainer

NFL API Guide: Free NFL Stats Data for Python and R

The free source most public NFL analysis runs on is nflverse: 24 data releases on GitHub, 4,376 files, no key, CC BY 4.0. The catalog, how to load it with nflreadr or nflreadpy (nfl_data_py is archived and deprecated), the two releases that are traps, and a timed test: after Thursday night's game the 2026 play-by-play file was replaced 4 hours 18 minutes after kickoff.

By C. B. Zakarian · Published October 16, 2026

Is there a free NFL API for stats?

The free source most public NFL analysis is built on is nflverse: a GitHub repository that publishes its data as release files, with no key and no account, under a CC BY 4.0 licence. On October 16, 2026 it held 25 releases (24 of data and one for testing) and 4,376 files, about 6.6 GB. You load them with nflreadr in R or nflreadpy in Python, or read a file's URL directly. After Thursday night's game the 2026 play-by-play file was replaced 4 hours 18 minutes after kickoff.

Related: Expected points (EPA) · Chapter 3: nflverse and nflfastR · Resources

Measured from the nflverse release listing and repository records read through GitHub's REST API at 1:20 am ET on October 16, 2026, and from the 2026 play-by-play file downloaded at that time.

What "NFL API" Means for Free Data

Most searches for an NFL API are looking for one thing: a way to pull play-by-play, scores and player stats into code without paying. The free answer is not a REST service with endpoints and keys. It is a set of files. nflverse, an open-source project, runs automated jobs that rebuild the data and upload it to GitHub releases, one release per data set (play-by-play, schedules, rosters, injuries and so on), with one file per season in several formats: csv, compressed csv, parquet, R's rds and qs.

That makes the URL of a file the API. Every file follows the same pattern; the 2026 play-by-play file, for example, is at

https://github.com/nflverse/nflverse-data/releases/download/pbp/play_by_play_2026.parquet

and the season number and the format in the name are all that change. The two loader packages, nflreadr for R and nflreadpy for Python, build these URLs for you, cache the downloads and hand back a data frame.

This guide sticks to openly licensed data. Sports sites also serve JSON to their own apps through endpoints that have no public documentation; their terms of use govern those, not a published licence, so they are left out here. Paid data services are left out too: none were tested.

The Exhibit

Horizontal bars for the 24 nflverse data releases, on a log scale of hours since each release's newest file was updated, at 1:20 am ET on October 16, 2026. Five releases updated after Thursday's 8:15 pm ET kickoff are green: schedules, pfr_advstats, stats_team, stats_player and pbp, all under an hour old. Twelve more, updated within the past week, are navy, most of them 15 to 17 hours old. Seven older releases are rust, from misc at about 700 hours to player_stats at about 12,600 hours, last changed in May 2025.
Every nflverse data release, by how long ago its newest file was updated, with each release's file count and size. Data: the nflverse-data release listing through GitHub's REST API, read 1:20 am ET, October 16, 2026.

The Catalog: 24 Data Releases

Sorted by size. "Newest file" is the date, Eastern time, of the most recent update to any file in the release.

ReleaseWhat it holdsFilesMBNewest file
pbpPlay-by-play, every season since 1999, with EPA, win probability and CPOE1644,3272026-10-16
player_statsThe old player stats files (deprecated 2025-08-01)1,8315812025-05-07
stats_playerPlayer stats by week, season and season with playoffs5543932026-10-16
pbp_participationWho was on the field for each play, from NGS (no 2026 file)463932026-02-10
weekly_rostersRosters by week, since 20021043112026-10-15
depth_chartsDepth charts1092682026-10-15
rostersSeason rosters434712026-10-15
snap_countsSnap counts77482026-10-13
ftn_chartingPlay charting provided by FTN21392026-10-14
contractsOverTheCap contract data7332026-10-15
pfr_advstatsPro Football Reference advanced stats209262026-10-16
stats_teamTeam stats by week, season and season with playoffs554222026-10-16
players_componentsComponent files for the players build12182026-10-15
injuriesInjury reports and practice participation77182026-10-15
miscOne-off files, not updated automatically17172026-09-16
playersPlayer information and ID mappings7172026-10-15
nextgen_statsNFL Next Gen Stats tables95132026-10-15
espn_dataESPN QBR, by season and by week1242026-10-15
draft_picksDraft picks since 1980742026-10-14
schedulesSchedule and results: one row per game642026-10-16
combineCombine results722026-03-12
officialsOfficials assigned to each game722026-09-02
tradesTrades7<12026-05-19
teamsTeam names, colors and logo links7<12026-03-27

Play-by-play is the core: 164 files and 4,327 MB, a file per season for every season from 1999 to 2026, each play carrying expected points added (EPA), win probability and completion percentage over expected (CPOE). The next most useful for most work are schedules, one row per game with the score, and the two stats releases, stats_player and stats_team, which hold weekly and season totals.

Two releases are traps. player_stats has the most files, 1,831, but its release notes read "DEPRECATED 2025-08-01: USE stats_player OR stats_team INSTEAD", and none of its files has changed since May 7, 2025. Code that still reads it gets no 2026 numbers. And misc is labelled in its notes as one-off files that are not updated automatically.

How Fresh Is It? Thursday Night, Timed

Thursday's game gives a clean test. Seattle at Denver kicked off at 8:15 pm ET on October 15, and Denver won 17-14. The listing read at 1:20 am ET showed:

  • the 2026 play-by-play file replaced at 12:33 am ET, 4 hours 18 minutes after kickoff, and already holding the game;
  • the weekly player and team stats files at 12:34 am;
  • Pro Football Reference's advanced stats at 1:02 am;
  • the schedules file, with the final score, at 1:16 am, 5 hours 1 minute after kickoff.

Those five releases were the only ones changed since kickoff. Over the day before, 14 of the 24 releases had a file updated, the other nine between 8:16 am and 9:48 am ET on Thursday, and 17 of the 24 within the week. The files are also rebuilt when no game has been played: the 2026 play-by-play file read on Wednesday, October 14 carried a 10:31 am ET timestamp from that morning, and the weekly stats files read on Thursday a 10:12 am timestamp, both days with no game since Monday night.

These are a handful of observations, not a published schedule. What they show is the practical rhythm: the data is a morning-after source, not a live feed. Nothing in these releases updates during a game, and a timestamp says when a file was uploaded, not which games it holds, so check the latest week in the data before you trust it.

Loading It: R, Python, or a URL

R. nflreadr is the loader the release notes themselves name (the play-by-play release reads "accessed with nflreadr::load_pbp()"):

install.packages("nflreadr")
library(nflreadr)
pbp   <- load_pbp()        # play-by-play, current season
games <- load_schedules()  # schedules and results

Python. Use nflreadpy. Its README describes it as a Python port of nflreadr; it returns Polars data frames, and a to_pandas() call converts one for pandas users. The repository was created on September 8, 2025 and is MIT-licensed:

pip install nflreadpy

import nflreadpy as nfl
pbp = nfl.load_pbp()          # current season, a Polars DataFrame
pbp = pbp.to_pandas()         # if you work in pandas
games = nfl.load_schedules()

The older Python package, nfl_data_py, is the one most search results still point to. Its repository is archived, its last push was September 25, 2025, and its README now opens: "nfl_data_py has been deprecated in favour of nflreadpy ... No further nfl_data_py maintenance or updates are planned." New code should start with nflreadpy.

No package at all. Any tool that reads a URL can read a release file. In pandas, with pyarrow installed:

import pandas as pd
url = "https://github.com/nflverse/nflverse-data/releases/download/pbp/play_by_play_2026.parquet"
pbp = pd.read_parquet(url)

Choose parquet when you can. The 2026 play-by-play file is 28.2 MB as csv, 5.5 MB as compressed csv, 6.0 MB as parquet and 4.2 MB as rds: the parquet file is about a fifth of the csv and keeps each column's type.

A Worked Example: Thursday's Game From the File

The 2026 play-by-play file downloaded at 1:20 am ET has 14,031 rows and 372 columns, covering 80 games, weeks 1 through 6. Not every row is a play from scrimmage. The usual filter keeps rows marked as a pass or a run that carry an EPA value:

plays = pbp[((pbp["pass"] == 1) | (pbp["rush"] == 1)) & pbp["epa"].notna()]
tnf = plays[plays["game_id"] == "2026_06_SEA_DEN"]
tnf.groupby("posteam")["epa"].agg(["count", "mean"])
(tnf["epa"] > 0).groupby(tnf["posteam"]).mean()   # success rate

That leaves 10,350 plays for the season: 5,677 passes, 4,153 runs and 520 rows whose play type is no_play, snaps wiped out by a penalty that the file still marks as a pass or a run. The 3,681 rows the filter drops are 974 other penalty rows, 827 kickoffs, 614 punts, 704 extra points and field goals, 152 kneel-downs and spikes, and 410 marker rows such as the start and end of each game and the end of each quarter.

Thursday's game has 189 rows and 142 plays. Seattle ran 83 plays at -.089 EPA per play with a success rate of .398; Denver ran 59 at -.113 with a success rate of .288. Denver won anyway, 17-14, and the file's own running score columns (total_home_score and total_away_score) end at 17 and 14, matching the game log. One game's per-play numbers and its result can point different ways; the success rate and expected points explainers explain what each measure can and cannot say.

Before You Build on It

  • Credit the source. The nflverse-data repository is licensed CC BY 4.0, which allows reuse with attribution. Some releases carry data that the release notes credit to third parties, among them FTN (charting), Pro Football Reference (advanced stats, draft picks, combine) and OverTheCap (contracts); read a release's notes before you reuse it commercially.
  • Team codes change. The game log, which runs from 1999, keeps the codes of the time: OAK through 2019, SD through 2016 and STL through 2015. Map them to LV, LAC and LA before you join seasons.
  • Old files can have holes. The 2002 team-stats file holds only eight of Jacksonville's 16 games (its home games are missing), which is why the site's turnover history starts in 2003. Count games per team before you trust a season.
  • Use the current releases. stats_player and stats_team, not player_stats; nflreadpy, not nfl_data_py.

What This Page Leaves Out

  • Live data. Nothing here updates during a game; a live score feed is outside this guide.
  • Paid services. None were tested, so none are compared.
  • A schedule. The update times above are what the listing showed on three days in October 2026, nothing more.
  • Every column. nflverse documents the columns in data dictionaries linked from the nflreadr site; this page uses only a handful.

Method and Sources

catalog      = GET api.github.com/repos/nflverse/nflverse-data/releases (all pages, every asset)
newest file  = latest asset updated_at in each release, shown in Eastern time (UTC-4)
freshness    = asset updated_at minus Thursday's kickoff, 2026-10-16 00:15 UTC
libraries    = repository records and READMEs for nflreadr, nflreadpy, nfl_data_py, nflfastR
worked case  = play_by_play_2026.parquet; plays = (pass == 1 or rush == 1) and EPA not missing

The script make_nfl_api_guide_chart.py reads the frozen listing, repository records and play-by-play file, builds the catalog and the timings, checks Thursday's final score in the file against the game log, draws the exhibit and asserts every number on this page.

Sources: the nflverse-data release listing, licence record and 2026 play-by-play file, read through GitHub's REST API at 1:20 am ET on October 16, 2026, with the play-by-play and stats listings read October 14 and 15 for the earlier timestamps; the repository records and READMEs of nflreadr, nflreadpy and nfl_data_py, read the same morning; the nflverse game log for Thursday's score.

Further reading

About the author

C. B. Zakarian

C. B. Zakarian is an independent analyst who writes about what he can measure. He builds every model, chart, and calculator on this site himself from the public nflverse play-by-play and game-log releases, shows the working, and never invents a number. The dataset behind the exhibits is served openly at /data/, and the method behind every figure is spelled out so you can check it against the same file. When the data can't answer a question, he says so.

More Explainers
Do Favorites Cover? Scoring by Week Most Common Scores Favorite Win Rates Playoff Football Division Games & Home Field DVOA EPA vs. DVOA CPOE Passer Rating vs. QBR Pythagorean Wins Air Yards & YAC Fourth-Down Analytics Strength of Schedule ANY/A RYOE Pass Protection Coverage Metrics Special Teams PROE & Game Script Red Zone Efficiency Explosive Plays Third Down Time of Possession Turnovers & Luck Win Probability YAC Over Expected Snaps & Usage Points Per Drive Success Rate Pressure Rate Play-Action Yards After Contact RPO Two-Point Conversions Yards per Route Run Block Win Rates Target Share & WOPR Home-Field Advantage Expected Points Point Spread Accuracy Weather & Scoring Rest & Scheduling Scoring Trend Overtime Over/Under Accuracy Key Numbers (3 & 7) Thursday & Primetime Grass vs. Turf One-Score Games Stadium Scoring Referee Effects QB Continuity Week 1 Signal Shutouts 2026 Schedule Strength 2026 Schedule Quirks Best Record vs. Super Bowl Win & Loss Streaks Division Repeats Close-Game Luck The Prediction Model The Week 1 Slate AFC East 2026 AFC North 2026 AFC South 2026 AFC West 2026 NFC East 2026 NFC North 2026 NFC South 2026 NFC West 2026 Preseason Signal 2026 Preseason 2026 Win Totals 2026 Playoff Odds 2026 International Games 2026 Miss Budget AFC vs NFC The 17-Game Era The Coach Ledger Week 1 Predictions Opening Night 2026 SB Rematch Effect Road Favorites The Chiefs' Rating Division Leverage The Learning Curve The Board, Sorted September, Priced The Offseason Haircut Fair Prices What One Game Moves The Shortest Lines The Week 10 Problem The New-Coach Bounce Same Record, Different Rating The Opener, Graded Rankings After the Opener The First Miss, Graded What Sunday Can Do SF and LA, Re-Priced No Good Years, Only Lucky Ones Week 2 Overreaction Sunday, Graded Week 1 Scoring, 2026 What 0-2 Costs Monday Night, Graded Playoff Odds After Week 1 Calibrated Playoff Odds Thursday: DET at BUF Game-Pick Calibration The QB Blind Spot DET at BUF, Graded The Second Meeting Three Fixes, One Knob The Engine's Constants The Margin Multiplier Honest, Not Sharp A Hindsight Variable What Two Weeks Bought What Would Change Its Mind Week 3 Leverage Board How Low Is 1314.6 What 0-3 Means The Order of a 1-1 Start ATL at GB, Graded Denver's Home Field Week 3, Graded ATL at NO: Boom or Bust September, Graded 0-4 and Still 14th PHI at JAX in London HOU at TEN: Two 0-4 Teams CHI at GB: Favoured at Lambeau Remaining Schedules After Week 4 TB at DAL: Thursday Week 5: Ledger vs Market TB at DAL, Graded Week 5: Three Long Trips The NFC West, Measured 1-3 Favourites Thirteen Straight New Coaches, Four Games In Week 5 Sunday, Graded Week 5 Playoff Swings Standings After Week 5 Week 6 Playoff Picture Seahawks at Broncos by EPA EPA Rankings After Week 5 Passer Rating Formula Turnover Differential After Week 5 NFL API: Free Data Guide Division Standings 2026: Games Behind All explainers

Go deeper

Want the code behind these metrics? Work through the 43-chapter NFL analytics tutorial.

Browse tutorials Free tools