Pular para o conteúdo

Erros e segurança

Todo erro da api tem o mesmo shape:

{
"code": "forbidden",
"message": "destino fora da allowlist da instância (modo sandbox)"
}

details é opcional e só aparece quando há algo estruturado a mais para devolver.

HTTP code Quando
400 bad_request Corpo/parâmetro inválido
401 unauthorized Sem credencial, ou credencial inválida/expirada — mensagem sempre genérica ("credenciais ausentes ou inválidas"), nunca diz qual
403 forbidden Autenticado, mas sem papel suficiente (ex.: usuário comum numa rota admin-only) ou destino fora da allowlist
404 not_found Recurso não existe ou existe mas não é seu — ver anti-enumeração abaixo
409 conflict Ex.: tentar mudar o papel do único admin ativo
429 rate_limited Limite de envio da instância estourado
500 internal_error Erro interno — nunca vaza detalhe (stack trace, erro de driver)
503 unavailable Dependência indisponível (ex.: worker fora do ar)

Confirmado ao vivo: um login com usuário inexistente devolve exatamente 401 {"code":"unauthorized","message":"credenciais ausentes ou inválidas"} — a mesma resposta de uma rota sem nenhuma credencial.

403 vs 404 — não é inconsistência, é anti-enumeração

Seção intitulada “403 vs 404 — não é inconsistência, é anti-enumeração”

Duas regras diferentes, fáceis de confundir:

  • 403 (forbidden) — você está autenticado e a API confirma que você não tem papel para aquilo (ex.: usuário comum chamando rota admin-only).
  • 404 (not_found) — usado deliberadamente onde confirmar a existência do recurso já seria um vazamento: pedir uma instância que não é sua devolve exatamente o mesmo 404 de uma instância que não existe. Confirmado ao vivo: consultar o status de um UUID aleatório que não existe no banco devolve 404 — não dá pra saber de fora se o recurso “não existe” ou “existe, mas não é seu”.

Na prática: se uma chamada sua devolver 404 numa rota com :id, não assuma que o ID está errado — também pode ser um recurso real de outro dono.

  • Token de instância: só vem no corpo de POST /instance/init (criação) ou POST /instance/{id}/rotate-token (rotação). GET /instance/all e GET /instance/{id}/status nunca incluem o token — confirmado ao vivo.
  • Segredo de webhook: só vem no corpo de POST /instance/{id}/webhooks (criação). GET .../webhooks nunca devolve segredo — confirmado ao vivo.

Se você perder um desses valores, a única forma de recuperar acesso é gerar um novo (rotacionar o token da instância, ou recriar o webhook).