On the wire · 04:58:29 UTC Live 568 · Prematch 14,378 · Markets 56,862 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Réponse · Python · pandas

Cotes Pinnacle dans un DataFrame pandas

Mis à jour le · PinnFeed · 2 min de lecture

Réponse : appelez GET /v1/odds puis parcourez événements → marchés → issues pour construire une ligne par issue. Vous obtenez un DataFrame propre avec decimal, fair, fairProb, margin et maxStake pour chaque prix, prêt pour groupby, Parquet ou un notebook. Fonctionne sur tous les plans ; sur Free, les données ont 30 secondes de retard.

Code#

# 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)

Étapes suivantes#

  • Marchés avec volume : df[df.max_stake >= 100].
  • Plus de 200 événements : paginez avec offset (doc REST).
  • Cotes de clôture pour le CLV sur Builder : /v1/closing/{id}.
  • Changements en direct sans polling : client WebSocket.

Offres#

Free (0 €) : 30 s de retard, 2 sports, marchés principaux, 1 000 requêtes par jour. Hobby (29 €/mois) : REST en temps réel. Builder (99 €/mois) : WebSocket, tous les marchés et historique des clôtures. Essai de 3 jours ; carte requise, débitée après le jour 3 sauf résiliation.

Contenu éducatif pour adultes (18+) : ni pronostics ni promesse de gain. En France, seuls les opérateurs agréés par l'ANJ peuvent proposer des paris en ligne.

Questions fréquentes#

Pourquoi une ligne par issue ?#

Chaque prix tient dans une colonne, ce qui simplifie filtres, pivots et jointures. Une ligne par marché : df.pivot_table(index=["event_id","market","line"], columns="outcome", values="decimal").

Cela marche-t-il dans Jupyter ou Colab ?#

Oui. Définissez la clé avec os.environ["PINNFEED_KEY"] = "ps_live_..." dans une cellule que vous ne partagez pas.

Existe-t-il une version polars ?#

Passez la même liste rows à polars.DataFrame(rows).

Le plan WebSocket : Builder, 99 €/mois.

Les cotes Pinnacle en temps réel sur un seul WebSocket : les 13 sports, tous les marchés, cotes justes sans marge et cotes de clôture. 3 jours gratuits, résiliable en 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.