The News feature gives every player a running feed of recent headlines — each one tagged by impact so you can tell an injury designation apart from a puff piece. This guide covers the data model, how to pull and filter it, how to seed coverage for players the dataset hasn't picked up yet, and how to render it as a live feed.
/api/v1/news/{player_id} — recent headlines for a player/api/v1/news/{player_id}/request — seed coverage for a player with no news yetA player ID is "{Player Name}#{POS}" — e.g. Malik Nabers#WR. URL-encode it (the # becomes %23).
Each item in the news array is one headline:
{
"headline": "Nabers (knee) full participant at Wednesday practice",
"impact": "injury",
"source": "espn-nfl",
"url": "https://www.espn.com/nfl/story/_/id/00000000",
"published_at": "2026-09-10T17:22:00Z"
}
The impact tag is what makes the feed useful — it lets you color, filter, or prioritize headlines by what they actually mean for a lineup:
| impact | What it covers |
|---|---|
| injury | Injury designations, practice participation, IR / activations, game-time decisions |
| role | Depth-chart moves, snap/target/touch share, promotions and benchings |
| transaction | Signings, trades, releases, suspensions, roster moves |
| general | Everything else — previews, features, and analysis |
curl -H "x-api-key: YOUR_KEY" \
"https://api.gridirondata.com/api/v1/news/Malik%20Nabers%23WR?days=7"
{
"player_id": "Malik Nabers#WR",
"days": 7,
"count": 2,
"news": [ /* newest first */ ]
}
Three query params shape the response:
days — lookback window (default 14, max 90). Items roll off after ~30 days.limit — max headlines to return (default 10, max 50).impact — return only one category, e.g. ?impact=injury.Ask the API for a single category server-side, or pull everything and group client-side. Server-side filtering keeps payloads small when you only care about, say, injuries:
curl -H "x-api-key: YOUR_KEY" \
"https://api.gridirondata.com/api/v1/news/Malik%20Nabers%23WR?impact=injury&days=14"
Tracking a deep-bench player or a just-promoted backup the dataset hasn't covered yet? A count: 0 response hands you a ready-made link to request one:
{
"player_id": "Max Bredeson#RB",
"count": 0,
"news": [],
"message": "No news found for Max Bredeson#RB in the last 14 days.",
"request_scrape": { "method": "POST",
"href": "https://api.gridirondata.com/api/v1/news/Max%20Bredeson%23RB/request" }
}
curl -X POST -H "x-api-key: YOUR_KEY" \
"https://api.gridirondata.com/api/v1/news/Max%20Bredeson%23RB/request"
# 202 Accepted — the scrape runs asynchronously; poll GET /news again shortly after
POST /news/{player_id}/request is added to the automated scraper — so your first lookup seeds them, and every run after that stays fresh with no extra work.Pull news for a watchlist, merge into one timeline, and render newest-first with an impact label. Swap the print for HTML, a Discord embed, or a dashboard card — the shape is the same.
import requests
from urllib.parse import quote
API = "https://api.gridirondata.com/api/v1"
H = {"x-api-key": "YOUR_KEY"}
WATCHLIST = ["Malik Nabers#WR", "Bijan Robinson#RB", "Trey McBride#TE"]
LABEL = {"injury": "🔴 INJURY", "role": "🟠 ROLE",
"transaction": "🔵 MOVE", "general": "⚪ NEWS"}
def player_news(pid, days=7, limit=10):
r = requests.get(f"{API}/news/{quote(pid, safe='')}",
headers=H, params={"days": days, "limit": limit})
r.raise_for_status()
return r.json()
feed = []
for pid in WATCHLIST:
data = player_news(pid)
if data.get("count", 0) == 0: # no coverage yet — seed it
link = data.get("request_scrape")
if link:
requests.request(link["method"], link["href"], headers=H)
continue
for item in data["news"]:
feed.append((pid, item))
# One timeline, newest first
feed.sort(key=lambda x: x[1]["published_at"], reverse=True)
print("=== PLAYER NEWS FEED ===")
for pid, item in feed:
name = pid.rsplit("#", 1)[0]
tag = LABEL.get(item["impact"], item["impact"].upper())
print(f"{tag:12} {name:20} {item['headline']}")
print(f"{'':12} {item['url']} ({item['source']})")
News items refresh throughout the day and roll off after ~30 days, so a small days window (5–7) keeps the feed tight and current. For a live dashboard, poll every 15–30 minutes; for a weekly check, run it Sunday morning with days=3 to catch just the pre-kickoff updates. Because on-demand scrapes are asynchronous, request any uncovered players on the first pass, then re-poll them a minute later.
/news