On the wire · 04:48:47 UTC Live 550 · Prematch 14,382 · Markets 56,970 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Tutoriel · Python · FastAPI

Proxy de cotes Pinnacle avec FastAPI

Mis à jour le · PinnFeed · 2 min de lecture

Réponse : lancez une petite app FastAPI qui lit PINNFEED_KEY depuis l'environnement, appelle /v1/odds avec httpx, met le résultat en cache quelques secondes et ne renvoie que les champs utiles. Le navigateur parle à votre API ; la clé ne quitte pas le serveur, et le cache garde beaucoup de visiteurs dans votre rate limit.

app.py#

import os, time
import httpx
from fastapi import FastAPI, HTTPException

KEY = os.environ["PINNFEED_KEY"]            # ps_live_...
API = "https://pinnfeed.io/v1"
TTL = 5                                     # seconds
cache: dict[str, tuple[float, list]] = {}
app = FastAPI()
client = httpx.AsyncClient(headers={"x-api-key": KEY}, timeout=10)

@app.get("/odds/{sport}")
async def odds(sport: str, q: str | None = None):
    ck = f"{sport}|{q}"
    hit = cache.get(ck)
    if hit and time.time() - hit[0] < TTL:
        return hit[1]
    params = {"sport": sport, "market": "moneyline", "main": "true", "limit": 100}
    if q:
        params["q"] = q
    r = await client.get(f"{API}/odds", params=params)
    if r.status_code != 200:
        raise HTTPException(r.status_code, r.json().get("error", {}).get("message", "upstream error"))
    rows = [
        {"id": e["id"], "home": e["home"], "away": e["away"], "start": e["startTime"], "live": e["live"],
         "prices": {o["name"]: o["decimal"] for m in e["markets"] for o in m["outcomes"]},
         "maxStake": max((m["maxStake"] or 0) for m in e["markets"]) if e["markets"] else None}
        for e in r.json()["events"]
    ]
    cache[ck] = (time.time(), rows)
    return rows

Lancez avec pip install fastapi uvicorn httpx puis uvicorn app:app --port 8000, et appelez /odds/soccer?q=arsenal.

Notes prod#

  • Ajoutez votre auth ou un rate limit sur le proxy s'il est public.
  • Respectez 429 avec Retry-After de PinnFeed ; plans : 1 (Free), 2 (Hobby), 10 (Builder) ou 30 (Pro) req/s.
  • Pour les tableaux live, un WebSocket serveur (Builder) et fan-out : WebSocket Python.

CTA#

Builder (99 €/mois). Essai 3 jours ; carte requise. REST gratuit : inscription. Autres hôtes : Cloudflare Worker, Supabase. Lié : JS navigateur / CORS.

Questions fréquentes#

Pourquoi ne pas appeler PinnFeed depuis JavaScript ?#

CORS le permet, mais la clé serait publique : JS navigateur et CORS.

Le cache rend-il les cotes périmées ?#

Jusqu'à TTL secondes. 1–5 s pour le prematch ; WebSocket pour le live.

Puis-je utiliser Flask ?#

Oui ; même motif avec requests et un dict cache.

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.

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.