Produto e estoque
O backend do ERP cadastra produtos pelo EAN, dá entrada no estoque do depósito e consulta o estoque do depósito e das máquinas. Preço e saída de estoque ficam com a plataforma da ETech.
Cadastrar produto pelo EAN
O mesmo PUT cria o produto quando o EAN é novo e atualiza quando já existe. Na atualização, só os campos enviados mudam: campo ausente não é apagado.
PUT /integration/v1/products/7891234567895
x-api-key: <api key>
Authorization: Bearer <access_token>
User-Agent: <nome-do-sistema>/<versão>
Content-Type: application/json
{
"name": "Cerveja IPA 473 ml",
"unit": "UN",
"group": "Cervejas",
"brand": "Cervejaria Exemplo",
"tax": { "ncm": "22030000", "cest": "0302100", "origin": 0 }
}
{ "productId": 4512, "skuId": 4630, "created": true }
| Campo | Na criação | Regra |
|---|---|---|
| EAN (na URL) | obrigatório | GTIN-8, 12, 13 ou 14, com dígito verificador válido |
name | obrigatório | Único entre os produtos do cliente |
unit | opcional, padrão UN | Sigla de unidade cadastrada na ETech, como UN, KG, CX |
group | opcional, padrão "Sem grupo" | Nome do grupo. Não diferencia maiúsculas; o que não existe é criado |
brand | opcional, padrão "Sem marca" | Nome da marca, com a mesma regra do grupo |
tax.ncm | obrigatório quando a ETech emite a NFC-e do cliente | 8 dígitos, da tabela oficial de NCM |
tax.origin | obrigatório quando a ETech emite a NFC-e do cliente | Origem da mercadoria, de 0 a 8 |
tax.cest | opcional | 7 dígitos, válido para o NCM do produto |
- Preço não vem por aqui. O produto nasce sem preço, e o preço é cadastrado na plataforma da ETech.
- Cadastre o produto antes da carga de estoque: uma carga com EAN desconhecido é recusada inteira.
Dar entrada no depósito
A carga soma quantidades ao estoque do depósito da empresa. É movimento, e não saldo: a ETech baixa o depósito quando abastece as máquinas, e o ERP vê o saldo pela consulta de estoque.
POST /integration/v1/stock-loads
x-api-key: <api key>
Authorization: Bearer <access_token>
User-Agent: <nome-do-sistema>/<versão>
Idempotency-Key: nf-000123-serie-1
Content-Type: application/json
{
"companyDocument": "12345678000190",
"lines": [
{ "ean": "7891234567895", "quantity": 48, "unitCost": 4.35 },
{ "ean": "7896045505876", "quantity": 24 }
]
}
{ "loadId": 381, "status": "Pending", "lineCount": 2, "errors": [], "createdAt": "2026-10-26T13:05:12+00:00", "appliedAt": null }
- O depósito é achado pelo CNPJ da empresa: é a única loja ativa dela que não é máquina. Uma empresa sem loja assim, ou com mais de uma, é recusada com
422. Idempotency-Keyé obrigatório, com até 100 caracteres. Reenviar com a mesma chave devolve a carga que já existe, com200, sem somar de novo. Use uma chave por documento de origem, como a nota de entrada.- A resposta é
202: a carga é aplicada em segundo plano, em segundos. O resultado sai na consulta da carga. - Tudo ou nada. Se uma linha tiver erro, nenhuma é aplicada, e a carga volta com o erro de cada linha.
- Uma linha por EAN. O mesmo EAN duas vezes na carga é erro.
quantityé maior que zero e aceita decimais, para produto vendido por peso.unitCostatualiza o custo médio do produto no depósito. Ele é obrigatório só para o produto que ainda não tem custo médio, como na primeira entrada.- Limites: até 5.000 linhas e 1 MB por carga.
Acompanhar a carga
Consulte a carga até ela sair de Pending ou Processing.
GET /integration/v1/stock-loads/381
{
"loadId": 381,
"status": "Rejected",
"lineCount": 2,
"errors": [
{ "line": 2, "code": "INTEGRATION_STOCK.UNIT_COST_REQUIRED" }
],
"createdAt": "2026-10-26T13:05:12+00:00",
"appliedAt": null
}
status | O que significa |
|---|---|
Pending | Recebida, esperando a vez |
Processing | Sendo aplicada |
Applied | Todas as linhas entraram no depósito. appliedAt diz quando |
Rejected | Nada entrou. errors lista o erro de cada linha |
lineconta a partir de 1, na ordem em que as linhas foram enviadas. A linha 0 é um erro da carga inteira.- Corrija e reenvie com uma chave nova. A carga recusada fica guardada com a chave antiga, e reenviar com ela devolve a mesma recusa.
| Código de linha | Quando |
|---|---|
INTEGRATION_STOCK.EAN_NOT_FOUND | EAN sem produto cadastrado |
INTEGRATION_STOCK.DUPLICATE_EAN | O mesmo EAN em mais de uma linha |
INTEGRATION_STOCK.INVALID_QUANTITY | Quantidade ausente, zero ou negativa |
INTEGRATION_STOCK.INVALID_UNIT_COST | Custo negativo |
INTEGRATION_STOCK.UNIT_COST_REQUIRED | Produto ainda sem custo médio no depósito, e linha sem unitCost |
INTEGRATION_STOCK.APPLY_FAILED | Linha 0: a ETech não conseguiu aplicar depois de 5 tentativas. Fale com a ETech antes de reenviar |
Consultar o estoque
A consulta devolve o saldo de cada produto no depósito e em cada máquina da empresa, em páginas com cursor. É por ela que o ERP vê as saídas que não são venda, como abastecimento e quebra.
GET /integration/v1/stock?companyDocument=12345678000190&ean=7891234567895&after=0&limit=100
{
"items": [
{
"store": { "id": 12, "name": "Depósito Centro", "type": "Full" },
"ean": "7891234567895", "skuId": 4630, "stock": 120, "available": 118,
"updatedAt": "2026-10-26T13:05:14+00:00"
},
{
"store": { "id": 34, "name": "Máquina Shopping", "type": "VendingMachine" },
"ean": "7891234567895", "skuId": 4630, "stock": 9, "available": 9,
"updatedAt": "2026-10-26T12:40:02+00:00"
}
],
"next": 9817
}
companyDocumenté obrigatório;eanfiltra um produto só.typesepara o depósito das máquinas: a máquina éVendingMachine.availableé o saldo menos o que está reservado para vendas em andamento.- Paginação:
limitvai de 1 a 500, com padrão 100. Use onextcomoafterda próxima chamada; uma página vazia devolve o mesmoaftere encerra a leitura.
Respostas e erros
Os erros de token, credencial e gateway estão em Acesso. Erro de linha da carga não aparece aqui: ele sai na consulta da carga.
| HTTP | Código | Quando |
|---|---|---|
| 400 | INTEGRATION_PRODUCT.INVALID_EAN | EAN fora do formato ou com dígito verificador errado |
| 400 | INTEGRATION_PRODUCT.NAME_REQUIRED | Produto novo sem name |
| 409 | INTEGRATION_PRODUCT.NAME_IN_USE | Outro produto do cliente já tem esse nome |
| 409 | INTEGRATION_PRODUCT.EAN_BELONGS_TO_KIT | O EAN é de um kit, não de um produto |
| 422 | INTEGRATION_PRODUCT.UNIT_NOT_FOUND | Unidade não cadastrada na ETech |
| 422 | INTEGRATION_PRODUCT.NCM_NOT_FOUND | NCM fora da tabela oficial |
| 422 | INTEGRATION_PRODUCT.CEST_NOT_FOUND | CEST inexistente para o NCM do produto |
| 422 | INTEGRATION_PRODUCT.INVALID_ORIGIN | Origem fora de 0 a 8 |
| 422 | INTEGRATION_PRODUCT.TAX_REQUIRED | Produto novo sem NCM ou origem, quando a ETech emite a NFC-e |
| 400 | INTEGRATION_STOCK.IDEMPOTENCY_KEY_REQUIRED | Carga sem o header Idempotency-Key |
| 400 | INTEGRATION_STOCK.IDEMPOTENCY_KEY_TOO_LONG | Chave com mais de 100 caracteres |
| 400 | INTEGRATION_STOCK.EMPTY_LINES | Carga sem linhas |
| 400 | INTEGRATION_STOCK.TOO_MANY_LINES | Mais de 5.000 linhas |
| 413 | — | Corpo com mais de 1 MB |
| 404 | INTEGRATION_STOCK.COMPANY_NOT_FOUND | CNPJ que não é de uma empresa do cliente |
| 422 | INTEGRATION_STOCK.DEPOSIT_NOT_FOUND | A empresa não tem loja ativa que não seja máquina |
| 422 | INTEGRATION_STOCK.DEPOSIT_AMBIGUOUS | A empresa tem mais de uma loja assim; fale com a ETech |
| 404 | INTEGRATION_STOCK.LOAD_NOT_FOUND | Carga inexistente, ou de outro cliente |