Pinnacle API alternative · independent

A Pinnacle API alternative for live and prematch odds.

Pinnacle shut its public API in July 2025 and now deals only with selected business partners. If your code still needs those prices, PinnRadar delivers the in-play and pre-game markets through REST, Server-Sent Events, a raw WebSocket and an MCP server, on a self-serve key that needs only an email.

Email only · no Pinnacle account · independent, not affiliated with Pinnacle

Phases
Live + prematch
Sports
13
Transports
REST · SSE · WS
Free key
$0, email only

01 · Where things stand

The official API closed. The need did not.

Pinnacle took its public API off sale on 23 July 2025. Existing integrations were cut off, and new access now means negotiating a direct commercial deal rather than paying a listed price. Models, alert bots and closing-line checks that read Pinnacle as their reference price lost their source.

That leaves three routes: a deal with Pinnacle, a scraper you keep alive yourself, or an independent feed. PinnRadar is the third. It carries Pinnacle's prices, line depth and market coverage in real time, and you start on a free key with no sales call.

It is a data service only. You read prices; there is nothing to log in to at Pinnacle and nothing that places a bet.

What you get on every plan:

  • Live and prematch boards for 13 sports, soccer, tennis, basketball and esports among them
  • Moneyline, spreads, totals and team totals, quarter lines included
  • Player and team props, correct scores and futures on request
  • Server-side dropping odds detection with the no-vig fair price
  • The same data in Claude, Cursor or VS Code through the MCP server

02 · Migration map

Your old calls, mapped.

Every integration asks the same few questions. Here is where each answer lives now. Send the key as x-portal-apikey, x-api-key or ?key=.

You needPinnRadarNotes
List of sportsSport id tableStable integers: 1 Soccer, 2 Tennis, 3 Basketball, 11 Esports and so on
Upcoming fixtures with pricesGET /kit/v1/prematch/fixturesEvery open fixture of one sport with all periods and markets
In-play boardGET /kit/v1/marketsevent_type=live is the default; the layout matches prematch
One event, every market/kit/v1/details · /kit/v1/prematch/marketsLive and prematch respectively, by event_id
One market typeGET /kit/v1/prematch/linesmarket_type: money_line, spreads, totals or team_total
Only what changedsince= cursorPass the last value of your previous reply
Props and futuresinclude_specials=1Flat rows linked by parent_id, or nested
Push updateswss://…/ws/feedRaw upstream frames; $99 / mo add-on
Line moves/odds-drop · /api/dropsSSE alerts, or a pollable buffer of about 3 h
Feed healthGET /healthLive and prematch status, write age in ms
Bets, balance, historyNot offeredPinnRadar is a data feed only

03 · First calls

A full board, then only the deltas.

The usual pattern carries over directly. Fetch a sport's whole board once, keep it keyed by event_id, then send the last cursor back as since= so each later reply holds only the events that changed.

A delta reply cannot tell you that an event left the board. Fixtures that kick off move to the live board, and withdrawn ones disappear, so refresh the full response every so often. The delta polling notes spell out each case, and the X-Data-Status header tells an empty board apart from a quiet feed.

Pick a poll interval your plan allows: a Free key has 100 requests a day, REST and Edge 10 a second. Plain HTTP works, or use the optional SDK: pip install pinnradar / npm install pinnradar. Longer walkthroughs: Pinnacle odds in Python and REST vs WebSocket vs SSE.

pythonprematch soccer, delta polling
import os, time, requests

BASE = "https://pinnradar.com"
s = requests.Session()
s.headers["x-portal-apikey"] = os.environ["PINNRADAR_KEY"]

def fixtures(**params):
    r = s.get(BASE + "/kit/v1/prematch/fixtures",
              params={"sport_id": 1, **params}, timeout=30)
    r.raise_for_status()
    return r.json()

board = fixtures()                       # full board once
book = {ev["event_id"]: ev for ev in board["events"]}
cursor = board["last"]

while True:
    time.sleep(60)                       # fit this to your plan
    delta = fixtures(since=cursor)       # changed events only
    for ev in delta["events"]:
        book[ev["event_id"]] = ev
    cursor = delta["last"]
node 18+live basketball moneylines
const BASE = "https://pinnradar.com";
const url = new URL("/kit/v1/markets", BASE);
url.searchParams.set("sport_id", "3");
url.searchParams.set("event_type", "live");

const resp = await fetch(url, {
  headers: { "x-portal-apikey": process.env.PINNRADAR_KEY },
});
if (!resp.ok) throw new Error(`markets: HTTP ${resp.status}`);
const { events } = await resp.json();
for (const ev of events) {
  const ml = ev.periods?.num_0?.money_line;
  if (ml) console.log(ev.league_name, ev.home, "v", ev.away, ml.home, ml.away);
}

04 · Fit check

What carries over, and what does not.

Layout

Familiar JSON

Events with periods keyed num_0, num_1 and so on; decimal prices, handicaps and totals keyed by line, with a max stake per line.

Depth

Full ladders

Alternate spreads and totals, every team-total line in team_totals, and quarter lines at .25 and .75, on the free key as on Scale.

Specials

Props on request

Player props, team props, correct scores and futures arrive as their own rows, each pointing back to its match through parent_id.

Not included

No bet placement

There are no betting, balance or account endpoints. PinnRadar reads the market; it never trades on it.

Not included

No archive

The service is real time. If you need history, record the stream on your side, and grade bets with your own closing-line store.

Scope

One bookmaker

Pinnacle as the sharp reference price, on purpose. Comparing against soft books needs a second source next to it.

05 · Plans

Same data on every tier. You pay for rate and push.

Longer billing terms cut up to about 24%. MCP calls count against the same plan.

PlanPriceRESTSSE drop streamsWebSocket
Free$020/min, 100/dayNoNo
Drops$99 / moFree limitsYesNo
REST$99 / mo10 req/sNo+$99 / mo add-on
Edge$149 / mo10 req/sYes+$99 / mo add-on
Scale$229 / mo30 req/sYes+$99 / mo add-on

Full breakdown, billing terms and payment methods on the Pinnacle API pricing page, with a plain-language guide in choosing a plan. Rate limits are in the docs.

06 · Further reading

Go deeper.

07 · Questions

Before you switch.

Anything else goes to @PinnRadarSupport on Telegram or info@pinnradar.com, answered by the people who run the feed.

Is there still a public Pinnacle API?

Not through any public sign-up. Pinnacle took its public API off sale on 23 July 2025, and new access now means a direct commercial agreement with Pinnacle. PinnRadar is a separate, independent service that delivers Pinnacle's live and prematch prices to a self-serve key over REST, SSE and WebSocket.

Do I need a Pinnacle account to use PinnRadar?

No. An email address gets you a key, and you never sign in to Pinnacle. PinnRadar is not affiliated with, endorsed by or connected to Pinnacle.

How much code changes when I switch?

The /kit/v1 responses follow the layout of the common third-party Pinnacle price APIs, and the key goes in the x-portal-apikey header those clients already send, so most of them migrate by swapping the base URL and the key. Code built around a different layout maps onto the Event object: periods, then money_line, spreads, totals and team totals.

Can I place bets through PinnRadar?

No. PinnRadar supplies odds data only. It does not take, place or facilitate bets, and it has no balance or bet-history endpoints. Placement stays with whichever account you bet from.

Are live prices and push updates included?

Yes. Live prices come from /kit/v1/markets on every plan, the SSE drop streams are part of Drops, Edge and Scale, and the raw WebSocket feed is a $99 monthly add-on on any plan with REST.

Can I get historical odds?

Not from PinnRadar. It is a real-time service with no archive of past prices. Teams that want history record the /ws/feed stream themselves and keep their own store. If you need something specific, ask support.

Is there a free plan to test with?

Yes, and it does not expire. A Free key allows 20 requests a minute and 100 a day over REST, with every sport and full line depth. New accounts also start with a three-day full demo of the push streams. Paid plans are on the pricing page.

Point your client at a new base URL.

The Free key costs nothing and never expires. Swap the base URL and the key, run your parser against a live board, and upgrade only when you need the rate or the streams.