On the wire · 04:46:15 UTC Live 550 · Prematch 14,363 · Markets 56,879 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Resposta · Python · WebSocket

WebSocket de odds da Pinnacle: exemplo em Python

Atualizado em · PinnFeed · 2 min de leitura

Resposta: instale websockets, defina PINNFEED_KEY, conecte em wss://pinnfeed.io/v1/stream com o header x-api-key, envie uma mensagem subscribe, aplique cada snapshot/delta, responda ao ping com {"type":"pong"} e reconecte com backoff exponencial. Você precisa do plano Builder (€99/mês): chaves Free e Hobby recebem 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 pronto")
                        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, "nova tentativa em", delay, "s")
        await asyncio.sleep(delay + random.random())
        delay = min(delay * 2, 30)

asyncio.run(main())

Campos de cada resultado: decimal, american, fair (sem margem), fairProb. O id do mercado é eventId:key. O filtro maxStake >= 100 descarta mercados com pouca liquidez. Lista completa de frames: docs do WebSocket.

Códigos de fechamento#

CódigoSignificado
4002 no_subscriptionNenhum subscribe em 30 s
4008 slow_consumerCliente lento demais (buffer do servidor acima de 16 MB)
4001 key_revokedChave revogada: não reconecte em loop

Builder: teste de 3 dias em preços; é preciso cartão, cobrado após o dia 3 se você não cancelar. Ou comece com uma chave REST grátis. Veja também push ou polling e bootstrap de conta em Python.

Conteúdo educativo para maiores de 18 anos: documentação técnica, não palpites nem promessa de lucro.

Perguntas frequentes#

Por que minha chave Free recebe 403 no WebSocket?#

Free e Hobby são só REST. Passe para o Builder para ter push, ou consulte /v1/odds no Free (30 s de atraso) ou Hobby (tempo real).

Preciso responder aos ping?#

Sim. O servidor envia ping a cada 20 segundos; sem pong por 60 s, a conexão é encerrada.

Quantas conexões?#

O Builder permite 3 simultâneas e o Pro 10. Acima disso: 429 connection_limit.

O plano WebSocket: Builder, €99/mês.

Odds da Pinnacle em tempo real por um único WebSocket: os 13 esportes, todos os mercados, odds justas sem margem e odds de fechamento. 3 dias grátis, cancele com um clique.

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.