NFL player props odds API with Pinnacle prices
Answer: when Pinnacle posts NFL player props, they arrive as special events. On PinnFeed Builder and Pro, /v1/odds?sport=american-football returns them next to the games: a prop event has a special {category, description} object and a parentId that points to the game's event id, and its outcomes carry decimal, american, fair and fairProb. Free and Hobby are limited to main markets, so props need Builder. Which props exist, how many, and when they open depends entirely on what Pinnacle lists for each game; PinnFeed does not add any.
Props grouped by game (Python)#
import os, requests
from collections import defaultdict
H = {"x-api-key": os.environ["PINNFEED_KEY"]} # ps_live_...
# 1) find the NFL league id once (college football is a different league)
ev = requests.get("https://pinnfeed.io/v1/events", headers=H, timeout=10,
params={"sport": "american-football", "q": "nfl", "limit": 200}).json()["events"]
print({(e["league"]["id"], e["league"]["name"]) for e in ev if e["league"]})
LEAGUE = int(input("NFL league id: "))
# 2) games and props together (no main=true: that would drop the specials)
data = requests.get("https://pinnfeed.io/v1/odds", headers=H, timeout=15,
params={"sport": "american-football", "league": LEAGUE, "limit": 500}).json()["events"]
games = {e["id"]: e for e in data if not e.get("special")}
props = defaultdict(list)
for e in data:
if e.get("special") and e.get("parentId") in games:
props[e["parentId"]].append(e)
for gid, items in props.items():
g = games[gid]
print(f'{g["away"]} @ {g["home"]} ({len(items)} props)')
for p in items[:10]:
for m in p["markets"]:
line = " | ".join(f'{o["name"]} {o["decimal"]} (fair {o.get("fair")})' for o in m["outcomes"])
print(" ", p["special"]["description"], m["type"], m.get("line"), line)
Stream them (Builder)#
{ "type": "subscribe", "sports": ["american-football"], "leagues": [LEAGUE_ID], "specials": true }
Replace LEAGUE_ID with the number you found. Prop prices then arrive in the same delta frames as the game lines.
Things to know#
- Coverage is Pinnacle's, and it varies. Some games get many props, some few or none, and they often open later in the week. Write your code so an empty list is normal.
- Link by
parentId. Team names are on the game; the prop event'sspecial.descriptionnames the player and the proposition. - Thin markets. Props usually carry a lower
maxStakethan sides and totals; filter on it (for examplemaxStake >= 100) before treating a move as meaningful: max stake. - Pinnacle only. No other books' props and no player stats or injury news. Game lines: NFL odds. General specials: specials and props. Basketball: NBA player props.
Plans#
Builder (€99/mo): all markets and specials, WebSocket, closing records for games. 3-day trial; a card is required and it is charged after day 3 unless you cancel. Free and Hobby: main markets only.
Educational content for adults (18+). No tips, no guaranteed profit.
Related: historical player props.
NBA player props (same pattern)#
NBA player props use the same special-event pattern (special {category, description} and parentId pointing at the game), on sport=basketball instead of american-football. Look up the NBA league id with /v1/events?sport=basketball&q=nba. Do not pass main=true when you want the specials — that flag drops them. Free and Hobby stay on main markets only; props need Builder or Pro. Which props exist still depends only on what Pinnacle lists for that game.
Questions people ask#
Are NFL props in the closing records?#
Do not count on it. Closing capture is built around the games themselves, so for CLV on props, log the prop price yourself shortly before kick-off.
Why do I see no props for a game?#
Pinnacle has not posted any yet, or does not offer them for that game. Check again closer to kick-off.
Can I filter by player name?#
Filter special.description in your code; the q= search matches team and league names, not prop descriptions.