Visão geral
Um local de estoque é onde os seus produtos ficam guardados: um depósito, uma loja física ou um centro de distribuição. Todo saldo de estoque é contado por local, e é o local que define a origem do frete e o endereço fiscal de um envio.
Este guia cobre o ciclo de vida do local (criar, editar, ativar/desativar), os endereços dele, as filiais que ele pode representar e como listar os produtos com saldo em cada local. A movimentação de saldo (entrada e saída de estoque) fica em Produtos: estoque.
Leitura exige o escopo store_stock_locations_read; criar, editar, mudar status e gerenciar endereços exigem store_stock_locations_write.
Conceitos
Tipo de local (location_type):seller_location (depósito ou loja própria, que você gerencia) ou fulfillment (centro de distribuição da plataforma). Locais fulfillment são geridos por um sistema externo (WMS) e são somente leitura pela API: qualquer tentativa de criar, editar ou mudar o status é recusada. Na criação, só seller_location é aceito.
Status (status):available (operacional, entra no cálculo de venda e frete) ou unavailable (desativado, some da conta de disponibilidade, mas preserva o histórico). Não existe DELETE de local: para tirar um local de operação, mude o status para unavailable.
Filial (branch): um local pode estar vinculado a uma filial da empresa (CNPJ próprio) ou à matriz. O vínculo é feito pelo company_branch_id; branch: null na resposta significa matriz. A lista de filiais válidas vem de Filiais disponíveis.
Retirada e produção:allows_pickup marca o local como ponto de retirada pelo cliente; allows_production marca o local como apto a industrialização/produção sob encomenda.
Endereço de logística: para operar (cotar frete, emitir nota), um local precisa de pelo menos um endereço do tipo logistics. Você cadastra pela API, em Endereços do local.
O objeto que a API devolve para um local:
{
"location_id": "01K9T…", // ID do local, usado como {locationId} nas rotas
"store_id": 42, // referência interna da loja (não é o store_id da sessão)
"name": "Depósito Central",
"status": "available", // available | unavailable
"location_type": "seller_location", // seller_location | fulfillment (WMS, somente leitura)
"allows_pickup": true, // aceita retirada no local
"allows_production": false, // apto a industrialização
"branch": { // filial vinculada (null = matriz)
"id": "01K9B…", // ID da filial
"name": "Filial Campinas",
"document": "12345678000199" // CNPJ da filial
}
}Locais
A listagem devolve todos os locais da loja (inclusive os desativados e os de fulfillment) e não é paginada. O {locationId} das outras rotas é o location_id retornado aqui.
| Campo | Descrição |
|---|---|
location_id | ID do local, gerado na criação. |
name | Nome do local. Obrigatório na criação. O par nome + tipo é único por loja. |
status | available ou unavailable. Obrigatório na criação: não há valor assumido. |
location_type | Obrigatório na criação, e só seller_location é aceito. fulfillment só aparece na leitura. |
allows_pickup | Marca o local como ponto de retirada. Opcional, default false. |
allows_production | Marca o local como apto a industrialização. Opcional, default false. |
company_branch_id | Vincula o local a uma filial. Envie null para desvincular (matriz). A filial precisa estar ativa e pertencer à empresa da loja. Só no corpo de criação/edição. Na leitura, o vínculo volta em branch. |
Não há endpoint de exclusão. Para tirar um local de operação, use
PUT /api/locations-stock/{locationId}/statuscomstatus: "unavailable".
Locais
fulfillmentsão geridos pela plataforma. Criar, editar ou mudar o status de um localfulfillmenté recusado: eles só aparecem na listagem para leitura.
Limite de locais
Cada loja tem um teto de locais. O valor vigente vem em max_locations, na resposta de GET /api/stores/auth/session. Leia de lá em vez de fixar um número na integração.
A contagem inclui todos os locais já cadastrados, inclusive os unavailable e os de fulfillment. Desativar um local não libera vaga. Ao atingir o teto, o POST responde 403 orientando a contatar o suporte.
Criar
Envie name, status e location_type: os três são obrigatórios. Repetir o par nome + tipo devolve 409.
{
"name": "Novo Depósito Zona Norte",
"status": "available",
"location_type": "seller_location",
"allows_pickup": false,
"allows_production": false,
"company_branch_id": "01K9B..."
}Editar
O PUT /api/locations-stock/{locationId} aplica só os campos enviados (name, allows_pickup, allows_production, company_branch_id). Para mudar o status, use a rota dedicada de status. O PUT de edição não muda status.
A resposta da rota de status não traz o campo branch. Se precisar do vínculo atualizado depois de ativar ou desativar, consulte o local.
Filiais disponíveis
Lista a matriz e as filiais ativas da empresa, para você escolher o company_branch_id na criação/edição de um local. A matriz vem com uid: null, ou seja, para deixar o local na matriz, omita o campo ou envie null.
{
"headquarters": { "id": null, "name": "Matriz", "document": "12345678000190" },
"branches": [
{ "id": "01K9B...", "name": "Filial Campinas", "document": "12345678000199" }
],
"default_branch": { "id": "01K9B...", "name": "Filial Campinas" }
}Enviar uma filial inativa, de outra empresa ou inexistente devolve 422 no campo company_branch_id.
Endereços do local
Sem endereço logistics, o local não cota frete nem serve de origem fiscal. Depois de criar o local, cadastre o endereço pela mesma integração.
O {locationStockId} é o location_id do local. O {addressId} é o id que a listagem de endereços devolve — os dois são ULID.
Tipos
type | Para que serve |
|---|---|
logistics | Origem do frete e endereço fiscal do envio. É o que o local precisa para operar. |
local_real | Endereço físico do local, quando difere do de logística. |
local_devolucao | Destino das devoluções que chegam a este local. |
O type é obrigatório na criação e só aceita esses três valores. O local pode ter mais de um endereço do mesmo tipo.
Criar
{
"type": "logistics",
"street": "Rua das Palmeiras",
"number": "1200",
"complement": "Galpão 3",
"district": "Distrito Industrial",
"city": "Campinas",
"state": "SP",
"zip_code": "13052-000",
"reference": "Em frente ao posto",
"delivery_instructions": "Recebimento das 8h às 17h"
}Obrigatórios: type, street, number, district, city, state (2 letras) e zip_code (com ou sem hífen). country é opcional e assume BR.
Se você não mandar latitude/longitude, a plataforma resolve a coordenada pelo CEP e, se não achar, tenta geocodificar. Quando nada resolve, o endereço é criado do mesmo jeito e volta com is_complete: false — vale conferir esse campo, porque endereço sem coordenada atrapalha cotação de frete.
O que a API devolve:
{
"id": "01K9C…", // ULID do endereço, usado como {addressId}
"uid": "01K9C…", // mesmo valor de id
"type": "logistics",
"type_label": "Logística",
"street": "Rua das Palmeiras",
"number": "1200",
"complement": "Galpão 3",
"reference": "Em frente ao posto",
"can_deliver_to_neighbor": false,
"delivery_instructions": "Recebimento das 8h às 17h",
"district": "Distrito Industrial",
"city": "Campinas",
"state": "SP",
"country": "BR",
"zip_code": "13052-000", // formatado; em full_address o CEP sai sem máscara
"latitude": -22.9099,
"longitude": -47.0626,
"place_id": null,
"address_components": null,
"full_address": "Rua das Palmeiras, 1200 - Galpão 3 - Distrito Industrial, Campinas - SP, 13052000",
"is_complete": true // false = coordenada não resolvida
}Repetição exata dá 409
Endereço do mesmo tipo, pode. O que a plataforma recusa é o endereço idêntico: CEP, logradouro, bairro, cidade, UF, número e complemento iguais aos de outro já vinculado ao local devolvem 409. Na edição vale o mesmo: se a alteração deixar dois endereços iguais, o PUT é recusado.
Editar e remover
O PUT aplica só os campos enviados. Quando algum campo de endereço muda e você não manda latitude/longitude, a coordenada é recalculada; mandando as duas, a plataforma respeita o que veio.
O DELETE desfaz o vínculo com o local e responde 204 sem corpo. Se o endereço não estiver mais vinculado a nada, ele é apagado de vez.
Listar
A listagem é paginada (data.data[] + data.meta.pagination), aceita per_page (padrão 15) e o filtro type — que é o caminho curto para pegar o endereço de logística do local:
GET /api/locations-stock/01K9T…/addresses?type=logisticsEstas rotas têm um limite próprio de 60 requisições por minuto, mais restrito que o limite global do token. Ver Limites de uso.
Produtos por local
Lista paginada dos produtos com o saldo daquele local (quantity, reserved_quantity, sold_reserved_quantity e available_quantity são escopados ao local). Aceita filter[name], filter[sku], filter[search], ordenação por name, sku, created_at, updated_at e per_page (padrão 15). Segue o envelope paginado padrão (data.data + data.meta.pagination).
Para dar entrada ou baixa de saldo em um local, use a movimentação de estoque em Produtos: estoque.
Dados auxiliares
Devolve os valores válidos de location_types, location_statuses e address_types (com rótulos em pt-BR). Use para popular selects no seu sistema. A lista address_types traz todos os tipos de endereço da plataforma; em locais de estoque valem apenas logistics, local_real e local_devolucao.
Fluxo: novo local pronto para operar
| Etapa | Ação | Onde |
|---|---|---|
| 1 | Conferir o teto de locais da loja (max_locations) | GET /api/stores/auth/session |
| 2 | Consultar filiais disponíveis | GET /api/locations-stock/available-branches |
| 3 | Criar o local (seller_location) | POST /api/locations-stock |
| 4 | Cadastrar o endereço logistics do local | POST /api/locations-stock/{locationStockId}/addresses |
| 5 | Dar entrada de estoque nos SKUs | Produtos: estoque |
| 6 | Conferir o saldo por local | GET /api/locations-stock/{locationId}/products |
O que pode dar errado
| Erro | Quando acontece | Como tratar |
|---|---|---|
403 FORBIDDEN | Limite de locais da loja atingido no POST. | Não crie mais locais; desativar um local não libera vaga. Contate o suporte para ampliar o limite. |
403 FORBIDDEN | O local existe, mas é de outra loja (no PUT de edição ou de status). | Confira o location_id na listagem da loja autenticada. |
403 FORBIDDEN | Falta o escopo store_stock_locations_read ou store_stock_locations_write. | Conceda o escopo à credencial no Portal do Vendedor. |
409 DUPLICATED | POST com nome + tipo já existente na loja. | Use outro nome ou reative o local existente via status. |
422 VALIDATION_ERROR em location_type | Tentativa de editar ou mudar o status de um local fulfillment. | Locais de fulfillment são somente leitura; não os altere pela API. |
422 VALIDATION_ERROR em company_branch_id | Filial inexistente, inativa ou de outra empresa. | Escolha um id de available-branches. |
422 VALIDATION_ERROR | Campo obrigatório ausente ou inválido (ex.: location_type diferente de seller_location). | Corrija os campos apontados em errors. |
404 NOT_FOUND | locationId inexistente. | Confira o location_id retornado na listagem. |
403 FORBIDDEN | Rota de endereço com um locationStockId de outra loja ou inexistente. | Aqui o erro é 403, não 404. Confira o location_id na listagem de locais. |
409 CONFLICT | Endereço idêntico (CEP, rua, bairro, cidade, UF, número e complemento) já vinculado ao local. | Reaproveite o endereço existente ou mude algum campo. |
404 NOT_FOUND | addressId que existe mas não está vinculado a este local. | Liste os endereços do local e use um id de lá. |
Para onde ir agora
| Você precisa… | Vá para |
|---|---|
| Dar entrada ou baixa de saldo | Produtos: estoque |
| Entender frete a partir da origem | Pedidos: logística |
| Ver todos os schemas e códigos de erro | Referência: Locais de estoque |

