TheRundown
  1. Home
  2. Blog
  3. Developer guide

Developer guide

Pinnacle API alternative after the 2025 closure

Pinnacle closed its public API on July 23, 2025. A Pinnacle API alternative: Pinnacle odds, max stakes, and closing lines beside 24 other books.

· 7 min read

Pinnacle closed its API to the general public on July 23, 2025. Pinnacle’s API documentation now reserves access for select high-value bettors, commercial partners, and academic or pregame handicapping projects, by application. If you are a developer outside those groups, you can still get Pinnacle’s prices through TheRundown, a Pinnacle API alternative: Pinnacle is affiliate ID 3, returned in the same JSON schema as the other 24 sportsbooks and exchanges the API covers, with Pinnacle’s max stake on its game, period, and team-total lines. This guide covers what changed, which Pinnacle markets you get, a first request in curl and Python, how to compare Pinnacle with other books and with its own closing line, and which plan includes it (Starter, $49 a month, and up).

What changed, and when

The README of Pinnacle’s API documentation repository carries this notice near the top, in its Overview section: “Access to Pinnacle API suite has been closed for the general public since July 23rd, 2025.” It goes on to say Pinnacle offers “bespoke data services for select high value bettors & commercial partnerships” and supports “academics and pregame handicapping projects,” and asks applicants to email a short description of their use case to [email protected].

Pinnacle’s own site points to the same notice: its old API terms page, pinnacle.com/en/api/terms-and-conditions, now redirects to that GitHub repository. Developers outside those groups have no self-serve way to get new credentials, whether for a side project, a model, or a product.

What you get for Pinnacle on TheRundown

Pinnacle comes back in the same events, markets, participants, lines, and prices structure as every other book (the developer guide walks through it), keyed by affiliate ID 3. Filter to Pinnacle alone with affiliate_ids=3, or add other IDs to get several books in one response.

On an NFL game checked on October 5, 2026, Pinnacle priced:

  • Game lines: moneyline, spread, and total (market IDs 1, 2, 3), plus alternate spreads and totals when you leave off main_line=true
  • First half and first quarter: moneyline, spread, and total (4, 5, 6, 981, 957, 958)
  • Team totals for the game, first half, and first quarter (94, 95, 991)
  • Player props: passing, rushing, and receiving yards, and receptions (51, 53, 57, 58)

Dropping main_line=true also returns alternates that are no longer offered, marked with closed_at; filter those out client-side, or pass hide_closed=true to exclude them server-side.

Coverage varies by league and game; the Pinnacle odds API page lists the market types Pinnacle posts in each league. Pinnacle also prices games in progress, which come back as separate in-play markets (moneyline_in_play, handicap_in_play, totals_in_play, IDs 41, 42, 43), and futures boards through GET /sports/{sport_id}/futures, including the Super Bowl winner, division and conference winners, MVP and other awards, and NFL win totals.

Pinnacle max stake: liquidity_usd

Each Pinnacle price can carry a liquidity_usd field. TheRundown’s docs FAQ defines it, for Pinnacle, as the book’s max stake, in US dollars (full field schema in the OpenAPI spec). Three details matter when you code against it:

  • Read it from the price you use. Within a market it is often the same across alternate lines and both sides, but it can differ by alternate line and occasionally by side. On the NFL game above, most spread and total lines shared one figure, while a few alternates carried a lower one.
  • It can be absent. The field is omitted, never null and never zero, when no current reading is available, so read it with price.get("liquidity_usd") in Python. In our checks, Pinnacle’s player-prop prices (market IDs 51, 53, 57, 58) and its futures prices never carried liquidity_usd at all — treat it as a game, period, and team-total feature rather than something present on every Pinnacle price.

The same field name means something different on prediction markets: on Kalshi and Polymarket it is approximate resting order-book depth. If you read liquidity_usd across books, branch on the affiliate ID.

Your first Pinnacle request

Get a key on the odds API page and keep it in an environment variable (THERUNDOWN_API_KEY below) rather than in source control. Every request sends it in the X-TheRundown-Key header to https://therundown.io/api/v2.

Step 1: find the next game date

For the NFL, pass the regular season, preseason, and playoffs together (2,25,26), and add exclude_canceled=true so a date with only canceled events is skipped:

curl -s "https://therundown.io/api/v2/sports/dates?sport_ids=2,25,26&format=epoch&exclude_canceled=true" \
  -H "X-TheRundown-Key: $THERUNDOWN_API_KEY"

Each value is a Unix start timestamp in UTC — convert it to a calendar date (YYYY-MM-DD) before using it as the {date} path segment below, e.g. date -u -d @<timestamp> +%F (on macOS, date -u -r <timestamp> +%F), or in Python, datetime.fromtimestamp(stamp, timezone.utc).date().isoformat().

Step 2: pull Pinnacle’s prices

Request that date’s events with affiliate_ids=3 for Pinnacle only, the moneyline, spread, and total (market_ids=1,2,3), and main_line=true:

curl -s "https://therundown.io/api/v2/sports/2/events/2026-10-11?market_ids=1,2,3&affiliate_ids=3&main_line=true" \
  -H "X-TheRundown-Key: $THERUNDOWN_API_KEY"

Replace 2026-10-11 with that converted date. On a Free key the same request returns DraftKings, FanDuel, and BetMGM instead of Pinnacle, because Pinnacle needs Starter or above.

Doing it in Python

The same two calls with requests, printing each Pinnacle price with its max stake:

import os
from datetime import datetime, timezone

import requests

api = "https://therundown.io/api/v2"
headers = {"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]}
PINNACLE = "3"

# Step 1: the next NFL game date (regular season, preseason, or playoffs)
dates_resp = requests.get(
    f"{api}/sports/dates",
    params={"sport_ids": "2,25,26", "format": "epoch", "exclude_canceled": "true"},
    headers=headers,
    timeout=30,
)
dates_resp.raise_for_status()
dates = dates_resp.json()
now = datetime.now(timezone.utc).timestamp()
upcoming = [
    (sport_id, stamp)
    for sport_id, body in dates.items()
    for stamp in body.get("dates") or []
    if stamp > now
]
sport_id, stamp = min(upcoming, key=lambda row: row[1], default=("2", now))
date = datetime.fromtimestamp(stamp, timezone.utc).date().isoformat()

# Step 2: Pinnacle's main moneyline, spread, and total for that slate
slate = requests.get(
    f"{api}/sports/{sport_id}/events/{date}",
    params={"market_ids": "1,2,3", "affiliate_ids": PINNACLE, "main_line": "true"},
    headers=headers,
    timeout=30,
)
slate.raise_for_status()
print("Data points used:", slate.headers.get("X-Datapoints"))

for event in slate.json().get("events") or []:
    for market in event["markets"]:
        for participant in market["participants"]:
            for line in participant["lines"]:
                price = line["prices"].get(PINNACLE)
                if price is None:
                    continue
                # liquidity_usd is Pinnacle's max stake, omitted when no reading exists
                print(event["event_date"], market["name"], participant["name"],
                      line.get("value", ""), price["price"],
                      price.get("liquidity_usd", "-"), price["updated_at"])

Run on October 5, 2026, it printed the Falcons at Saints game: start time, market, side, line, American odds, max stake in dollars, and last update.

Data points used: 8
2026-10-06T00:15:00Z moneyline Atlanta Falcons  104 50000 2026-10-05T21:43:09Z
2026-10-06T00:15:00Z moneyline New Orleans Saints  -115 50000 2026-10-05T21:43:09Z
2026-10-06T00:15:00Z handicap Atlanta Falcons +1.5 -109 75000 2026-10-05T21:43:04Z
2026-10-06T00:15:00Z handicap New Orleans Saints -1.5 -101 75000 2026-10-05T21:43:04Z
2026-10-06T00:15:00Z totals Over 48 -102 20000 2026-10-05T21:05:20Z
2026-10-06T00:15:00Z totals Under 48 -110 20000 2026-10-05T21:05:20Z

Comparing Pinnacle with other books

Because Pinnacle shares the schema, comparing it with another book is a one-parameter change: affiliate_ids=3,19,23 returns all three books in one response. Where books post the same number (for example, all three at -3.5), their prices sit together in that line’s prices map, keyed by affiliate ID. Where the numbers differ (Pinnacle’s spread a half-point off DraftKings’ or FanDuel’s, say), each number is its own line object — match on market, participant, and line value across line objects, or drop main_line=true to pull in alternates where the numbers do overlap. Moneylines have no line value, so they always merge into one prices map; spreads and totals often don’t. GET /affiliates lists every book’s ID.

A common use is to treat Pinnacle’s price as a reference point: flag when another book’s price on the same line differs from Pinnacle’s by more than a threshold you choose, or track how a book’s line moves relative to Pinnacle’s.

Pinnacle opening and closing lines

Closing line value (CLV) compares the price you took with the last price before the game started, so it needs the closing price. Three v2 endpoints cover a line’s life:

  • GET /sports/{sport_id}/openers/{date} and GET /sports/{sport_id}/closing/{date} take the same affiliate_ids, market_ids, and main_line filters. Openers returns the earliest recorded price for each line and book; closing returns the latest recorded price at or before each event’s scheduled start (provisional before the event starts).
  • GET /events/{event_id}/markets/{market_id}/history takes the market as a path segment, not a market_ids filter, plus affiliate_ids, participant_id (to isolate one side), line, from/to, and limit (default 1,000, maximum 5,000 — the series is capped, not guaranteed to be every recorded change). It returns timestamped price points for that one market, oldest first.

Pinnacle’s closing lines for one NFL date:

curl -s "https://therundown.io/api/v2/sports/2/closing/2026-10-04?market_ids=1,2,3&affiliate_ids=3&main_line=true" \
  -H "X-TheRundown-Key: $THERUNDOWN_API_KEY"

Closing lines need Pro or above. Replace 2026-10-04 with a past game date inside your plan’s history window (30 days on Pro, 90 on Ultra); older dates return 403.

CLV describes how a past price compared with the close. It is a measurement, not a forecast of future results. The historical odds guide covers the history endpoints in detail.

Which plan includes Pinnacle

Prices and limits below are current as of October 2026; see API pricing for the live numbers.

Plan Price Pinnacle Delay Notes
Free $0, no card No 5 min DraftKings, FanDuel, and BetMGM pre-match lines only
Starter $49/month Yes 60 sec Every published book and market except futures, 7-day history; internal or personal use
Pro $149/month Yes 30 sec Opening and closing lines, 30-day history, commercial end-user display
Ultra $399/month Yes Real-time WebSocket (1 connection), futures, 90-day history

Starter is the lowest plan with Pinnacle. Pro adds Pinnacle’s opening and closing lines and lets you show odds to your own users, and Ultra adds real-time WebSocket delivery and Pinnacle futures.

Where to go next

Questions

When did Pinnacle close its API, and who can still get access?
Pinnacle closed its API suite to the general public on July 23, 2025 — see the notice in Pinnacle’s API documentation. It now grants access by application only, to select high-value bettors, commercial partners, and academic or pregame handicapping projects (apply via [email protected]).
Is there a Pinnacle API alternative?
TheRundown returns Pinnacle odds as affiliate ID 3, in the same JSON schema as the other 24 sportsbooks and exchanges it covers. Filter to Pinnacle with affiliate_ids=3, or add other IDs to compare books in one response, on Starter ($49 a month) and up — the Free plan covers only DraftKings, FanDuel, and BetMGM pre-match lines, not Pinnacle.
Can I get Pinnacle odds for free?
No. The Free plan covers pre-match moneyline, spread, and total lines from DraftKings, FanDuel, and BetMGM only. Pinnacle starts on Starter ($49 a month). See API pricing for current terms.
Does the API include Pinnacle’s max stake?
Yes, on Pinnacle’s game, period, and team-total lines. liquidity_usd is Pinnacle’s posted max stake in US dollars, reported on each price. It is often the same across a market’s alternate lines and both sides, but it can differ, so read it from the price you use. As of this writing it is not populated on Pinnacle player props or futures prices.
Can I get Pinnacle closing lines?
Yes, on Pro ($149 a month) and up. GET /sports/{sport_id}/closing/{date} with affiliate_ids=3 returns the latest recorded Pinnacle price at or before each scheduled start, and /openers returns the earliest.
Can I get Pinnacle futures?
Yes, on Ultra ($399 a month) and up. GET /sports/{sport_id}/futures with affiliate_ids=3 returns the futures boards Pinnacle prices, such as the Super Bowl winner, MVP, and NFL win totals.
How fresh are the Pinnacle odds?
It depends on your plan: a 60-second delay on Starter, 30 seconds on Pro, and real-time on Ultra and up, which adds WebSocket delivery. Every price also carries updated_at, the time of its last change.

Pinnacle starts on Starter, $49 a month.

Starter includes every published book and market except futures, which start on Ultra. Free covers only DraftKings, FanDuel, and BetMGM pre-match lines, not Pinnacle.