VenddorDocumentação API
API atualAPI legada
Guia rápidoReferência completa
Carregando índice…
API atual/Referência completa

Catálogo da vitrine

Como a API pública de navegação lista produtos, categorias, marcas e filtros, como ela mostra preço e estoque e o que muda entre visitante e cliente logado.

O catálogo da vitrine é a parte da API que o comprador usa para navegar: listar produtos, abrir a página de um produto, percorrer categorias e marcas e refinar com filtros. É a mesma API que a loja web da Venddor e os apps móveis consomem, e você pode usá-la para montar a sua própria vitrine (um site headless, um app, um quiosque) ou para sincronizar o catálogo público com outro sistema.

Todas as rotas desta seção são GET (exceto onde indicado), ficam sob /api/v1/storefront/... e não exigem login na configuração padrão. A loja é identificada pelo domínio da requisição ou pelo cabeçalho X-Tenant-ID (veja Lojas e tenants).

Pontos-chave
  • Só aparecem produtos ativos (status A). Rascunho, oculto, desativado, em moderação e rejeitado nunca saem desta API, nem por id direto (resposta 404).
  • Dinheiro é inteiro em centavos (3780 = R$ 37,80). Cada produto traz também price_str, o mesmo valor em string decimal ("37.80"), para quem prefere decimal.
  • Respostas anônimas são cacheáveis (Cache-Control: public, max-age=300). Com Authorization a resposta vira private, no-store, porque o preço pode depender do grupo do cliente.
  • A loja pode exigir login para navegar (resposta 401 shopping_requires_login) ou esconder preços de visitantes (price_redacted: true, preço zerado).
  • Uma lista que passa do fim não dá erro: devolve products: null com total correto. Confira total_pages antes de pedir a próxima página.

Como funciona

Uma vitrine típica faz estas chamadas, nesta ordem:

  1. Montar o menu

    GET /categories/nav devolve as categorias em formato leve, já respeitando o idioma e a regra de "ocultar categorias vazias" da loja. Use /categories/tree quando precisar da árvore aninhada.

  2. Listar os produtos de uma categoria

    GET /products?category_id=... com page, per_page, ordenação e filtros de preço, marca e estoque. A resposta traz o cartão de cada produto: nome, imagens, preço, estoque, vendedor e o caminho canônico da URL.

  3. Montar a barra de filtros

    GET /categories/{id}/available-filters devolve os filtros da categoria com a contagem de produtos de cada valor, já levando em conta o que o comprador marcou. Reenvie as escolhas como features[id]=valor na listagem.

  4. Abrir um produto

    GET /products/{id} aceita UUID ou slug e devolve o produto completo: SEO, breadcrumb, escadas de preço, vídeos. O restante da página (opções, variações, características, anexos) vem das rotas de Página de produto.

  5. Atualizar preços depois do login

    Páginas em cache mostram o preço de visitante. Depois do login, GET /products/prices?ids=... troca em lote pelos preços reais do cliente, sem refazer as listas.

Status de produto

A vitrine só enxerga A. O campo status existe na resposta e é sempre A.

statusSignificadoAparece na vitrine
AAtivo e aprovadoSim
DDesativadoNão (404)
HOcultoNão (404)
REm moderação (aguardando aprovação)Não (404)
XRejeitadoNão (404)

Status de categoria

statusSignificadoAparece na vitrine
AAtivaSim
DDesativadaNão
HOcultaNão

Uma categoria desativada ou oculta esconde também toda a sua subárvore: GET /categories/{id} de uma filha devolve 404 enquanto um ancestral estiver inativo.

Conceitos-chave

Preço, desconto e preço de visitante

price é o preço unitário atual em centavos. list_price (pode ser null) é o preço "de" que a loja risca quando há promoção cadastrada no produto. catalog_discount é o desconto por unidade, em centavos, de uma promoção de catálogo ativa: o valor que o carrinho de fato cobra é price - catalog_discount. O carrinho e a vitrine usam a mesma conta.

Para cliente logado, price já vem com a tabela do grupo de usuário dele (por exemplo, tabela regional ou atacado) quando existe preço por grupo para a quantidade 1. Visitante vê o preço base. Se a loja tiver desligado "visitante vê preço", os preços saem zerados e price_redacted vem true: mostre "Entre para ver o preço".

price_tiers é a escada de preço por quantidade (preços universais). Detalhes de cada degrau ficam na rota de preço por quantidade, fora desta seção.

Estoque e disponibilidade

CampoTipoSignificado
track_inventorybooleanfalse = estoque ilimitado, ignore quantity.
quantitynúmeroSaldo na unidade de venda. Pode ser fracionado (0.5 kg). amount é um alias do mesmo valor.
out_of_stock_actionstringO que fazer com saldo zero: N esconde o botão de compra (padrão), B aceita venda sem estoque (encomenda), S mostra o aviso "avise-me quando chegar".
min_quantity, max_quantity, quantity_stepnúmeroRegras de quantidade na compra. 0 em min/max = sem limite.
sale_unitstringUnidade de venda: un, kg, cx, l, par ou personalizada.
zero_price_actionstringO que fazer com preço zero: P usa o preço, R pede orçamento (sem compra), A permite comprar de graça.

Duas configurações da loja mudam o que a lista mostra: se "mostrar produtos sem estoque" estiver desligado, a lista só traz produtos com saldo (ou sem controle de estoque); se "mostrar produtos de preço zero" estiver desligado, produtos com preço zero somem e o GET /products/{id} deles dá 404. Em listagens de busca ou de categoria, produtos indisponíveis vão para o fim, sem mudar a ordem escolhida dentro de cada grupo.

Vendedores (marketplace)

Em lojas com vários vendedores (sellers, ou lojistas), cada produto pertence a um vendedor: vendor_id, vendor_name, vendor_slug (e os aliases company_id, company_name). Produtos da própria loja não têm vendedor. Com o módulo de produtos mestre ligado, vários vendedores podem ofertar o mesmo produto: a lista colapsa as ofertas num único cartão, o da oferta mais barata visível, e o link do cartão já aponta para essa oferta. Se a loja filtra por região de entrega, só aparecem vendedores que entregam ao CEP do comprador (veja "Região de entrega" abaixo).

SEO

A página de produto traz seo.meta_title, seo.meta_description e seo.canonical_url já resolvidos (com os textos padrão da loja quando o produto não tem os próprios), breadcrumb e categories (a cadeia da raiz até a categoria do produto). Cada produto da lista traz canonical_path, a URL canônica em segmentos (["escritorio", "zz-doc-midia-teste", "p"] vira /escritorio/zz-doc-midia-teste/p) e slugs com os slugs por idioma, usados para hreflang. Categorias trazem seo_title, seo_description e meta_keywords quando preenchidos. Slugs antigos de produto redirecionam: veja Consultar produto.

Idioma

Envie ?lang=pt-BR (ou en, es) ou o cabeçalho Accept-Language. O nome, a descrição e os textos de produtos, categorias e marcas voltam no idioma pedido; quando não há tradução, vale o texto base. Sem nenhum dos dois, o texto base.

Cache e cabeçalhos

SituaçãoCache-Control
Visitante, rota de catálogopublic, max-age=300, stale-while-revalidate=1800
Menu de categorias (/categories/nav)public, max-age=60, stale-while-revalidate=300
Preço e escada de preço de um produtono-store
Qualquer rota com Authorizationprivate, no-store
Loja com filtro de região de entrega ativoprivate, no-store
Errosno-store, no-cache, must-revalidate

As respostas também trazem ETag e Vary: X-Tenant-ID. Como o cache público dura minutos, uma mudança de preço feita pelo lojista pode levar até 5 minutos para aparecer a visitantes; para preços atuais use /products/prices ou o carrinho.

Região de entrega

Em lojas que ativaram o filtro por região de entrega, o catálogo esconde vendedores que não entregam ao comprador. A região vem, nesta ordem, de deliver_to_state, deliver_to_city, deliver_to_district e deliver_to_cep (ou buyer_state... e cep) na query, dos cabeçalhos X-Buyer-State, X-Buyer-City, X-Buyer-District, X-Buyer-CEP, ou do endereço padrão do cliente logado. Sem região, nada é filtrado. Com filtro ativo a resposta é private, no-store.

Visitante, cliente e chave de API

VisitanteCliente logado (JWT)Chave de API
AcessoLivre, a menos que a loja exija login (401)Sempre liberadoPrecisa do escopo storefront:read (403 missing_scope)
Produtos restritos a gruposSó os públicosTambém os do grupo do clienteConforme o dono da chave
PreçoBase (ou zerado se a loja esconde)Preço do grupo do clienteConforme o dono da chave
CachePúblicoprivate, no-storeConforme o caso

Para obter o token do cliente, veja Autenticação.

Endpoints

Método e caminhoPara que serveAuthPágina
GET /api/v1/storefront/productsListar produtos com filtros, ordenação e paginaçãoOpcionalListar produtos
GET /api/v1/storefront/products/{id}Produto completo por UUID ou slugOpcionalConsultar produto
GET /api/v1/storefront/products/by-barcodeAchar produto pelo código de barrasOpcionalConsultas rápidas
GET /api/v1/storefront/products/pricesPreços reais de vários produtos de uma vezOpcionalConsultas rápidas
GET /api/v1/storefront/categoriesTodas as categorias ativas, em lista planaOpcionalCategorias
GET /api/v1/storefront/categories/visibleMesma lista, sem categorias vazias se a loja pedirOpcionalCategorias
GET /api/v1/storefront/categories/navMenu: mesma lista em formato leveOpcionalCategorias
GET /api/v1/storefront/categories/treeÁrvore aninhada de categoriasOpcionalCategorias
GET /api/v1/storefront/categories/{id}Uma categoriaOpcionalCategorias
GET /api/v1/storefront/categories/{id}/filtersFiltros da categoria com contagemOpcionalFiltros de categoria
GET /api/v1/storefront/categories/{id}/available-filtersFiltros com contagem que reflete as escolhas atuaisOpcionalFiltros de categoria
GET /api/v1/storefront/filtersFiltros globais ou de uma categoriaOpcionalFiltros de categoria
GET /api/v1/storefront/features/{id}Uma característica e seus valoresOpcionalFiltros de categoria
GET /api/v1/storefront/brandsMarcas com produtos ativosOpcionalMarcas
GET /api/v1/storefront/brands/{slug}Uma marcaOpcionalMarcas
GET /api/v1/storefront/brands/{slug}/productsProdutos de uma marcaOpcionalMarcas
GET /api/v1/storefront/feeds/{id}Feed de produtos por id (módulo de feeds)NãoFeeds de produtos
GET /api/v1/feeds/{token}Feed de produtos pelo link secretoToken na URLFeeds de produtos

Erros comuns

  • Esperar 404 em página vazia. Pedir uma página além do fim devolve 200 com "products": null. Pare quando page >= total_pages.
  • Pedir per_page maior que 100. Não é limitado a 100: volta ao padrão de 20. Use no máximo 100.
  • Usar features_hash com ids em UUID. O formato separa valores por hífen e os UUIDs também têm hífen, então o filtro não casa. Use features[featureId]=variantId.
  • Tratar price como o valor cobrado. Subtraia catalog_discount. E lembre que visitante e cliente podem ver preços diferentes.
  • Mostrar preço de uma resposta em cache a um cliente logado. Troque os preços com /products/prices depois do login.
  • Chamar GET /categories/{id} com slug. Categorias só aceitam UUID; o slug dá 404. Resolva o slug pela lista de categorias.
  • Mandar ids com mais de 200 itens. Os excedentes são ignorados em silêncio, em /products e em /products/prices.

Próximos passos

Listar produtos
Filtros, ordenação, paginação e o cartão do produto.
Consultar produto
A página completa de um produto, com SEO e escadas de preço.
Página de produto
Opções, variações, características e anexos.
Paginação
Convenções de paginação da API.
Anterior
Tarefas em lote
Próxima
Listar produtos
Nesta página
  • Como funciona
  • Status de produto
  • Status de categoria
  • Conceitos-chave
  • Preço, desconto e preço de visitante
  • Estoque e disponibilidade
  • Vendedores (marketplace)
  • SEO
  • Idioma
  • Cache e cabeçalhos
  • Região de entrega
  • Visitante, cliente e chave de API
  • Endpoints
  • Erros comuns
  • Próximos passos