Pular para o conteúdo

Erros e repetição segura

As rotas públicas devolvem erros JSON com uma referência para diagnóstico:

{
"erro": {
"codigo": "REQUISICAO_INVALIDA",
"mensagem": "A requisição não corresponde ao contrato da API.",
"request_id": "bb12f58a-0dbc-46e5-b95a-96780597dc0e",
"caminho": "produtos[3].ncm"
}
}

caminho aparece quando a recusa identifica um campo. Registre request_id, status e código; nunca registre a chave Bearer ou o corpo privado para obter suporte. A mensagem é para pessoas e pode mudar; a decisão do seu código usa codigo.

HTTP codigo O que significa
400 IDEMPOTENCIA_INVALIDA Falta a Idempotency-Key ou ela está fora do formato.
400 VERSAO_INVALIDA If-Match malformado: ETag fraco, *, lista ou valor inventado.
401 CREDENCIAL_INVALIDA Chave ausente, inválida, expirada ou revogada.
409 LOTE_CONFLITANTE Sequência ou chave de idempotência já usada com outro conteúdo.
409 REVISAO_HUMANA_NECESSARIA Tentativa de aplicar uma ingestão em precisa_revisao.
409 DESTINO_CATALOGO_OBRIGATORIO A empresa tem mais de um catálogo ativo e o pedido não informou catalogo_id.
409 ANALISE_NAO_CONCLUIDA Resultados pedidos antes de a análise terminar.
409 ASSINATURA_INATIVA Webhook configurado, testado ou reenviado sem plano pago ativo.
412 VERSAO_DIVERGENTE O recurso mudou desde a leitura que gerou o ETag.
422 REQUISICAO_INVALIDA Corpo fora do contrato da rota.
428 VERSAO_OBRIGATORIA A rota exige If-Match e ele não foi enviado.

Testar com segurança mostra como provocar os mais comuns sem alterar dados.

HTTP Tratamento
400 Corrija JSON, tamanho declarado, ETag ou chave idempotente malformados.
401 Confira chave, expiração, revogação e empresa; não repita sem limite.
403 Emita uma chave com o escopo necessário.
404 Confira o ID e o ambiente; recursos de outra empresa também não são revelados.
408 A leitura do corpo excedeu o prazo; confirme o estado antes de repetir.
409 Leia o código: pode haver conflito de estado, capacidade, franquia ou idempotência.
412 Consulte o recurso novamente e revise a alteração antes de usar o novo ETag.
413 Reduza bytes, itens ou o total da ingestão.
415 Envie application/json sem compressão quando a rota espera JSON.
422 Corrija campos e formato; repetir o mesmo pedido não resolve.
428 Faça a leitura e envie a precondição If-Match exigida.
429 Aguarde Retry-After e reduza a concorrência.
503 Preserve a idempotência, respeite Retry-After e mantenha a falha visível.

Toda mutação exige uma chave de repetição. Gere e persista uma chave aleatória por operação lógica antes do primeiro envio. Em caso de timeout ou resposta perdida, repita o mesmo método, caminho, corpo e precondições com a mesma chave.

const idempotencyKey = crypto.randomUUID()
// Persista com o pedido antes de enviar. Reutilize somente para esse pedido.

Nas rotas de recursos, a chave aceita 16 a 128 caracteres entre letras, números, ., _, :, e -. O protocolo de ingestão aceita 16 a 200 caracteres sem espaço. Consulte o OpenAPI da operação antes de gerar. Um UUID atende aos dois contratos.

O replay devolve o recibo original e não aplica o efeito outra vez. Ele não prova que o recurso ainda está naquele estado: faça um GET para ler a situação atual. Reutilizar a chave com outro corpo, alvo, operação ou ETag retorna 409.

Rotacionar a credencial não muda o namespace empresarial das operações REST. Uma chave substituta válida e autorizada pode recuperar o replay; uma chave revogada não pode.

Trate cada ETag como opaco e guarde o valor completo, incluindo aspas. Não construa o cabeçalho a partir da versão numérica. ETags fracos, * e listas são recusados quando a rota exige a representação exata.

Uma resposta 412 é uma decisão, não um erro para repetição automática: leia novamente, compare o estado e confirme se a alteração ainda faz sentido.