On the wire · 05:09:39 UTC Live 584 · Prematch 14,344 · Markets 57,085 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Answer · American football · Props

NFL player props odds API with Pinnacle prices

Updated · PinnFeed · 3 min read

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's special.description names the player and the proposition.
  • Thin markets. Props usually carry a lower maxStake than sides and totals; filter on it (for example maxStake >= 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.

The WebSocket plan: Builder, €99/mo.

Real-time Pinnacle odds pushed over one WebSocket, all 13 sports, every market, no-vig fair odds and closing lines. 3 days free, cancel in one click.

Form K-1 · Free API key

Get your free API key.

One field. No password, no card: enter your email, click the link we send, and your key is on screen.

By continuing you agree to the Terms and Privacy Policy.

One free key per email. Link valid for 20 minutes.