On the wire · 04:48:13 UTC Live 550 · Prematch 14,373 · Markets 57,037 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Tutorial · Python · FastAPI

Proxy de cuotas Pinnacle con FastAPI

Actualizado el · PinnFeed · 1 min de lectura

Respuesta: ejecute una pequeña app FastAPI que lea PINNFEED_KEY del entorno, llame /v1/odds con httpx, cachee el resultado unos segundos y devuelva solo los campos útiles. El navegador habla con su API; la clave no sale del servidor.

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

Ejecute con pip install fastapi uvicorn httpx y uvicorn app:app --port 8000, luego /odds/soccer?q=arsenal.

CTA#

Builder (€99/mes). Prueba de 3 días; tarjeta requerida. REST gratis: signup. Otros hosts: Cloudflare Worker, Supabase. Relacionado: JS navegador / CORS.

Preguntas frecuentes#

¿Por qué no llamar PinnFeed desde JavaScript?#

CORS lo permite, pero la clave sería pública: JS navegador y CORS.

¿La caché deja cuotas viejas?#

Hasta TTL segundos. 1–5 s para prematch; WebSocket para live.

¿Puedo usar Flask?#

Sí; mismo patrón con requests y un dict cache.

Contenido educativo para mayores de 18 años. Sin pronósticos ni ganancias garantizadas. En España, apuesta solo con operadores con licencia de la DGOJ.

El plan WebSocket: Builder, 99 €/mes.

Cuotas de Pinnacle en tiempo real por un único WebSocket: los 13 deportes, todos los mercados, cuotas justas sin margen y cuotas de cierre. 3 días gratis y cancelas 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.