On the wire · 04:56:04 UTC Live 556 · Prematch 14,383 · Markets 56,966 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Risposta · Python · pandas

Quote Pinnacle in un DataFrame pandas

Aggiornato il · PinnFeed · 1 min di lettura

Risposta: chiama GET /v1/odds e scorri eventi → mercati → esiti per costruire una riga per esito. Ottieni un DataFrame ordinato con decimal, fair, fairProb, margin e maxStake per ogni prezzo, pronto per groupby, Parquet o un notebook. Funziona su tutti i piani; su Free i dati hanno 30 secondi di ritardo.

Codice#

# pip install requests pandas
import os, requests, pandas as pd

r = requests.get(
    "https://pinnfeed.io/v1/odds",
    headers={"x-api-key": os.environ["PINNFEED_KEY"]},  # ps_live_...
    params={"sport": "soccer", "main": "true", "limit": 200},
    timeout=20,
)
r.raise_for_status()

rows = []
for ev in r.json()["events"]:
    for m in ev.get("markets", []):
        for o in m.get("outcomes", []):
            rows.append({
                "event_id": ev["id"], "start": ev.get("startTime"), "live": ev.get("live"),
                "league": (ev.get("league") or {}).get("name"),
                "home": ev.get("home"), "away": ev.get("away"),
                "market": m.get("type"), "period": m.get("period"), "line": m.get("line"),
                "margin": m.get("margin"), "max_stake": m.get("maxStake"),
                "outcome": o.get("name"), "decimal": o.get("decimal"),
                "fair": o.get("fair"), "fair_prob": o.get("fairProb"),
            })

df = pd.DataFrame(rows)
df["start"] = pd.to_datetime(df["start"], utc=True)
print(df.groupby("market")["margin"].describe())
df.to_csv("pinnacle_soccer.csv", index=False)

Passi successivi#

  • Mercati con volume: df[df.max_stake >= 100].
  • Oltre 200 eventi: pagina con offset (documentazione REST).
  • Quote di chiusura per il CLV su Builder: /v1/closing/{id}.
  • Variazioni live senza polling: client WebSocket.

Piani#

Free (0 €): 30 s di ritardo, 2 sport, mercati principali, 1.000 richieste al giorno. Hobby (29 €/mese): REST in tempo reale. Builder (99 €/mese): WebSocket, tutti i mercati e storico delle chiusure. Prova di 3 giorni; carta richiesta, addebito dopo il giorno 3 salvo disdetta.

Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.

Domande frequenti#

Perché una riga per esito?#

Ogni prezzo sta in una colonna, così filtri, pivot e join restano semplici. Una riga per mercato: df.pivot_table(index=["event_id","market","line"], columns="outcome", values="decimal").

Funziona in Jupyter o Colab?#

Sì. Imposta la chiave con os.environ["PINNFEED_KEY"] = "ps_live_..." in una cella che non condividi.

Esiste una versione polars?#

Passa la stessa lista rows a polars.DataFrame(rows).

Il piano WebSocket: Builder, 99 €/mese.

Quote Pinnacle in tempo reale su un unico WebSocket: tutti i 13 sport, tutti i mercati, quote eque senza margine e quote di chiusura. 3 giorni gratis, disdici con un clic.

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.