Released September 2026 · Available on every plan, no version bump required
Every fantasy-relevant player now carries per-week offensive snap share back to 2020 — the share of his team's offensive plays he was actually on the field for. It's the earliest honest signal of a role change, and it's live on a new /snaps endpoint plus joined onto the stats you already pull.
Fantasy points are a lagging indicator. A running back can take over a backfield in Week 9 and still post a quiet line because the game script went sideways. Snap share doesn't have that problem — if the coach is putting him on the field for 85% of plays instead of 40%, the role has already changed, and the points follow.
Chase Brown's 2024 season is the clean version of this. Here's what the API returns for him, alongside his PPR output:
| Week | Opponent | Snap share | Snaps | PPR |
|---|---|---|---|---|
| 1 | NE | 33% | 17 | 5.3 |
| 4 | CAR | 40% | 27 | 23.2 |
| 8 | PHI | 48% | 28 | 11.4 |
| 9 | LV | 80% | 59 | 26.7 |
| 10 | BAL | 87% | 71 | 24.4 |
| 14 | DAL | 83% | 59 | 24.3 |
| 15 | TEN | 93% | 64 | 26.3 |
Weeks 1–8 he hovered between 20% and 48%. From Week 9 on he never dropped below 80%. If you were watching snap share, the takeover was visible the Sunday it happened — not three box scores later.
/api/v1/snaps/{player_id}?season=2024&trend=4 — per-week snap share, season average, and a trailing-window trend/api/v1/snaps?name=Chase+Brown&position=RB — same thing by name and position/api/v1/stats/{player_id}/{season} — now carries snap_pct on every weekly entry plus a snap_counts block0–100. Sourced from nflverse / Pro-Football-Reference game-level snap counts, which begin in 2013 league-wide.
curl -H "x-api-key: YOUR_KEY" \
"https://api.gridirondata.com/api/v1/snaps/Chase%20Brown%23RB?season=2024&trend=4"
{
"player_id": "Chase Brown#RB",
"player_name": "Chase Brown",
"position": "RB",
"season": "2024",
"games": 16,
"games_with_snaps": 16,
"season_snap_pct_avg": 62.8,
"recent_snap_pct_avg": 88.8,
"trend_weeks": 4,
"trend_delta": 26.0,
"totals": {
"games": 16,
"offense_snaps": 686,
"offense_pct_avg": 62.8,
"st_snaps": 82,
"st_pct_avg": 18.6
},
"weekly_snaps": [
{ "week": 1, "offense_snaps": 17, "snap_pct": 33.0, "st_snaps": 9,
"st_pct": 43.0, "team": "CIN", "opponent": "NE" }
],
"source": "nflverse / Pro-Football-Reference game-level snap counts"
}
The three fields that do the work:
season_snap_pct_avg — his baseline role across the seasonrecent_snap_pct_avg — his role over the last trend weeks he actually playedtrend_delta — the difference. Positive means the role is growing.Weeks with zero offensive snaps are inactives, not "played but never on the field," so they're excluded from both averages. That keeps a bye or a healthy scratch from faking a collapse in the trend.
You don't need a second request to correlate the two. Snap share is joined onto the stats endpoint you're probably already calling:
curl -H "x-api-key: YOUR_KEY" \
"https://api.gridirondata.com/api/v1/stats/Chase%20Brown%23RB/2024"
{
"weekly_stats": {
"9": { "points": 26.7, "opponent": "LV", "snap_pct": 80.0, "offense_snaps": 59 }
},
"snap_counts": {
"weekly": { ... },
"totals": { "games": 16, "offense_snaps": 686, "offense_pct_avg": 62.8 }
}
}
0.
The real payoff is running this across a position group and sorting by trend_delta. This finds the players whose roles are expanding right now:
import requests
from urllib.parse import quote
API = "https://api.gridirondata.com/api/v1"
H = {"x-api-key": "YOUR_KEY"}
SEASON = "2024"
MIN_GAMES = 8 # ignore small samples
TREND = 4 # trailing window
def snaps(player_id):
r = requests.get(f"{API}/snaps/{quote(player_id, safe='')}",
headers=H, params={"season": SEASON, "trend": TREND})
return r.json() if r.status_code == 200 else None
# Every RB/WR/TE in the dataset.
pool = []
for pos in ("RB", "WR", "TE"):
r = requests.get(f"{API}/players", headers=H, params={"position": pos})
pool += [p["player_id"] for p in r.json()["players"]]
risers = []
for pid in pool:
d = snaps(pid)
# 404 simply means no snap data for that player-season.
if not d or d["games_with_snaps"] < MIN_GAMES:
continue
risers.append((d["trend_delta"], pid, d["position"],
d["season_snap_pct_avg"], d["recent_snap_pct_avg"]))
risers.sort(reverse=True)
print(f"{'DELTA':>6} {'PLAYER':26} {'POS':4} {'SEASON':>7} {'LAST 4':>7}")
for delta, pid, pos, season_avg, recent in risers[:10]:
print(f"{delta:+6.1f} {pid.rsplit('#', 1)[0]:26} {pos:4} "
f"{season_avg:7.1f} {recent:7.1f}")
Run against 2024, that returns:
DELTA PLAYER POS SEASON LAST 4
+37.2 Daniel Bellinger TE 33.1 70.2
+33.6 Payne Durham TE 39.7 73.2
+32.0 Parker Washington WR 55.3 87.2
+28.8 Malik Washington WR 44.7 73.5
+28.8 Cedric Tillman WR 54.9 83.8
+26.0 Chase Brown RB 62.8 88.8
+25.0 Isaac Guerendo RB 24.5 49.5
+24.6 Nick Westbrook-Ikhine WR 69.9 94.5
+24.2 Stone Smartt TE 20.6 44.8
+23.7 Olamide Zaccheaus WR 42.1 65.8
Note what this list is and isn't. It surfaces role change, not value — Daniel Bellinger at the top was a blocking tight end whose snaps ballooned without the targets to match. That's the honest read: snap share tells you a player is on the field, and you still have to ask what he's doing there. Cross-reference against /stats targets and you separate the Chase Browns from the Bellingers.
Combining the two signals is a handful of lines. A player worth a claim is one whose snap share jumped and whose production followed:
def worth_a_claim(player_id, season=SEASON):
s = snaps(player_id)
if not s or s["games_with_snaps"] < MIN_GAMES:
return None
r = requests.get(f"{API}/stats/{quote(player_id, safe='')}/{season}",
headers=H, params={"scoring": "ppr"})
weekly = r.json()["weekly_stats"]
# Split the season at the snap-share inflection point.
recent_weeks = sorted((int(w) for w in weekly), reverse=True)[:TREND]
recent_pts = [float(weekly[str(w)]["points"]) for w in recent_weeks]
all_pts = [float(v["points"]) for v in weekly.values()]
ppg_now = sum(recent_pts) / len(recent_pts)
ppg_season = sum(all_pts) / len(all_pts)
return {
"player": player_id,
"snap_delta": s["trend_delta"],
"ppg_delta": round(ppg_now - ppg_season, 1),
# Role expanding AND the points are showing up.
"claim": s["trend_delta"] > 10 and ppg_now > ppg_season,
}
A positive snap_delta with a flat ppg_delta is the interesting edge case: the role arrived but the production hasn't. Historically that's the buy window, and it closes fast.
If you use the MCP server, snap share landed there too as get_snap_share. Update to the latest server and you can just ask:
"Which RBs gained the most snap share over the last four weeks of 2024,
and did their PPR points follow?"
st_snaps / st_pct, which is what you want for evaluating a bench player's path to a role.