Skip to main content

Dois envelopes

A Tryno tem duas superfícies (veja a diferença) e elas respondem erros em formatos diferentes. Isto não é um acidente que vai ser “corrigido” — é a fronteira entre o contrato público e a API interna.

Platform API v1

Envelope tipado:

API da aplicação

Envelope plano, só com um código:
Ramifique sempre no type (ou no código), nunca no message. A mensagem é escrita para humanos, está em inglês e pode mudar sem aviso; o type é o contrato.

Status em /api/v1

Estes quatro são os únicos error.type que /v1 emite hoje. Ainda assim, escreva o seu cliente com um ramo default — um type novo pode aparecer, e tratar desconhecido como “erro não recuperável” é mais seguro do que estourar. O 401 é deliberadamente indistinguível entre “chave inexistente” e “chave revogada”: informar a diferença ajudaria apenas quem está sondando chaves. O 404 também cobre o caso “existe, mas em outra tribo” — uma chave nunca confirma a existência de dados de outra tribo. Hoje ele só aparece em GET /v1/members/{username}; as listas devolvem data: [], e lista vazia não é erro.
A ordem da checagem importa. A autenticação roda antes do limite de taxa, e o limite de taxa antes da checagem de escopo. Então uma chave inválida sempre recebe 401 (nunca 429), e uma chave válida sem escopo recebe 429 antes de 403 se estiver estourando o teto.

Códigos da API da aplicação

Os endpoints de administração (criar chave, registrar webhook) usam o envelope plano:
Repare que no_scopes e no_events também aparecem quando você enviou valores, mas todos eram inválidos: escopos e eventos desconhecidos são filtrados em silêncio antes da validação. Um 400 no_events costuma ser um typo no nome do evento, não uma lista vazia.

Limites de uso

A Platform API permite 120 requisições por minuto por chave.
Resposta ao estourar
Retry-After é o único cabeçalho de limite que a Tryno envia, e ele só aparece na resposta 429, sempre com o valor 60. Não existem X-RateLimit-Limit, X-RateLimit-Remaining nem X-RateLimit-Reset: você não consegue saber quanto do orçamento já gastou antes de estourar. Se o seu cliente depende de ler o saldo restante, ele precisa contar do próprio lado.
O limite é por chave, não por IP: uma chave vazada não pode ser usada em paralelo de vários lugares sem bater no teto. É também por isso que vale ter uma chave por integração — uma automação em laço não derruba as outras.

Como a janela funciona

É uma janela fixa de 60 segundos, não deslizante: o contador zera de uma vez quando a janela expira. Consequência prática: 120 chamadas no segundo 59 e mais 120 no segundo 61 passam as duas — 240 chamadas em dois segundos. E o inverso também vale: se você gastou o orçamento no início da janela, espera até 60s pela liberação, mesmo que o Retry-After sugira exatamente isso.
O contador é mantido por instância do worker e é best-effort: sob tráfego distribuído por vários pontos de presença, o teto efetivo pode ficar acima de 120/min. Trate 120/min como a garantia mínima que você tem, não como um número em que dá para encostar de propósito. Há também proteção no WAF acima disso, que não é configurável por chave.
Como não chegar perto do teto: use pageSize=100 em vez de páginas pequenas (8× menos requisições para varrer a mesma lista), cacheie o que muda pouco, e prefira webhooks a varreduras periódicas. A maior fonte de 429 é código que relê a lista inteira só para descobrir o que mudou.

Retentativa com backoff exponencial e jitter

Este é o cliente mínimo correto: repete 429 e 5xx, respeita o Retry-After quando ele existe, aplica jitter para não sincronizar retentativas concorrentes, e falha rápido em 401/403/404 — que repetir nunca conserta.
Some jitter mesmo quando respeitar o Retry-After. Se dez processos seus levarem 429 no mesmo segundo e todos esperarem exatamente 60s, os dez voltam juntos e estouram o teto de novo — a mesma manada, um minuto depois. Um aleatório de até 1s entre eles resolve.

Como tratar, resumido

Toda a /v1 é somente leitura, então qualquer requisição é segura de repetir: não há efeito colateral duplicado possível. Isso é o que torna a retentativa agressiva aceitável aqui — o cuidado com duplicidade fica do lado de webhooks, onde o guia de webhooks detalha a idempotência.
Se o seu caso é reagir a mudanças, webhooks evitam a maior fonte de 429: varrer listas em laço só para descobrir o que mudou.