pnclENGINEObter acesso à API

RUNBOOK DE ERROS

Um runbook para erros da API da Pinnacle.

Cada status que a API de odds da Pinnacle devolve pede uma reação diferente de um poller. Este runbook os separa em parar, esperar e repetir, dá a regra de espera de cada um e diz quais devem acordar uma pessoa. As regras são as mesmas na chave gratuita e nos planos REST pagos.

Quatro classes de resposta

Um poller só precisa de quatro reações. A tabela mapeia cada status para uma delas; tudo o que vem depois explica o tempo.

RespostaO que significaReação
401Sem chave, ou uma chave que a API não reconheceParar e alertar uma pessoa
403A chave é conhecida, mas o plano não cobre esta chamadaParar e verificar o plano
429A cota por segundo ou diária acabouEsperar o Retry-After e retomar
5xx, timeout, resetO serviço ou a rede falhou por enquantoRepetir com backoff limitado
200 com um corpo inesperadoUma resposta que não é o envelope documentadoTratar como falha; manter o último snapshot

Erros de parada: 401 e 403

Nenhum dos dois melhora com o tempo, então repeti-los em loop só acrescenta ruído aos logs e, em uma conta compartilhada, ao lado do fornecedor. Um 401 significa que a requisição não trazia uma chave utilizável: o header está faltando, a variável de ambiente está vazia neste deploy, ou a chave foi rotacionada. Verifique se o poller envia a chave no header x-portal-apikey e se o valor bate com o painel da conta.

Um 403 é mais sutil: a autenticação funcionou, mas o plano não inclui o que foi pedido. Uma chave válida ainda pode não ter um transporte, um complemento ou um endpoint, e a correção está na conta, não no código. O checklist de acesso no pnclODDS separa autenticação de direito de uso passo a passo. Nos dois casos, registre o status e o código de erro, nunca a chave nem o corpo completo da resposta, e acione quem cuida da conta.

Erros de espera: 429

Um 429 diz que a programação cruzou o teto: 20 requisições por minuto ou 100 por dia na chave gratuita, 10 ou 30 por segundo nos planos REST pagos. O header Retry-After é a autoridade sobre quanto esperar. Respeite-o, adicione um pouco de jitter para que workers paralelos não retomem em sincronia, e compartilhe o estado do backoff entre os workers, já que dez processos educados ainda somam dez vezes as requisições. A página de limites de taxa tem o loop de backoff e a regra de folga que mantém os 429 raros.

HTTP/1.1 429 Too Many Requests
Retry-After: 2

Um 429 na cota diária da chave gratuita é de outra natureza: nenhum backoff traz o dia de volta. Detecte-o pelo tamanho do Retry-After e pare o poller até a janela reiniciar, em vez de queimar a próxima hora em chamadas rejeitadas.

Erros de repetição: 5xx, timeouts e resets

Estes são transitórios até prova em contrário. Repita com um atraso que começa em meio segundo, dobra a cada vez e para em 30 segundos, e desista depois de três tentativas em um ciclo de polling. Falhar o ciclo não é problema: o próximo polling agendado roda de qualquer forma, e um snapshot dez segundos atrasado é melhor do que um poller preso em um loop de retentativas. Continue servindo o último snapshot bom aos seus próprios consumidores, com a idade dele visível, para que um dashboard mostre preços desatualizados em vez de nenhum.

def poll_once():
    delay = 0.5
    for attempt in range(3):
        try:
            res = get(url, timeout=8)
        except (Timeout, ConnectionError):
            sleep(delay + random() * delay / 2)
            delay = min(delay * 2, 30)
            continue
        if res.status in (401, 403):
            raise Stop(res.status)
        if res.status == 429:
            sleep(float(res.headers.get("Retry-After", delay)))
            continue
        if res.status >= 500:
            sleep(delay + random() * delay / 2)
            delay = min(delay * 2, 30)
            continue
        return validate(res.json())
    return None  # this cycle failed; the next one runs

Valide o 200

Um status de sucesso é o começo da verificação, não o fim. A resposta de mercados é um objeto com um array events e um cursor last; exija os dois antes de tocar no payload. Um array vazio em uma hora tranquila é uma resposta válida e não deve ser registrado como erro, enquanto um corpo sem o cursor está malformado e não deve substituir o snapshot que você já tem. Nunca preencha um preço ausente com zero: uma money line nula significa que o mercado está fechado ou indisponível, e zero pareceria um preço para tudo o que vem depois.

O que deve acionar uma pessoa

Quatro condições justificam acordar alguém; o resto pertence a um dashboard. Um 401 ou 403 a qualquer momento, porque o poller não consegue se recuperar sozinho. Mais de um 429 a cada cem requisições durante uma hora, porque a programação está perto demais do teto. Uma sequência de 5xx ou timeouts por mais de cinco minutos, porque uma falha transitória deixou de ser transitória. E um snapshot mais velho que três intervalos de polling em qualquer quadro durante uma grade, que é o sintoma que os outros três causam. A página de monitoramento transforma isso em métricas com limiares.

Obter acesso à API

Perguntas da escala de plantão

Um 429 deve ser repetido imediatamente alguma vez?

Não. Mesmo sem um header Retry-After, espere pelo menos o atraso base. Uma retentativa imediata cai dentro da mesma janela e prolonga o bloqueio.

Um 403 é sempre um problema de plano?

Nesta API quase sempre é: a chave foi aceita e a requisição foi recusada. Compare o endpoint e o transporte que você chamou com os direitos do plano antes de mudar qualquer código.

Quantas tentativas por ciclo é demais?

Mais de três. Cada tentativa extra gasta orçamento em uma chamada que provavelmente vai falhar de novo, e o próximo ciclo está a segundos de distância. Falhe rápido e deixe a programação se recuperar.

Os significados dos status e as cotas seguem a documentação publicada pelo fornecedor, conferida em 26 de setembro de 2026. Publicado em .