Enviar peças
Um caminho de entrada: o arquivo. Toda regra abaixo vale para cada peça dentro dele.
POST /api/v1/integration/pieces/import
Envie um .csv, .xlsx ou .zip como multipart form data, num campo chamado file:
curl -H "X-API-Key: mgi_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@exemplo.zip" \
https://seu-servidor/api/v1/integration/pieces/import
O nome do campo importa: qualquer coisa diferente de file chega como nada e a importação falha. A extensão também — o servidor decide o que fazer pelo nome que você envia, então um ZIP chamado dados.txt é recusado.
{
"fileFormat": "ZIP (CSV)",
"totals": { "read": 3, "created": 1, "ignored": 1, "rejected": 1 },
"items": [
{ "barcode": "ABC-001", "outcome": "CREATED" },
{ "barcode": "ABC-002", "outcome": "IGNORED", "reason": "Código de Barras já existe" },
{ "barcode": "ABC-003", "outcome": "REJECTED", "reason": "Informe ao menos um serviço em ServicosAplicaveis (ex.: [CORTE_MONO],[TEMPERA]) — sem serviço não há roteiro de produção." }
],
"warnings": [],
"createdGlassTypes": [],
"createdCustomers": []
}
Os campos que talvez surpreendam
fileFormat diz o que o servidor realmente leu — ZIP (CSV) significa que ele achou um CSV dentro do seu ZIP. Útil quando o pacote é montado errado.
warnings são não-fatais. Uma imagem ou forma citada na planilha e ausente do pacote, por exemplo: a peça entrou, o anexo é que não.
createdGlassTypes e createdCustomers listam o que o sistema criou sozinho a partir do seu arquivo. Tipologia ou cliente que ainda não existe é criado na importação — e receber a lista de volta é o que impede o cadastro de crescer sem você saber. Se VIDRO A e VIDRO A aparecerem aqui em duas semanas diferentes, alguém está digitando diferente na origem.
As colunas que o arquivo pode levar estão na página formato do arquivo. Coluna que não conhecemos é ignorada, não recusada.
Os três desfechos
| Desfecho | O que significa | O que fazer |
|---|---|---|
CREATED | A peça foi criada, com o roteiro de produção | Nada |
IGNORED | Aquele código de barras já existia | Nada. É o resultado esperado de um reenvio |
REJECTED | Não entrou, e o reason diz por quê | Corrigir o dado e reenviar só as recusadas |
O outcome sempre vem como texto, nunca como número. Isso é garantido e testado — enum serializado como número obrigaria você a decorar uma ordem que poderia mudar em silêncio.
O reason é preenchido em IGNORED e REJECTED, e nulo em CREATED, onde não há o que explicar.
O reason volta no seu idioma. Mande um header Accept-Language — pt-BR, en, it ou es-ES — e o texto da recusa chega traduzido. Sem o header você recebe português. Esse texto é para pessoa ler: nunca condicione o seu código a ele, porque a frase pode ser reescrita e a tradução, corrigida. Condicione ao outcome, que não muda.
O arquivo não é atômico
Cada peça tem transação própria. Um arquivo com 100 peças e 3 linhas ruins grava 97 e recusa 3. Não existe rollback do lote.
É por isso que a resposta é item a item. Duas consequências que valem considerar no seu código:
- Reenviar o arquivo inteiro depois de corrigir é seguro — as 97 voltam como
IGNORED - Mas saber quais 3 falharam evita ter que fazer isso
Repetir é seguro
O código de barras é seu, e garantimos não duplicá-lo.
Se uma requisição der timeout e você não souber se ela chegou, mande de novo. O pior caso é IGNORED. Não há passo de conciliação, não há chave de idempotência para gerenciar, e não existe janela em que repetir cria uma peça gêmea.
O que uma recusa não é
Recusa é resposta de negócio, não falha de servidor. Ela chega com 200, não com 500.
Essa distinção importa para a sua lógica de repetição: 5xx significa tentar mais tarde, o conteúdo nunca foi o problema. REJECTED significa que o conteúdo é o problema, e repetir sem mudar vai falhar igual para sempre.