Erros da API
[object Object]
Quando uma chamada à API não dá certo, a resposta traz um corpo padronizado que explica o problema. Este artigo ajuda quem faz a integração a entender cada resposta e a decidir o que fazer.
Para que serve
Saber ler o erro, corrigir a sua requisição ou, quando for o caso, pedir ajuda ao suporte com a informação certa.
O formato
Toda resposta de erro tem Content-Type: application/problem+json e estes campos:
| Campo | O que traz |
|---|---|
type | Identificador estável do tipo de erro, no formato /errors/<codigo> (o código com hífen no lugar de _). |
title | Título curto, em português, fixo para cada tipo. |
status | O mesmo status do HTTP. |
detail | A mensagem desta ocorrência, em português. |
code | O código do erro (em snake_case). É por ele que o seu sistema deve decidir o que fazer. |
errors | Quando o problema é de campo: o caminho do campo e as mensagens. |
traceId | Só no erro 500: o identificador para o suporte achar o registro. |
Exemplo, enviando um produto com stock inválido:
{
"type": "/errors/validation-error",
"title": "Dados inválidos",
"status": 400,
"detail": "Verifique os campos informados.",
"code": "validation_error",
"errors": { "[0].stock": ["O campo 'estoque' deve ser um número decimal válido."] }
}
A chave de errors é o caminho do JSON que você enviou: [0].stock é a propriedade stock do primeiro item da lista (a contagem começa em zero).
Os códigos da integração
| Status | code | Quando acontece | O que fazer |
|---|---|---|---|
| 400 | validation_error | Algum campo veio inválido (tipo errado, formato inválido). | Leia errors, corrija o campo apontado e envie de novo. |
| 401 | unauthenticated | Sem chave (API Key não foi fornecida.) ou com chave que não existe (API Key inválida.). | Envie o cabeçalho X-API-KEY com uma chave ativa. Veja Chaves de API. |
| 409 | import_conflict | A importação encontrou um conflito. | Leia o detail e ajuste os dados. |
| 422 | validation_error | A lista veio vazia ou inválida (detail: "lista vazia"). | Envie a lista com pelo menos um item. |
| 422 | import_failed | Nenhuma linha do lote pôde ser importada. | Veja unsaved_items: cada item recusado traz o index e os erros. |
| 429 | rate_limited | Muitas requisições com a mesma chave. | Espere o tempo do cabeçalho Retry-After (em segundos) e tente de novo. |
| 500 | internal_error | Erro inesperado do lado da plataforma. | Tente de novo em instantes. Se persistir, mande o traceId ao suporte. |
Linhas recusadas: unsaved_items
Quando o lote tem linhas com problema, o resumo diz quais:
{
"type": "/errors/import-failed",
"title": "Importação sem itens válidos",
"status": 422,
"code": "import_failed",
"sent": 1, "saved": 0, "updated": 0, "unsaved": 1,
"unsaved_items": [
{ "index": 0, "errors": ["código obrigatório", "nome obrigatório"], "data": { } }
]
}
Quando só algumas linhas são recusadas, a resposta é 200 e as recusadas voltam em unsaved_items; as demais foram importadas.
Os códigos da plataforma
O aplicativo da plataforma usa a mesma estrutura de erro, com mais códigos, como forbidden (acesso negado), token_expired (sessão expirada), duplicate_email (e-mail já cadastrado) e domain_error (regra de negócio violada). Quem integra pelo ERP lida, na prática, com os da tabela acima.
Perguntas frequentes
Recebi 401 mesmo enviando a chave.
Confira se o cabeçalho é X-API-KEY, se a chave foi copiada inteira e se ela está ativa (não revogada nem expirada), em Configurações → API Keys.
Recebi 429. Quanto espero?
O tempo vem no cabeçalho Retry-After, em segundos. A resposta não traz nenhum pedaço da sua chave.
O erro fala de um campo que eu não conheço.
O caminho em errors segue o JSON que você enviou, não os nomes da tela. Confira os nomes dos campos em Integração com o ERP.