Skip to main content
Quando algo dá errado, a API retorna um status HTTP de erro (4xx/5xx) e um corpo JSON no formato padrão abaixo.

Formato do erro

Programe sua lógica em cima do code (e do status HTTP), nunca do texto de message — o texto pode mudar ou vir traduzido.

Códigos HTTP

Quatro erros não seguem esse formato. O 401 e o 403 (autenticação), o 429 (limite de requisições) e os conflitos de idempotência — 422 para a mesma Idempotency-Key com corpo diferente, 409 para duas requisições simultâneas com a mesma chave — são interrompidos antes de chegar à aplicação. Neles, error vem como texto, não como objeto:
Formato normal
401, 403, 422 e 429
Na prática: error.code e error.message são undefined nesses casos. Um tratador genérico que leia error.code quebra — e quebra dentro do próprio tratamento de erro, escondendo o problema original. Para esses status, ramifique pelo status HTTP e leia os headers (Retry-After no 429). Veja Convenções · Idempotência.

Rate limit (429)

Requisições podem ser limitadas para proteger a plataforma. Os tetos variam por endpoint e podem mudar sem aviso, então trate o 429 em qualquer chamada em vez de assumir onde ele ocorre. Como nos outros erros de infraestrutura, error vem como texto, não como objeto:
Headers relevantes:

Erros de validação (400)

Quando um ou mais campos são recusados, o corpo traz issues — uma lista com todos os problemas encontrados de uma vez, não só o primeiro:
A message do topo é genérica ("Validation failed") e não descreve o erro. O que interessa está em issues — não exiba a mensagem de fora para o usuário final achando que ela explica algo.
path vazio ("") significa erro que não pertence a um campo só. É o caso das regras que cruzam campos — por exemplo customer ou customerId é obrigatório, que depende dos dois. Ao montar a exibição do erro no seu sistema, trate o path vazio como um erro do formulário inteiro, e não de um campo específico.
Toda validação responde 400, venha ela do formato do payload ou de uma regra de negócio, e sempre neste mesmo formato. Um único tratamento cobre os dois casos.

Erros de domínio: a key

Alguns erros trazem um terceiro campo além de code e message: uma key estável, que identifica o caso específico.
Os três campos respondem perguntas diferentes:
A key não vai em code. Um erro de slug duplicado tem code: "CONFLICT" e key: "errors.checkout.slug_taken". Comparar error.code === "slug_taken" nunca casa — e falha em silêncio, porque o campo existe e simplesmente tem outro valor.
Cada página de endpoint lista os erros que aquela rota produz, com a key quando houver. Não há catálogo central: erros de domínio nascem e mudam com as regras de negócio, e uma lista mantida à mão desatualiza sem ninguém perceber.

Tratamento recomendado

Retry com backoff

Em 429 e 5xx, repita com backoff exponencial. Combine com Idempotency-Key para não duplicar a operação.

Não faça retry em 4xx

400, 409 e 422 não se resolvem repetindo a mesma requisição — corrija o payload ou trate o conflito.

Logue o code e o corpo

Guarde code, status HTTP e o corpo do erro para diagnóstico — em 400, guarde issues inteiro. Nunca logue a API key.

Idempotência sempre

Em escrita, use Idempotency-Key para que retries sejam seguros. Ver Convenções.