Pular para o conteúdo
Menu de documentos

API REST

Produtos

Listar, pesquisar, ler e criar ou atualizar produtos, com preços de lista ou quaisquer preços de clientes.

Um produto tem um SKU, um preço de lista e uma marca, categoria, status de estoque e detalhes adicionais opcionais. Os preços são sempre calculados para você: veja Preços.

Os produtos também podem ter familyId e orderStep (padrão 1). Uma leitura de um único produto inclui metadados opcionais family com seu nome, nomes de atributos de variante e predefinição. Um preço configurado contém orderingFields, configurationRequired, definitionVersion e preço do cliente opcional quantityBreaks. Os campos de ordenação são entradas do comprador; details permanecem como fatos do produto.

POST/api/v1/products/{id}/quote

Esta operação somente leitura aceita { "customer": "ACME01", "qty": 3, "configuration": { "length": 2.75, "reference": "Kitchen" } }. customer é opcional para preços da lista de funcionários. Chaves somente leitura podem usá-lo. Ele retorna data.productId, qty, fields validados, definitionVersion e price com unit, line e a especificação escolhida. Campos obrigatórios ausentes retornam Configurar para preço; combinações inválidas são recusadas. Ele não cria um cesto, pedido ou pagamento. Use price.line em vez de multiplicar o preço unitário.

As importações aceitam os family, orderStep e orderingDefinition opcionais. Uma definição usa o esquema OpenAPI, requer o plano Pro e permissão para precificação global, e retorna o ruleDrafts para revisão por meio do fluxo de trabalho existente de alteração de preço. A estrutura omitida deixa as configurações existentes intactas. Veja configuração do catálogo de comércio.

O objeto do produtoLink para esta seção#

json
{
  "id": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
  "sku": "HX-8510",
  "name": "Hex bolt M10 x 50 zinc",
  "description": "Grade 8.8, zinc plated, fully threaded.",
  "brandId": "a1b2c3d4-0000-4000-8000-000000000001",
  "categoryId": "a1b2c3d4-0000-4000-8000-000000000002",
  "manufacturerRef": "DIN933-M10-50",
  "unitLabel": "Box of 100",
  "minOrderQty": 1,
  "availability": "in_stock",
  "stockQty": 240,
  "lowStockAt": null,
  "leadTimeNote": null,
  "dealText": null,
  "active": true,
  "visibility": "all",
  "details": { "Finish": "Zinc", "Thread": "M10" },
  "createdAt": "2026-08-14T09:30:00.000Z",
  "updatedAt": "2026-09-20T16:02:11.000Z",
  "price": {
    "unit": 1850,
    "line": 1850,
    "list": 1850,
    "discountBp": 0,
    "source": "list",
    "label": ""
  }
}
CampoTipoDescrição
idstringID do produto.
skustringSeu código de estoque. Único no espaço de trabalho, ignorando maiúsculas e minúsculas.
namestringNome do produto.
descriptionstring ou nullDescrição mais longa.
brandId, categoryIdstring ou nullConsulte marcas e categorias.
manufacturerRefstring ou nuloNúmero de peça do fabricante. Pesquisável como o SKU.
unitLabelstringO que uma unidade é, por exemplo, “Cada” ou “Caixa de 100”.
minOrderQtyinteiroQuantidade mínima que os compradores podem pedir.
availabilitystringnot_tracked, in_stock, low_stock, out_of_stock ou made_to_order. Uma etiqueta apenas para compradores: cada produto pode ser comprado. Enviando-o sem um stockQty apaga qualquer contagem armazenada (você está definindo o status manualmente). Com um stockQty é calculado para você: 0 ou menos é out_of_stock, até o nível mínimo é low_stock, acima disso é in_stock. made_to_order nunca é alterado pelo número.
stockQtyinteiro ou nuloUnidades em estoque, ou null quando você não contabiliza este produto. Quando definido, availability segue-o. Excluído quando você o solicita como cliente (customer).
lowStockAtinteiro ou nuloNível de estoque baixo próprio do produto, ou null para usar o nível do espaço de trabalho. Excluído quando você o pede como cliente.
leadTimeNotestring ou nullex. “3–5 dias úteis”.
dealTextstring ou nuloUma nota exibida ao lado do preço, como "mín 12 btls 45". Seu título é a etiqueta de negócios do espaço de trabalho (Configurações, Exibição do Catálogo).
activebooleanoProdutos inativos são ocultos dos compradores.
visibilitystringall, ou selected quando apenas clientes selecionados puderem vê-lo.
detailsobjectColunas adicionais de imports, como { "Finish": "Zinc" }.
priceobjeto ou nuloO preço na quantidade 1 (ou qty). Veja Preços. unit é null quando o produto não tem preço ainda.

Contagens de estoque são suas para manter atualizadas: os pedidos nunca mudam stockQty, então envie-o do seu sistema de estoque sempre que houver alterações. Os clientes veem apenas o status availability, nunca o número. Em zero, um produto ainda pode ser pedido; ele simplesmente é rotulado como fora de estoque.

Os nomes GET /products/{id} também incluem brand e category.

Imagens não são retornadas pela API. Você pode definir uma com imageUrl ao criar ou atualizar.

Listar ou pesquisar produtosLink para esta seção#

GET/api/v1/products

Sem q, os produtos são listados por nome. Com q, os resultados aparecem nesta ordem:

  1. SKU exato ou referência do fabricante
  2. SKU ou referência do fabricante que começa com q
  3. correspondências de texto completo no nome, marca, categoria e descrição (3 ou mais caracteres; consultas mais curtas correspondem ao início do nome)

Passe customer para definir o preço de cada linha para esse cliente e retorne apenas os produtos que esse cliente pode ver (ativos e tanto para todos quanto selecionados para eles). Isso é exatamente o que o cliente vê em seu portal comercial.

NomeTipoObrigatórioDescrição
qstringnãoSKU, referência do fabricante, nome, marca ou categoria. Até 200 caracteres.
categorystringnãoID da categoria.
brandstringnãoID da marca.
availabilitystringnãoUm dos valores de disponibilidade.
activetrue ou falsenãotrue retorna apenas produtos ativos. O padrão é true quando customer é definido; caso contrário, todos os produtos são retornados.
customerstringnãoID do cliente ou código da conta.
limitinteironão1 a 50. Padrão 50.
offsetinteironãoLinhas a pular. Padrão 0.
bash
curl "https://tradecatalog.app/api/v1/products?q=hex%20bolt&customer=OAK01&limit=20" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const params = new URLSearchParams({
  q: 'hex bolt',
  customer: 'OAK01',
  limit: '20',
})
const res = await fetch(`https://tradecatalog.app/api/v1/products?${params}`, {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: products, nextOffset } = await res.json()
json
{
  "data": [
    {
      "id": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
      "sku": "HX-8510",
      "name": "Hex bolt M10 x 50 zinc",
      "description": "Grade 8.8, zinc plated, fully threaded.",
      "brandId": "a1b2c3d4-0000-4000-8000-000000000001",
      "categoryId": "a1b2c3d4-0000-4000-8000-000000000002",
      "manufacturerRef": "DIN933-M10-50",
      "unitLabel": "Box of 100",
      "minOrderQty": 1,
      "availability": "in_stock",
      "leadTimeNote": null,
      "active": true,
      "visibility": "all",
      "details": { "Finish": "Zinc", "Thread": "M10" },
      "createdAt": "2026-08-14T09:30:00.000Z",
      "updatedAt": "2026-09-20T16:02:11.000Z",
      "price": {
        "unit": 1573,
        "line": 1573,
        "list": 1850,
        "discountBp": 1500,
        "source": "brand",
        "label": "Brand discount −15%"
      }
    }
  ],
  "nextOffset": null,
  "currency": "GBP"
}

Obter um produtoLink para esta seção#

GET/api/v1/products/{id}

NomeEntradaTipoObrigatórioDescrição
idcaminhostringsimID do produto.
customerconsultastringnãoID do cliente ou código da conta. Retorna 404 se esse cliente não puder visualizar o produto.
qtyconsultainteironãoQuantidade a ser precificada, 1 a 1.000.000. Padrão 1. price.line é unit × qty.
bash
curl "https://tradecatalog.app/api/v1/products/3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c?customer=OAK01&qty=5" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch(
  `https://tradecatalog.app/api/v1/products/${productId}?customer=OAK01&qty=5`,
  { headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` } },
)
const { data: product } = await res.json()
json
{
  "data": {
    "id": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
    "sku": "HX-8510",
    "name": "Hex bolt M10 x 50 zinc",
    "description": "Grade 8.8, zinc plated, fully threaded.",
    "brandId": "a1b2c3d4-0000-4000-8000-000000000001",
    "categoryId": "a1b2c3d4-0000-4000-8000-000000000002",
    "manufacturerRef": "DIN933-M10-50",
    "unitLabel": "Box of 100",
    "minOrderQty": 1,
    "availability": "in_stock",
    "leadTimeNote": null,
    "active": true,
    "visibility": "all",
    "details": { "Finish": "Zinc", "Thread": "M10" },
    "createdAt": "2026-08-14T09:30:00.000Z",
    "updatedAt": "2026-09-20T16:02:11.000Z",
    "brand": "Northgate",
    "category": "Bolts",
    "price": {
      "unit": 1573,
      "line": 7865,
      "list": 1850,
      "discountBp": 1500,
      "source": "brand",
      "label": "Brand discount −15%"
    }
  },
  "currency": "GBP"
}

Para pesquisar um produto pelo SKU, use GET /products?q=HX-8510: uma correspondência exata de SKU sempre aparece em primeiro lugar. Ou use GET /prices, que aceita um SKU.

Criar ou atualizar produtosLink para esta seção#

PUT/api/v1/productsescreva a chave

Envie até 100 produtos por chamada. Cada um é correspondido a um produto existente pelo SKU, ignorando maiúsculas e minúsculas. Se não houver correspondência, um novo produto é criado. Marcas e categorias são correspondidas pelo nome e criadas se não existirem.

Como os preços da lista são tratadosLink para esta seção#

O produto...O que acontece com o preço
é novoFica disponível em listPrice imediatamente.
existe, mas ainda não tem preçoFica disponível em listPrice imediatamente.
existe ao mesmo preçoNada.
existe a um preço diferenteNada muda ainda. O novo preço entra em uma mudança de preço em rascunho para essa lista. priceChangeId é o rascunho para a lista de listPrice. priceChangesByList tem uma entrada por lista que foi alterada.

Alterações de preço em rascunho são como o TradeCatalog evita que um erro de digitação chegue aos clientes. O proprietário ou funcionários revisam o rascunho no aplicativo (Alterações de preço), verificam as maiores mudanças e alertas, escolhem uma data e se deseja enviar um e-mail aos clientes, e depois publicam. Você pode visualizar um rascunho com GET /price-changes/{id}.

Uma sincronização, um rascunho por lista

Uma chamada que muda preços inicia um rascunho por lista, chamado “Importação de API (nome da chave)” para Standard e com o nome da lista quando você enviar mais de uma. Para manter uma sincronização inteira nesses rascunhos, envie priceChangeId (a lista para listPrice) e drafts (as outras listas) da primeira chamada com cada chamada posterior. Cada uma ainda deve ser um rascunho: uma vez publicada, cancelada ou descartada, deixe esse ID de fora para iniciar um novo.

CorpoLink para esta seção#

CampoTipoObrigatórioDescrição
productsarraysim1 a 100 produtos. SKUs devem ser únicos dentro da chamada.
priceChangeIdstringnãoUm rascunho da lista listPrice de uma chamada anterior. Preços alterados para essa lista são adicionados a ela. 404 se não existir, 400 se não for mais um rascunho.
draftsarraynãoAté 30 entradas { list, priceChangeId } para que outros listas continuem seus próprios rascunhos.
products[].skustringsimAté 64 caracteres.
products[].namestringsimAté 200 caracteres.
products[].listPriceinteiro ou nulosimUnidades menores, de 0 a 1.000.000.000. null é preço sob consulta: um novo produto não tem preço, um existente mantém o seu próprio.
products[].priceListstring ou nulonãoNome de uma lista de preços existente para listPrice. Omita ou null é Standard. Um nome desconhecido é rejeitado.
products[].listPricesarraynãoOutras listas, como { list, price }. price são unidades menores, ou null para deixar essa lista inalterada. Um nome desconhecido é rejeitado.
products[].unitLabelstringsimAté 60 caracteres, por exemplo, “Cada”.
products[].brandstringnãoNome da marca, até 120 caracteres. Limpo se omitido.
products[].categorystringnãoNome da categoria, até 120 caracteres. Limpo se omitido.
products[].manufacturerRefstringnãoAté 120 caracteres. Limpo se omitido.
products[].descriptionstringnãoAté 4.000 caracteres. Limpo se omitido.
products[].availabilitystringnãoUm dos valores de disponibilidade. Mantido se omitido; novos produtos começam como not_tracked.
products[].stockQtyinteiro ou nulonãoUnidades em estoque, de -1.000.000 a 1.000.000.000. Define availability (veja o objeto do produto); um status que você envia junto é ignorado, exceto made_to_order. Mantido se omitido, a menos que você envie um availability sem ele: então a contagem é limpa e esse status é usado. null para parar de contar; o availability enviado na mesma linha aplica-se, ou o status atual se não houver nenhum.
products[].lowStockAtinteiro ou nulonãoNível de estoque baixo para esse produto, de 0. null usa o nível da workspace (Configurações, 5 para começar). Mantido se omitido.
products[].leadTimeNotestringnãoAté 200 caracteres. Mantido se omitido.
products[].dealTextstringnãoAté 200 caracteres, mostrado ao lado do preço. Mantido se omitido.
products[].detailsobjetonãoAté 30 colunas extras: nomes até 60 caracteres, valores até 500. Substitui todos os detalhes quando enviado; mantido se omitido.
products[].imageUrlstringnãoUma URL de imagem https. Copiada para o TradeCatalog em segundo plano quando muda. Mantido se omitido.
products[].onlyForarraynãoAté 200 códigos de conta ou e-mails de contato. Torna o produto visível apenas para esses clientes, substituindo qualquer lista anterior. Mantido se omitido.

Envie todos os campos que você se importa

brand, category, manufacturerRef e description são escritos como enviados, então deixar um de fora os limpa. Envie o produto completo a cada vez, como uma linha de planilha.

Esses não podem ser alterados por meio da API ainda: tornar um produto inativo, minOrderQty, remover uma imagem, limpar uma observação de tempo de entrega e tornar um produto exclusivo do cliente visível para todos novamente. Faça essas alterações no aplicativo.

bash
curl -X PUT https://tradecatalog.app/api/v1/products \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "products": [
      {
        "sku": "HX-8510",
        "name": "Hex bolt M10 x 50 zinc",
        "listPrice": 1950,
        "unitLabel": "Box of 100",
        "brand": "Northgate",
        "category": "Bolts",
        "manufacturerRef": "DIN933-M10-50",
        "availability": "in_stock",
        "details": { "Finish": "Zinc", "Thread": "M10" }
      },
      {
        "sku": "OAK-HNG-75",
        "name": "Oak-finish butt hinge 75mm",
        "listPrice": 695,
        "unitLabel": "Pair",
        "category": "Hinges",
        "onlyFor": ["OAK01"]
      }
    ]
  }'
js
const res = await fetch('https://tradecatalog.app/api/v1/products', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ products }),
})
const { data: result } = await res.json()
if (result.priceChangeId)
  console.log('Review the draft price change in TradeCatalog')
json
{
  "data": {
    "created": 1,
    "updated": 1,
    "priceChanges": 1,
    "priceChangeId": "c4d5e6f7-1234-4abc-9def-0123456789ab",
    "priceChangesByList": [
      {
        "list": "Standard",
        "priceChangeId": "c4d5e6f7-1234-4abc-9def-0123456789ab"
      }
    ],
    "unknownCustomers": []
  }
}
CampoDescrição
createdNovos produtos.
updatedProdutos existentes correspondentes pelo SKU.
priceChangesQuantos preços entraram em um rascunho, em cada lista da chamada.
priceChangeIdO rascunho para a lista listPrice, ou null se essa lista não tiver alterações.
priceChangesByListUm { list, priceChangeId } para cada lista que tiver uma alteração de preço nesta chamada.
unknownCustomersValores em onlyFor que não corresponderam a nenhum cliente (até 50). Esses clientes não tiveram acesso.

As alterações aparecem no log de atividade pelo nome da chave, e as atualizações de pesquisa ocorrem imediatamente.

Marcas e categoriasLink para esta seção#

GET/api/v1/brands

GET/api/v1/categories

Ambos retornam todas as linhas, classificadas pelo nome, sem paginação. Use os ids com os filtros brand e category em GET /products.

bash
curl https://tradecatalog.app/api/v1/categories \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch('https://tradecatalog.app/api/v1/categories', {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: categories } = await res.json()
json
{
  "data": [
    { "id": "a1b2c3d4-0000-4000-8000-000000000002", "name": "Bolts" },
    { "id": "a1b2c3d4-0000-4000-8000-000000000003", "name": "Hinges" }
  ]
}

Para criar uma marca ou categoria, dê um nome a ela em um produto em PUT /products.