### Fetch prematch fixtures with Go Source: https://pinnodds.com/docs Go example using net/http to get prematch fixtures. Decodes the JSON response into a struct with Events field. Requires BASE and KEY variables. ```go req, _ := http.NewRequest("GET", BASE+"/kit/v1/prematch/fixtures?sport_id=1", nil) req.Header.Set("x-portal-apikey", KEY) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() var out struct { Events []map[string]interface{} `json:"events"` } json.NewDecoder(resp.Body).Decode(&out) // out.Events[i] has periods, money_line, spreads, totals, team_total, etc. ``` -------------------------------- ### Fetch prematch fixtures with PHP Source: https://pinnodds.com/docs PHP example using cURL to get prematch fixtures. Filters events that have odds and a num_0 period. Requires BASE and KEY variables. ```php true, CURLOPT_HTTPHEADER => ["x-portal-apikey: $KEY"], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); $with_odds = array_filter($data["events"], fn($e) => ($e["is_have_odds"] ?? false) && isset($e["periods"]["num_0"])); ``` -------------------------------- ### Fetch prematch fixtures with Python requests Source: https://pinnodds.com/docs Python example using requests to get prematch fixtures. Filters events that have odds and a num_0 period. Requires BASE and KEY variables. ```python import requests r = requests.get( f"{BASE}/kit/v1/prematch/fixtures", params={"sport_id": 1}, headers={"x-portal-apikey": KEY}, ) events = r.json()["events"] with_odds = [e for e in events if e.get("is_have_odds") and e.get("periods", {}).get("num_0")] ``` -------------------------------- ### Fetch prematch fixtures with Node.js fetch Source: https://pinnodds.com/docs Node.js example using fetch to get prematch fixtures. Filters events that have odds and a num_0 period. Requires BASE and KEY variables. ```javascript const r = await fetch( `${BASE}/kit/v1/prematch/fixtures?sport_id=1`, { headers: { "x-portal-apikey": KEY } } ); const { events } = await r.json(); const withOdds = events.filter(e => e.is_have_odds && e.periods?.num_0); ``` -------------------------------- ### Fetch live odds with Node.js fetch Source: https://pinnodds.com/docs Node.js example using fetch to call /kit/v1/markets with sport_id=2 and event_type=live. Parses the JSON response to get events and last. ```javascript const res = await fetch( `${BASE}/kit/v1/markets?sport_id=2&event_type=live`, { headers: { "x-portal-apikey": KEY } } ); const { events, last } = await res.json(); ``` -------------------------------- ### Authenticate with API Key via Header or Query String Source: https://pinnodds.com/docs Examples of using the x-portal-apikey header or the key query parameter to authenticate requests. ```bash # Header (recommended) curl -H "x-portal-apikey: YOUR_KEY" \ "https://pinnodds.com/kit/v1/markets?sport_id=2&event_type=live" # Query string curl "https://pinnodds.com/kit/v1/markets?sport_id=2&event_type=live&key=YOUR_KEY" ``` -------------------------------- ### Fetch live odds with Go Source: https://pinnodds.com/docs Go example using net/http to call /kit/v1/markets with sport_id=2 and event_type=live. Sets the x-portal-apikey header and decodes the JSON response into a struct. ```go package main import ( "encoding/json" "net/http" ) req, _ := http.NewRequest("GET", BASE+"/kit/v1/markets?sport_id=2&event_type=live", nil) req.Header.Set("x-portal-apikey", KEY) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() var out struct { Events []map[string]interface{} `json:"events"`; Last int64 `json:"last"` } json.NewDecoder(resp.Body).Decode(&out) ``` -------------------------------- ### SSE Stream Framing Example Source: https://pinnodds.com/docs Example of the raw data format received over the SSE connection. ```text # Stream framing (what arrives over the wire) data: {"type": "connected", "id": "d648beb8-bde8-..."} data: [{"home": "Sunshine Coast Phoenix", "away": "Cairns Dolphins", "league": "Australia - NBL1 Women", "from_price": 2.86, "to_price": 2.7, "outcome": "Home", "period": 4, "sect": "Moneyline", "id": 1629729400, "sport": "Basketball", "interval": 25, "alerted": 1777625196, "sport_id": 3, "nvp": 3.04, "starts": 1777624200, ...}] ``` -------------------------------- ### GET /kit/v1/prematch/fixtures Source: https://pinnodds.com/docs Retrieves all prematch fixtures for a given sport, including current full markets and periods structure. Use this endpoint to get upcoming event lines. ```APIDOC ## GET /kit/v1/prematch/fixtures ### Description Retrieves all prematch fixtures for a given sport, including current full markets and periods structure. Mirrors the shape of /kit/v1/markets, only the event_type field differs. ### Method GET ### Endpoint /kit/v1/prematch/fixtures ### Parameters #### Query Parameters - **sport_id** (integer) - Required - Dropping-odds sport id. See Sport IDs. - **since** (integer) - Optional - Return only events that changed since this last value (incremental polling). - **include_specials** (1 | nested) - Optional - Include special-market events (Player Props, Team Props, Exact Scores, futures). 1 = flat extra rows linked by parent_id (delta-friendly); nested = grouped under each parent event's specials array (one row per match). Off by default. ### Request Example curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/prematch/fixtures?sport_id=1" ### Response #### Success Response (200) Same shape as /kit/v1/markets with event_type: "prematch" on each event. #### Response Example { "sport_id": 1, "sport_name": "Soccer", "last": 523864, "last_call": 523864, "events": [ { "event_id": 1629513753, "sport_id": 1, "league_id": 5488, "league_name": "Italy - Serie A", "home": "Cremonese", "away": "Lazio", "starts": "2026-05-04T16:30:00Z", "start_ts": "2026-05-04T16:30:00Z", "event_type": "prematch", "is_have_odds": true, "is_have_periods": true, "periods": { "num_0": { "number": 0, "description": "Game","."money_line": { "home": 2.45, "draw": 3.30, "away": 2.90 }, "spreads": { "-0.5": { "hdp": -0.5, "home": 2.06, "away": 1.82, "max": 500 } }, "totals": { "2.5": { "points": 2.5, "over": 1.90, "under": 1.98, "max": 500 } }, "team_total": { "home": { "points": 1.5, "over": 1.86, "under": 2.00 } }, "meta": { "number": 0, "max_total": 500, "home_score": 0, "away_score": 0 } } }, "status": "pending"". } ]". } ``` -------------------------------- ### Fetch live odds with Python requests Source: https://pinnodds.com/docs Python example using requests.get to call /kit/v1/markets with sport_id=2 and event_type=live. Sends the API key in headers and parses JSON. ```python import requests r = requests.get( f"{BASE}/kit/v1/markets", params={"sport_id": 2, "event_type": "live"}, headers={"x-portal-apikey": KEY}, ) data = r.json() ``` -------------------------------- ### GET /kit/v1/details Source: https://pinnodds.com/docs Fetch a single event by ID. Same event shape as /kit/v1/markets. ```APIDOC ## GET /kit/v1/details ### Description Fetch a single event by ID. Same event shape as `/kit/v1/markets`. ### Method GET ### Endpoint /kit/v1/details ### Parameters #### Query Parameters - **event_id** (integer) - Required - Arcadia matchup ID from a previous `/markets` response. ### Request Example ``` curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/details?event_id=1628594960" ``` ``` -------------------------------- ### GET /kit/v1/prematch/fixtures?include_specials=1 Source: https://pinnodds.com/docs Fetches prematch fixtures including special markets (player props, team props, exact scores, futures) as flat rows. Use include_specials=1 to opt in, as specials are excluded by default. ```APIDOC ## GET /kit/v1/prematch/fixtures?include_specials=1 ### Description Fetches prematch fixtures including special markets (player props, team props, exact scores, futures) as flat rows. Use include_specials=1 to opt in, as specials are excluded by default. ### Method GET ### Endpoint /kit/v1/prematch/fixtures?include_specials=1 ### Parameters #### Query Parameters - **include_specials** (string) - Required - Set to 1 for flat rows or nested for grouped under each parent event's specials array. - **sport_id** (integer) - Optional - Filter by sport ID. ### Request Example curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/prematch/fixtures?sport_id=1&include_specials=1" ### Response #### Success Response (200) - **events** (array) - List of event objects, including special rows with fields: event_id, home, away, parent_id, special, special_category, special_markets. #### Response Example { "events": [{ "event_id": 1632278803, "home": "Australia", "away": "Egypt", "parent_id": 1632164518, "special": "Mohamed Salah To Score", "special_category": "Player Props", "special_markets": { "num_0": [{ "type": "moneyline", "max_risk": 1000, "prices": [ { "name": "No", "price": 1.33 }, { "name": "Yes", "price": 3.43 } ] }] } }] } ``` -------------------------------- ### Prematch fixtures response example Source: https://pinnodds.com/docs Sample JSON response from /kit/v1/prematch/fixtures. Shows the envelope with sport_id, last, and events array. Each event includes periods with money_line, spreads, totals, and team_total. ```json # → 200 OK — same envelope as /kit/v1/markets, only event_type differs { "sport_id": 1, "sport_name": "Soccer", "last": 523864, "last_call": 523864, "events": [ { "event_id": 1629513753, "sport_id": 1, "league_id": 5488, "league_name": "Italy - Serie A", "home": "Cremonese", "away": "Lazio", "starts": "2026-05-04T16:30:00Z", "start_ts": "2026-05-04T16:30:00Z", // alias of starts (back-compat) "event_type": "prematch", "is_have_odds": true, "is_have_periods": true, "periods": { "num_0": { "number": 0, "description": "Game", "money_line": { "home": 2.45, "draw": 3.30, "away": 2.90 }, "spreads": { "-0.5": { "hdp": -0.5, "home": 2.06, "away": 1.82, "max": 500 } }, "totals": { "2.5": { "points": 2.5, "over": 1.90, "under": 1.98, "max": 500 } }, "team_total": { "home": { "points": 1.5, "over": 1.86, "under": 2.00 } }, "meta": { "number": 0, "max_total": 500, "home_score": 0, "away_score": 0 } } // num_1 (1st half), num_2 (2nd half), etc. when offered }, "status": "pending" } ] } ``` -------------------------------- ### Fetch live odds with PHP curl Source: https://pinnodds.com/docs PHP example using curl to call /kit/v1/markets with sport_id=2 and event_type=live. Sets the x-portal-apikey header and decodes the JSON response. ```php true, CURLOPT_HTTPHEADER => ["x-portal-apikey: $KEY"], ]); $body = curl_exec($ch); curl_close($ch); $data = json_decode($body, true); ``` -------------------------------- ### Response envelope for /kit/v1/markets Source: https://pinnodds.com/docs Example JSON response from /kit/v1/markets showing the envelope with sport_id, sport_name, last, last_call, and events array. Each event is described by the Event object. ```json { "sport_id": 2, "sport_name": "Tennis", "last": 141, "last_call": 141, "events": [ { /* see Event object below */ } ] } ``` -------------------------------- ### GET /kit/v1/prematch/fixtures Source: https://pinnodds.com/docs Retrieves prematch fixtures from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ```APIDOC ## GET /kit/v1/prematch/fixtures ### Description Retrieves prematch fixtures from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ### Method GET ### Endpoint /kit/v1/prematch/fixtures ### Authentication API key required. The key is your login; no username or password. ### Response JSON response containing prematch fixture data. ``` -------------------------------- ### GET /ping Source: https://pinnodds.com/docs Public liveness probe. Returns `ok` in plain text. Useful for load balancers and uptime monitors that can't send an auth header. ```APIDOC ## GET /ping ### Description Public liveness probe. Returns `ok` in plain text. Useful for load balancers and uptime monitors that can't send an auth header. ### Method GET ### Endpoint /ping ### Response #### Success Response (200) - **body** (string) - Plain text `ok` n #### Response Example ```ok ``` ``` -------------------------------- ### Server-sent message structures Source: https://pinnodds.com/docs Examples of message formats received from the server, including live MQTT updates, prematch REST poll responses, membership changes, and heartbeat pings. ```json // Live MQTT — `topic`, `op`, `rec` exactly as we received from Pinnacle. { "type": "live", "sport_id": 1, "topic": "matchups/reg/sp/29/live/ld", "op": "upd", "rec": { /* Pinnacle record verbatim */ }, "ts": 1779200000123 } // Prematch REST poll responses — `data` is the response array verbatim. { "type": "prematch_matchups", "sport_id": 1, "arcadia_sid": 29, "data": [ /* /sports/29/matchups response verbatim */ ], "ts": 1779200005000 } { "type": "prematch_markets", "sport_id": 1, "arcadia_sid": 29, "matchup_id": 1631005165, "data": [ /* /matchups/.../markets/related/straight verbatim */ ], "ts": 1779200005230 } // Membership delta — what JOINED or LEFT the prematch set this cycle. // MQTT never announces this: /pre carries prices for matchups you already // track, and is blind to the set itself. Measured over 10 min across all 13 // sports: 34 membership changes, 0 announced by MQTT. This frame is the only // timely signal — including when a matchup leaves prematch for warmup/live. { "type": "prematch_membership", "sport_id": 1, "arcadia_sid": 29, "added": [ 1634753718, 1634753879 ], "removed": [ 1634713508 ], "ts": 1779200005010 } // Heartbeat every 30s — reply with {"type":"pong"} or socket closes after ~75s. // buffered_max_bytes = the highest server-side send backlog for YOUR socket // since the previous ping, then reset. Steady-state 0 means you are draining // as fast as we send; a number that climbs across pings means your read loop // is falling behind, and at 128 MB you are evicted with // 1011 "deregistered: slow_consumer". Track it to see headroom, not just breaches. { "type": "ping", "ts": 1779200030000, "buffered_max_bytes": 0 } ``` -------------------------------- ### GET /odds-drop-prematch Source: https://pinnodds.com/docs Establishes an SSE connection to receive odds drops from the prematch feed. Requires an API key or token. Supports optional min_drop and recheck query parameters. ```APIDOC ## GET /odds-drop-prematch ### Description Establishes an SSE connection to receive odds drops from the prematch feed. Requires an API key or token. Supports optional min_drop and recheck query parameters. ### Method GET ### Endpoint https://pinnodds.com/odds-drop-prematch ### Authentication API key or token required. Pass as query parameter `key`. ### Parameters #### Query Parameters - **key** (string) - Required - API key or token for authentication. - **min_drop** (integer) - Optional - Overrides the default 5% drop threshold. Floor is 1%. - **recheck** (integer) - Optional - Number of seconds to hold each drop before re-checking the current Pinnacle price. If the price has bounced back, the drop is suppressed. Omit or pass 0 for instant feed. ### Request Example ``` curl -N "https://pinnodds.com/odds-drop-prematch?key=$API_KEY" ``` ### Response #### Success Response (200) SSE stream of events. Each event data is a JSON array of drop objects with fields: sport, home, from_price, to_price. If recheck is used, surviving alerts include a `rechecked_ms` field. #### Response Example ``` data: [{"sport":"NBA","home":"Lakers","from_price":1.85,"to_price":1.80}] ``` ### Error Handling - **Rate limited**: Reconnect loops get a single `{"type":"error","error":"rate_limited"}` frame with a `Retry-After: 60` header. Back off with exponential backoff. ### Notes - One connection per account. Live and prematch each count as one SSE slot, so you can run one of each in parallel under the default cap. - Prematch lines move slowly; expect < 1 drop/sec on a typical day. A 90-second sample may surface zero drops. - The `recheck` parameter is only available on this endpoint; it is silently ignored on `/odds-drop`. ``` -------------------------------- ### Go: Fetch drops and decode JSON Source: https://pinnodds.com/docs Builds a URL with query parameters, sends a GET request with the API key header, and decodes the JSON response into a struct. The struct includes fields for total and drops, with nested fields for home, market, from, to, and nvp. ```go q := url.Values{} q.Set("mode", "live"); q.Set("sport_id", "1") q.Set("min_drop_pct", "7"); q.Set("max_age_sec", "600") req, _ := http.NewRequest("GET", BASE+"/api/drops?"+q.Encode(), nil) req.Header.Set("x-portal-apikey", KEY) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() var out struct { Total int `json:"total"` Drops []struct { Home, Market string; From, To, NVP float64 } `json:"drops"` } json.NewDecoder(resp.Body).Decode(&out) ``` -------------------------------- ### Sample JSON response for a player prop market Source: https://pinnodds.com/docs Example JSON response from the markets endpoint for the 'Mohamed Salah To Score' special. Shows the event fields, special_category, and special_markets with a moneyline type, max_risk of 1000, and prices for 'No' (1.33) and 'Yes' (3.43). ```json { "events": [{ "event_id": 1632278803, "home": "Australia", "away": "Egypt", "parent_id": 1632164518, "special": "Mohamed Salah To Score", "special_category": "Player Props", "special_markets": { "num_0": [{ "type": "moneyline", "max_risk": 1000, "prices": [ { "name": "No", "price": 1.33 }, { "name": "Yes", "price": 3.43 } ] }] } }] } ``` -------------------------------- ### Connect to SSE with Go Source: https://pinnodds.com/docs Use net/http and bufio to process the SSE stream in Go. ```go package main import ( "bufio"; "encoding/json"; "net/http"; "strings"; "fmt" ) type Drop struct { Home, Sport string; FromPrice, ToPrice, NVP float64 } req, _ := http.NewRequest("GET", BASE+"/odds-drop?key="+API_KEY, nil) req.Header.Set("Accept", "text/event-stream") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024) for scanner.Scan() { line := scanner.Text() if !strings.HasPrefix(line, "data: ") { continue } body := strings.TrimPrefix(line, "data: ") var drops []Drop if err := json.Unmarshal([]byte(body), &drops); err != nil { continue } for _, d := range drops { if ev := d.ToPrice/d.NVP - 1; ev > 0.02 { fmt.Println("+EV", d.Sport, d.Home, d.FromPrice, "→", d.ToPrice) } } } ``` -------------------------------- ### Connect to Prematch Feed via Go Source: https://pinnodds.com/docs Integration using standard library HTTP requests and bufio scanner. ```go req, _ := http.NewRequest("GET", BASE+"/odds-drop-prematch?key="+API_KEY, nil) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024) for scanner.Scan() { line := scanner.Text() if !strings.HasPrefix(line, "data: ") { continue } // parse JSON array of drops, same shape as /odds-drop } ``` -------------------------------- ### GET /health response JSON Source: https://pinnodds.com/docs Example JSON response from the GET /health endpoint. The top-level fields describe the live feed; the nested 'prematch' object describes the prematch feed. Use 'live_write_age_ms' and 'prematch.write_age_ms' for freshness alerts. 'prematch.status: "unreachable"' means the health check could not reach the prematch service, treat as unknown. ```json { "status": "healthy", // healthy | degraded — LIVE feed only "degraded_reason": null, "live_write_age_ms": 546, // ms since the last live write "source": "ws", // ws | rest | none "events_in_store": 145, "version": 50352678, // same cursor as /kit `last` "ws_messages": 1768510, "rest_polls": 149010, "uptime_s": 138836, "prematch": { "enabled": true, "status": "healthy", // healthy | degraded | unreachable "degraded_reason": null, "events_in_store": 15891, "write_age_ms": 71, // ms since the last prematch write "version": 50352723, "source": "ws", "rest_polls": 104828, "checked_age_ms": 1204 // age of this prematch reading } } ``` -------------------------------- ### Connect to Prematch Feed via Python Source: https://pinnodds.com/docs Integration using the requests and sseclient libraries. ```python import json, requests from sseclient import SSEClient resp = requests.get(f"{BASE}/odds-drop-prematch?key={API_KEY}", stream=True) for ev in SSEClient(resp).events(): p = json.loads(ev.data) if ev.data else None if isinstance(p, list): for d in p: print(d["sport"], d["home"], d["from_price"], "→", d["to_price"]) ``` -------------------------------- ### Event object JSON example Source: https://pinnodds.com/docs Example of a full event object from the Pinnacle odds API. Shows nested periods, state, and special-market fields. Note the comment on 'last' indicating it is serve time, not last update. ```json { "event_id": 1628594960, "sport_id": 1, "league_id": 2037, "league_name": "China - Super League", "starts": "2026-04-17T12:00:00Z", "last": 1776430365, // serve time, NOT last update — see below "home": "Yunnan Yukun", "away": "Tianjin Jinmen Tiger", "event_type": "live", "live_status_id": 1, "parent_id": 1628594613, "is_have_odds": true, "is_have_periods": true, "periods": { "num_0": { "number": 0, "description": "Game", "money_line": { "home": 2.450, "draw": 3.300, "away": 2.900 }, "spreads": { "-0.5": { "hdp": -0.5, "home": 2.060, "away": 1.820, "max": 500 } }, "totals": { "2.5": { "points": 2.5, "over": 1.900, "under": 1.980, "max": 500 } }, "team_total": { "home": { "points": 1.5, "over": 1.860, "under": 2.000 } }, "team_totals": { "home": { "0.5": { "points": 0.5, "over": 1.200, "under": 4.500, "max": 100 }, "1.5": { "points": 1.5, "over": 1.860, "under": 2.000, "max": 100 }, "2.5": { "points": 2.5, "over": 3.200, "under": 1.400, "max": 100 } }, "away": { /* same shape */ } }, "meta": { "number": 0, "max_total": 500, "home_score": 0, "away_score": 1 } }, "num_1": { /* first half */ } }, "state": { "match": { "state": 1, "minutes": 23 }, "home": { "score": 1, "redCards": 0 }, "away": { "score": 0, "redCards": 0 }, "home_stats": [{ "period": 0 }, { "period": 1 }], "away_stats": [{ "period": 0 }, { "period": 1 }] } } ``` -------------------------------- ### GET /ping Source: https://pinnodds.com/docs Ping endpoint to check connectivity and latency. ```APIDOC ## GET /ping ### Description Ping endpoint to check connectivity and latency. ### Method GET ### Endpoint /ping ### Authentication API key required. The key is your login; no username or password. ### Response JSON response with ping status. ``` -------------------------------- ### GET /health Source: https://pinnodds.com/docs Health check endpoint to verify the API is operational. ```APIDOC ## GET /health ### Description Health check endpoint to verify the API is operational. ### Method GET ### Endpoint /health ### Authentication API key required. The key is your login; no username or password. ### Response JSON response indicating service health status. ``` -------------------------------- ### curl: Query live and prematch drops Source: https://pinnodds.com/docs Two curl commands to query the /api/drops endpoint. The first fetches live soccer drops with a minimum drop of 7% within the last 10 minutes. The second fetches prematch drops across all sports with a minimum drop of 2% within the last hour. Both require an API key in the x-portal-apikey header. ```bash # Live drops, soccer only, ≥7%, last 10 min curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/api/drops?mode=live&sport_id=1&min_drop_pct=7&max_age_sec=600" # Prematch drops, all sports, last hour curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/api/drops?mode=prematch&min_drop_pct=2&max_age_sec=3600" ``` -------------------------------- ### wscat CLI subscription to Pinnodds WebSocket feed Source: https://pinnodds.com/docs Quick CLI client for ad-hoc inspection. Install wscat with 'npm i -g wscat', connect using the API key, then paste the subscribe frame at the prompt to subscribe to the 'live' stream for sport IDs 1 and 2. ```bash # npm i -g wscat — quick CLI client for ad-hoc inspection wscat -c "wss://pinnodds.com/ws/feed?key=$API_KEY" # then paste a subscribe frame at the prompt: {"type":"subscribe","streams":["live"],"sport_ids":[1,2]} ``` -------------------------------- ### Apply recheck Filter via EventSource Source: https://pinnodds.com/docs Example of appending the recheck parameter to the EventSource URL. ```javascript // EventSource (Node.js / browser) const es = new EventSource(`${BASE}/odds-drop-prematch?key=${API_KEY}&recheck=30`); ``` -------------------------------- ### Connect to SSE with Python Source: https://pinnodds.com/docs Use sseclient-py and requests to handle the SSE stream in Python. ```python # pip install sseclient-py requests import json, requests from sseclient import SSEClient resp = requests.get(f"{BASE}/odds-drop?key={API_KEY}", stream=True) for ev in SSEClient(resp).events(): if not ev.data: continue payload = json.loads(ev.data) if isinstance(payload, dict) and payload.get("type") in ("connected", "error"): continue for drop in payload: ev_pct = (drop["to_price"] / drop["nvp"]) - 1 if ev_pct > 0.02: print("+EV", drop["sport"], drop["home"], drop["from_price"], "→", drop["to_price"]) ``` -------------------------------- ### GET /api/drops Source: https://pinnodds.com/docs Retrieves dropping odds data. This endpoint is part of the dropping odds service, which is a $99/mo add-on. ```APIDOC ## GET /api/drops ### Description Retrieves dropping odds data. This endpoint is part of the dropping odds service, which is a $99/mo add-on. ### Method GET ### Endpoint /api/drops ### Authentication API key required. The key is your login; no username or password. ### Response JSON response containing dropping odds data. ``` -------------------------------- ### GET /kit/v1/prematch/markets?event_id={event_id} Source: https://pinnodds.com/docs Fetches prices for a single special market by passing its event_id. No include_specials flag is needed for this endpoint. ```APIDOC ## GET /kit/v1/prematch/markets?event_id={event_id} ### Description Fetches prices for a single special market by passing its event_id. No include_specials flag is needed for this endpoint. ### Method GET ### Endpoint /kit/v1/prematch/markets?event_id={event_id} ### Parameters #### Query Parameters - **event_id** (integer) - Required - The event ID of the special market. ### Request Example curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/prematch/markets?event_id=1632278803" ### Response #### Success Response (200) - **events** (array) - List of event objects containing the special market details. #### Response Example { "events": [{ "event_id": 1632278803, "home": "Australia", "away": "Egypt", "parent_id": 1632164518, "special": "Mohamed Salah To Score", "special_category": "Player Props", "special_markets": { "num_0": [{ "type": "moneyline", "max_risk": 1000, "prices": [ { "name": "No", "price": 1.33 }, { "name": "Yes", "price": 3.43 } ] }] } }] } ``` -------------------------------- ### Fetch event details with curl Source: https://pinnodds.com/docs Use this curl command to call /kit/v1/details with an event_id. Requires an API key sent via the x-portal-apikey header. ```bash curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/details?event_id=1628594960" ``` -------------------------------- ### Fetch specials with include_specials=1 Source: https://pinnodds.com/docs Curl command to fetch prematch fixtures with specials included as flat rows. Requires an API key passed via the x-portal-apikey header. The response includes rows with parent_id 1632164518 for the Australia vs Egypt match, listing specials like 'Anytime Goalscorer' and 'Mohamed Salah To Score'. ```bash curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/prematch/fixtures?sport_id=1&include_specials=1" # → rows with parent_id 1632164518 include: # 1632190502 "Anytime Goalscorer" (Player Props) # 1632190468 "First Goalscorer" (Player Props) # 1632278803 "Mohamed Salah To Score" (Player Props) # 1632181240 "Winning Margin" (Team Props) … ~50 more ``` -------------------------------- ### GET /kit/v1/markets Source: https://pinnodds.com/docs Retrieves live odds markets from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ```APIDOC ## GET /kit/v1/markets ### Description Retrieves live odds markets from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ### Method GET ### Endpoint /kit/v1/markets ### Authentication API key required. The key is your login; no username or password. ### Response JSON response containing live odds market data. ``` -------------------------------- ### Fetch live odds with curl Source: https://pinnodds.com/docs Use this curl command to call /kit/v1/markets with sport_id=2 and event_type=live. Requires an API key sent via the x-portal-apikey header. ```bash curl -H "x-portal-apikey: $KEY" \ "https://pinnodds.com/kit/v1/markets?sport_id=2&event_type=live" ``` -------------------------------- ### Connect to SSE with Node.js Source: https://pinnodds.com/docs Use the eventsource package to consume the SSE stream in Node.js. ```javascript // npm i eventsource import EventSource from "eventsource"; const es = new EventSource(`${BASE}/odds-drop?key=${API_KEY}`); es.onmessage = (e) => { const payload = JSON.parse(e.data); if (payload.type === "connected") return; if (payload.type === "error") { console.error(payload.error, payload.message); return; } for (const drop of payload) { const ev = (drop.to_price / drop.nvp) - 1; if (ev > 0.02) console.log("+EV", drop.sport, drop.home, drop.from_price, "→", drop.to_price); } }; es.onerror = (err) => console.error("sse closed", err); ``` -------------------------------- ### GET /kit/v1/prematch/lines Source: https://pinnodds.com/docs Retrieves prematch odds lines from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ```APIDOC ## GET /kit/v1/prematch/lines ### Description Retrieves prematch odds lines from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ### Method GET ### Endpoint /kit/v1/prematch/lines ### Authentication API key required. The key is your login; no username or password. ### Response JSON response containing prematch odds line data. ``` -------------------------------- ### GET /kit/v1/prematch/markets Source: https://pinnodds.com/docs Retrieves prematch odds markets from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ```APIDOC ## GET /kit/v1/prematch/markets ### Description Retrieves prematch odds markets from Pinnacle. This endpoint is part of the /kit/v1/* group that mirrors common third-party Pinnacle API formats. ### Method GET ### Endpoint /kit/v1/prematch/markets ### Authentication API key required. The key is your login; no username or password. ### Response JSON response containing prematch odds market data. ```