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.

CampoDescrição
location_idID do local, gerado na criação.
nameNome do local. Obrigatório na criação. O par nome + tipo é único por loja.
statusavailable ou unavailable. Obrigatório na criação: não há valor assumido.
location_typeObrigatório na criação, e só seller_location é aceito. fulfillment só aparece na leitura.
allows_pickupMarca o local como ponto de retirada. Opcional, default false.
allows_productionMarca o local como apto a industrialização. Opcional, default false.
company_branch_idVincula 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}/status com status: "unavailable".

Locais fulfillment são geridos pela plataforma. Criar, editar ou mudar o status de um local fulfillment é 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

typePara que serve
logisticsOrigem do frete e endereço fiscal do envio. É o que o local precisa para operar.
local_realEndereço físico do local, quando difere do de logística.
local_devolucaoDestino 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=logistics

Estas 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

EtapaAçãoOnde
1Conferir o teto de locais da loja (max_locations)GET /api/stores/auth/session
2Consultar filiais disponíveisGET /api/locations-stock/available-branches
3Criar o local (seller_location)POST /api/locations-stock
4Cadastrar o endereço logistics do localPOST /api/locations-stock/{locationStockId}/addresses
5Dar entrada de estoque nos SKUsProdutos: estoque
6Conferir o saldo por localGET /api/locations-stock/{locationId}/products

O que pode dar errado

ErroQuando aconteceComo tratar
403 FORBIDDENLimite 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 FORBIDDENO local existe, mas é de outra loja (no PUT de edição ou de status).Confira o location_id na listagem da loja autenticada.
403 FORBIDDENFalta o escopo store_stock_locations_read ou store_stock_locations_write.Conceda o escopo à credencial no Portal do Vendedor.
409 DUPLICATEDPOST com nome + tipo já existente na loja.Use outro nome ou reative o local existente via status.
422 VALIDATION_ERROR em location_typeTentativa 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_idFilial inexistente, inativa ou de outra empresa.Escolha um id de available-branches.
422 VALIDATION_ERRORCampo obrigatório ausente ou inválido (ex.: location_type diferente de seller_location).Corrija os campos apontados em errors.
404 NOT_FOUNDlocationId inexistente.Confira o location_id retornado na listagem.
403 FORBIDDENRota 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 CONFLICTEndereç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_FOUNDaddressId 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 saldoProdutos: estoque
Entender frete a partir da origemPedidos: logística
Ver todos os schemas e códigos de erroReferência: Locais de estoque