WebSocket de cuotas Pinnacle: ejemplo en Python
Respuesta: instala websockets, define PINNFEED_KEY, conéctate a wss://pinnfeed.io/v1/stream con la cabecera x-api-key, envía un mensaje subscribe, aplica cada snapshot/delta, responde a ping con {"type":"pong"} y reconecta con backoff exponencial. Necesitas el plan Builder (€99/mes): las claves Free y Hobby reciben 403 plan_lacks_ws.
Cliente mínimo#
pip install websockets
export PINNFEED_KEY="ps_live_..."
import asyncio, json, os, random
import websockets
WS = "wss://pinnfeed.io/v1/stream"
KEY = os.environ["PINNFEED_KEY"]
async def main():
delay = 1
while True:
try:
async with websockets.connect(WS, additional_headers={"x-api-key": KEY}, max_size=None) as ws:
await ws.send(json.dumps({
"type": "subscribe",
"sports": ["soccer", "tennis"],
"markets": ["moneyline"],
"main": True,
"specials": False,
}))
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "ping":
await ws.send('{"type":"pong"}')
elif msg["type"] == "snapshot" and msg.get("final"):
print("snapshot listo")
delay = 1
elif msg["type"] == "delta":
for c in msg["changes"]:
if c["kind"] == "market" and c["op"] == "upsert":
m = c["market"]
if (m["maxStake"] or 0) >= 100:
print(m["id"], [(o["name"], o["decimal"], o["fair"]) for o in m["outcomes"]])
except (OSError, websockets.ConnectionClosed) as e:
print("desconectado", e, "reintento en", delay, "s")
await asyncio.sleep(delay + random.random())
delay = min(delay * 2, 30)
asyncio.run(main())
Campos de cada resultado: decimal, american, fair (sin margen), fairProb. El id de mercado es eventId:key. El filtro maxStake >= 100 descarta mercados con poca liquidez. Lista completa de frames: docs del WebSocket.
Códigos de cierre#
| Código | Significado |
|---|---|
4002 no_subscription | Ningún subscribe en 30 s |
4008 slow_consumer | Cliente demasiado lento (búfer del servidor por encima de 16 MB) |
4001 key_revoked | Clave revocada: no reconectes en bucle |
Builder: prueba de 3 días desde precios; se requiere tarjeta y se cobra después del día 3 salvo que canceles. O empieza con una clave REST gratuita. Ver también push o polling y arranque de cuenta en Python.
Contenido educativo para mayores de 18 años: documentación técnica, no pronósticos ni promesas de ganancia.
Preguntas frecuentes#
¿Por qué mi clave Free recibe 403 en el WebSocket?#
Free y Hobby son solo REST. Pasa a Builder para el push, o consulta /v1/odds en Free (30 s de retraso) u Hobby (tiempo real).
¿Tengo que responder a los ping?#
Sí. El servidor envía ping cada 20 segundos; sin pong durante 60 s, corta la conexión.
¿Cuántas conexiones?#
Builder permite 3 simultáneas y Pro 10. Por encima: 429 connection_limit.