Estoque
O estoque tem três visões do mesmo saldo: o que existe fisicamente, o que está reservado em carrinhos e pedidos abertos, e o que sobra disponível pra nova venda. Este guia cobre como consultar e movimentar cada uma pela API.
Conceitos
| Campo | O que é |
|---|---|
quantity | Estoque físico total na sua loja. |
reserved_quantity | Já comprometido em carrinhos/pedidos em aberto. |
available_quantity | O que sobra pra venda: quantity - reserved_quantity. |
Regra: o catálogo respeita o available_quantity. Se ele zera, o produto deixa de aparecer pra novas compras, mesmo que ainda exista fisicamente.
O objeto que GET /products/{id}/stock devolve (total consolidado + saldo por localização):
{
"total": 150, // soma das quantidades em todos os locais
"stocks": [ // ← saldo por localização
{
"id": 321, // ID do registro de saldo
"product_sku": {…}, // resumo do produto dono do saldo
"location_stock": {…}, // a localização deste saldo
"quantity": 100, // físico
"reserved_quantity": 5, // reservado em pedidos abertos
"available_quantity": 95 // o que sobra pra venda
}
],
"locations": [{…}] // metadados dos locais (name, status, location_type…)
}Tipos de movimentação
A rota de movimentação aceita 3 modos, controlados pelas flags booleanas increment e decrement:
| Flags enviadas | Efeito sobre quantity |
|---|---|
| nenhuma | Sobrescreve com o valor enviado. Útil pra acerto de inventário. |
increment: true | Soma. Útil pra entrada de fornecedor. |
decrement: true | Subtrai. Útil pra baixa manual (perda, avaria, venda fora do canal). |
Mandar as duas flags juntas é recusado com 400.
Os 3 modos mexem só em
quantity. Oreserved_quantityé gerido pela plataforma, que reserva e libera saldo conforme os pedidos abrem e fecham — você cuida apenas do estoque físico.
Consultar saldo
{
"data": {
"total": 150,
"stocks": [
{
"id": 321,
"product_sku": {
"id": "01H81AV32307PVBSV4RXF15EK9",
"name": "Caneta Esferográfica Azul",
"sku": "CAN-AZ-01"
},
"location_stock": {
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"store_id": 42,
"name": "Matriz - São Paulo",
"status": "available",
"location_type": "seller_location",
"allows_pickup": false,
"allows_production": false
},
"quantity": 100,
"reserved_quantity": 5,
"available_quantity": 95
}
],
"locations": [
{
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"store_id": 42,
"name": "Matriz - São Paulo",
"status": "available",
"location_type": "seller_location",
"allows_pickup": false,
"allows_production": false
}
]
}
}No exemplo, o
product_skuaparece resumido; na prática ele vem com o cadastro completo do produto (preços, thumbnail, dimensões…).
Movimentar
O location_id é obrigatório: diz em qual local o saldo se move. Sem flag nenhuma, o valor enviado sobrescreve a quantidade:
{
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"quantity": 150
}Exemplos por cenário
Recebi 40 unidades do fornecedor:
{
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"quantity": 40,
"increment": true
}Inventário deu 95 (era 100):
{
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"quantity": 95
}Avaria, baixar 3:
{
"location_id": "01H81AV32307PVBSV4RXF15LOC",
"quantity": 3,
"decrement": true
}Regras do corpo
location_idequantitysão obrigatórios.quantityé um inteiro maior ou igual a 1. Não existe envio de0: para zerar um saldo, usedecrementcom a quantidade que existe hoje.location_idprecisa ser olocation_id(ULID) de um local acessível pela loja — os mesmos que aparecem em Locais de estoque.
O que pode dar errado
| Erro | Quando acontece | Como tratar |
|---|---|---|
400 BAD_REQUEST | increment e decrement enviados juntos. | Escolha um dos dois, ou nenhum para sobrescrever. |
422 | O local é do tipo fulfillment. | Esse saldo é sincronizado pelo WMS da plataforma e não muda por esta rota. |
422 SUBSTORE_CATALOG_READ_ONLY | A loja opera em modo espelho. | SKU, preço e estoque vêm da matriz; a subloja não movimenta estoque. |
422 VALIDATION_ERROR | location_id inexistente ou quantity menor que 1. | Corrija os campos apontados em errors. |
404 NOT_FOUND | O produto não existe no catálogo efetivo da loja. | Confira o {id} do produto. |

