Códigos de resposta
| Código | Significado | Repetir? |
|---|---|---|
200 | A requisição foi entendida. Confira os desfechos por peça | Não |
400 | O pacote ou o JSON foi recusado antes de ler qualquer peça | Não sem corrigir |
401 | A chave está ausente, inválida ou revogada | Não |
5xx | Problema nosso | Sim — guarde o arquivo e tente de novo |
O que mais pega as pessoas
200 não significa que tudo funcionou.
Recusas de negócio vivem nos desfechos por peça, não no status HTTP. Um arquivo em que as três peças foram recusadas ainda devolve 200, porque a requisição em si foi entendida e respondida corretamente.
Então a conferência nunca é só if (status == 200) ok(). É:
status == 200 → ler totais.recusadas e a lista de itens
Escolhemos isso em vez de devolver 400 para arquivo parcialmente falho porque o arquivo não é atômico: com 97 peças criadas e 3 recusadas, nem "sucesso" nem "falha" é verdade, e só a lista de itens diz o que realmente aconteceu.
400 contra peça recusada
Os dois significam que algo está errado no dado, mas acontecem em momentos diferentes e pedem tratamento diferente.
400 é o pacote inteiro sendo recusado antes de qualquer linha ser lida — ZIP sem planilha na raiz, extensão não aceita, planilha ilegível. O corpo é texto puro, sem lista de itens, porque nenhum item chegou a existir.
REJECTED dentro de um 200 é uma linha que falhou enquanto as outras entraram. Você corrige aquela linha e reenvia só ela.
5xx e o que não fazer
Um 5xx significa que o conteúdo nunca foi o problema. Rede, banco, um defeito do nosso lado.
Guarde o arquivo e repita. Não mova para uma pasta de erro, não marque o pedido como falho, e não exija que alguém reexporte do seu ERP. Os mesmos bytes vão funcionar quando voltarmos.
É exatamente o que o Mover.Glass Connector faz na sua instalação: falha de transporte deixa o pacote na pasta de entrada para o próximo ciclo, e só recusa de conteúdo o move para o lado. Se você estiver escrevendo o seu próprio cliente, essa distinção é a que vale copiar.