Pular para o conteúdo principal

Erros

Toda resposta fora da faixa 2xx usa o mesmo envelope JSON. Seu cliente pode tratar erros a partir de um só formato.

Envelope

{
"code": "validation_failed",
"message": "Revise os campos informados e tente novamente.",
"detail": "Revise os campos informados e tente novamente.",
"hint": "Confira o tipo e o formato de cada campo.",
"details": {
"errors": [
{ "loc": ["body", "email"], "msg": "value is not a valid email address" }
]
},
"debug_id": "8e1f2c3a4b5c6d7e8f90",
"request_id": "8e1f2c3a4b5c6d7e8f90"
}

Campos

CampoTipoDescrição
codestringCódigo canônico, legível por máquina (validation_failed, forbidden, etc). Use este para lógica no cliente.
messagestringMensagem legível ao humano, traduzida conforme o header x-locale.
detailstringMesma coisa que message, mantido por compatibilidade.
hintstring | nullSugestão de ação para o usuário/desenvolvedor. Pode ser null quando não há dica específica.
detailsobjectContexto adicional específico da falha (campos inválidos, IDs envolvidos, etc). Estrutura varia por erro.
debug_idstringIdentificador único da requisição — use no suporte para investigação.
request_idstringMesmo valor de debug_id; exposto também no header X-Request-Id da resposta.

Códigos canônicos

HTTPcodeSignificadoComo reagir
400bad_requestRequisição mal formada (JSON inválido, tipo errado).Corrija o payload e repita.
401unauthorizedToken/chave ausente, inválido ou expirado.Autentique novamente.
403forbiddenAutenticado, mas sem permissão.Use uma chave com escopo maior, ou peça a permissão ao admin.
404not_foundRecurso não existe ou não está no seu escopo.Confirme o ID e o contexto de organização/projeto.
409conflictEstado atual incompatível (versão já publicada, email duplicado, etc).Atualize o estado local e tente de novo.
413payload_too_largeBody acima de 8 MB.Divida o payload ou reduza o conteúdo.
422validation_failed / request_validation_failedCampo inválido segundo o schema.Consulte details.errors e ajuste.
429rate_limitedLimite de requisições excedido.Leia Retry-After e espere. Veja Limites.
500internal_errorErro inesperado no servidor.Pode repetir com backoff. Se persistir, reporte com o debug_id.

Alguns endpoints retornam códigos mais específicos dentro de code (por exemplo plan_quota_exceeded, api_key_scope_insufficient, project_not_found). Trate qualquer code desconhecido como "erro do tipo HTTP" — o HTTP status é a fonte da verdade de alto nível.

Validação de schema (422)

Requisições com body em formato inválido para o schema retornam:

{
"code": "request_validation_failed",
"message": "Dados inválidos enviados na requisição.",
"hint": "Revise os campos obrigatórios e os formatos.",
"details": {
"errors": [
{
"type": "string_type",
"loc": ["body", "email"],
"msg": "Input should be a valid string",
"input": 42
}
]
},
"debug_id": "..."
}

details.errors[] segue o formato padrão do Pydantic v2. Os campos relevantes:

  • loc: caminho do campo problemático dentro do payload (["body", "items", 0, "name"]).
  • type: tipo do erro (missing, string_too_short, int_parsing, etc).
  • msg: mensagem detalhada.
  • input: valor rejeitado (pode ser omitido).

Autenticação e permissão (401 / 403)

codeDetalhe típico
unauthorizedMensagem como "Sessão expirada ou revogada", "API key inválida ou expirada".
forbidden"Permissão insuficiente", "Escopo da API key insuficiente", "Organização fora do escopo da sessão".

Diferença prática:

  • 401: o cliente não pode continuar sem renovar credenciais.
  • 403: o cliente está autenticado, mas a credencial não é suficiente para a operação. Pode ser escopo da API key, papel na organização, ou tentativa de acessar um projeto de outra organização.

Rate limiting (429)

Resposta quando o limite por minuto ou por hora é estourado:

{
"code": "rate_limited",
"message": "Rate limit excedido.",
"hint": "Aguarde o reset informado e tente novamente.",
"details": {
"route": "analysis.validate",
"reset_at": "2026-04-24T15:31:00Z"
},
"debug_id": "..."
}

Headers adicionais nessa resposta:

  • Retry-After: <segundos> — quanto esperar antes de tentar de novo.
  • X-RateLimit-Limit, X-RateLimit-Remaining — estado do limite no momento do bloqueio.

Veja Limites e uso para políticas por plano.

Payload grande (413)

{
"code": "payload_too_large",
"message": "Payload acima do limite permitido (8388608 bytes).",
"hint": "Reduza o tamanho do payload antes de tentar novamente."
}

O limite padrão é 8 MB. Para eventos de logtest acima disso, divida em chamadas separadas.

Internacionalização das mensagens

Mensagens de erro (message, hint) são resolvidas no idioma do cliente. A ordem de resolução:

  1. Header x-locale (valores aceitos: pt-BR, en-US).
  2. Header Accept-Language.
  3. Fallback para pt-BR.

Os codes nunca são traduzidos — são a sua interface estável com a API. Use sempre code para branching de lógica; deixe message e hint para exibir ao usuário final.

Debug IDs e correlação

O campo debug_id aparece também no header X-Request-Id da resposta. Ele é gerado automaticamente (ou aceito do cliente pelo mesmo header na requisição).

Use esse ID para:

  • Anexar ao reporte de bug/suporte — facilita a busca no log do servidor.
  • Correlacionar chamadas em cadeia — você pode enviar o mesmo X-Request-Id nas sub-chamadas para um rastreio único.

Para rastreamento distribuído (OpenTelemetry), veja o cabeçalho Traceparent descrito em Convenções.

Exemplos de tratamento

Python

import httpx

resp = httpx.post("https://ruleforge.example.com/api/v1/analysis/validate",
headers={"X-API-Key": key},
json=payload)

if resp.status_code == 429:
retry_after = int(resp.headers.get("Retry-After", "60"))
time.sleep(retry_after)
# retry
elif resp.status_code >= 400:
body = resp.json()
raise RuleForgeError(
code=body["code"],
message=body["message"],
debug_id=body.get("debug_id"),
)

JavaScript

const res = await fetch(`${base}/analysis/validate`, {
method: "POST",
headers: { "X-API-Key": key, "Content-Type": "application/json" },
body: JSON.stringify(payload),
})

if (!res.ok) {
const err = await res.json()
console.error(`[${err.code}] ${err.message} (debug_id=${err.debug_id})`)
throw err
}