Como Enviar Seu Catálogo para o SiteChat

A secure merchant key unlocks catalog upload APIs that send products and images into SiteChat search and chat

Se você usa o SiteChat no seu próprio site (não em uma loja Shopify), pode enviar registros de produtos estruturados para a Shoply para que os compradores possam encontrá-los no chat do SiteChat e na pesquisa de produtos.

Esses endpoints usam o mesmo Configurações → Segredo da API do proprietário da loja que o restante da API de Comerciantes da Shoply, e a página Catálogo de Produtos do admin do SiteChat pode chamá-los com seu token de acesso de admin autenticado. As lojas Shopify continuam sincronizando os dados do catálogo por meio da Shopify; essas rotas de upload estão disponíveis apenas para contas SiteChat que ainda não sincronizam um catálogo Magento.

No admin do SiteChat, Catálogo de Produtos abre uma área no estilo Shopify com Produtos, Coleções e Inventário. Você pode adicionar ou editar produtos, importar CSV/Excel, agrupar produtos em coleções manuais e ajustar quantidades em estoque.

Quais APIs Estão Disponíveis?

APIMétodoO que faz
/merchant/products/batchPOSTCria ou substitui completamente até 50 produtos em uma única solicitação
/merchant/productsPOSTCria ou substitui completamente um produto
/merchant/productsGETLê de volta um produto importado por source e external_id
/merchant/productsPATCHAtualiza parcialmente um produto; substituir variantes ou metafields exige a versão do GET
/merchant/productsDELETEArquiva temporariamente um produto (status=archived)
/merchant/products/listGETPagina os produtos importados para tabelas do admin
/merchant/products/imagesPOSTEnvia uma imagem de produto e recebe uma URL HTTPS pública
/merchant/collectionsGET / POSTLista ou cria coleções manuais
/merchant/collections/{id}GET / PUT / DELETELê, substitui ou arquiva uma coleção
/merchant/inventoryGETLista linhas de estoque (quantidades de produto e variante)
/merchant/inventory/adjustPOSTDefine a quantidade rastreada de um produto ou variante

Salvamentos de produto bem-sucedidos pedem à Shoply para reconstruir o índice da loja. Até que essa reconstrução termine, as respostas informam index_status: "pending". Produtos publicados então aparecem tanto no índice de produtos quanto no conhecimento usado pelo chat do SiteChat.

Quem Pode Usar Essas APIs?

  • Sua loja deve ser uma conta SiteChat (app_platform é SiteChat).
  • Chaves de loja Shopify (incluindo qualquer domínio *.myshopify.com) são rejeitadas.
  • A autenticação deve usar um segredo válido da API do proprietário da loja ou um token de acesso de admin do SiteChat para o store_key exato na solicitação.
  • Tokens da API Admin da Shopify não podem chamar essas rotas.

Crie ou altere o segredo do proprietário da mesma forma que outras integrações da API de Comerciantes: Como Usar a API de Comerciantes da Shoply. No console de admin do SiteChat, abra Catálogo de Produtos para gerenciar produtos, coleções e inventário — ou importar um arquivo CSV ou Excel — sem precisar gerenciar o segredo por conta própria.

Como Funciona a Autenticação?

A partir de um conector de servidor

Chame a API de um backend confiável via HTTPS. Coloque uma string JSON no cabeçalho Authorization:

json
{ "store_key": "YOUR_SITECHAT_STORE_KEY", "store_owner_api_secrete": "YOUR_STORE_OWNER_API_SECRET" }

store_owner_api_secrete é o nome público do campo, incluindo a grafia histórica. store_owner_api_secret também é aceito. Isso não é um token Bearer.

A partir do admin do SiteChat

A página Catálogo de Produtos envia sua sessão de admin autenticada em vez disso:

json
{ "store_key": "YOUR_SITECHAT_STORE_KEY", "admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN" }

access_token é aceito como alias para admin_auth_token.

O parâmetro de consulta store_key deve corresponder ao cabeçalho. Mantenha segredos do proprietário apenas em variáveis de ambiente no lado do servidor — nunca em um script da storefront, URL ou repositório público.

bash
export SHOPLY_STORE_KEY="your-sitechat-store-key" export SHOPLY_STORE_OWNER_API_SECRETE="shoply_owner_key_example123.secret-value"

Como Faço Upload de Produtos?

POST https://api.shoplyai.ai/merchant/products/batch?store_key=YOUR_SITECHAT_STORE_KEY

json
{ "source": "woocommerce-main", "products": [ { "external_id": "123", "title": "Trail shoes", "description": "Water-resistant hiking shoes.", "url": "https://example.com/products/trail-shoes", "currency": "USD", "price": "49.95", "original_price": "59.95", "available": true, "status": "published", "images": ["https://example.com/images/trail-shoes.jpg"], "categories": ["Footwear"], "metafields": {"material": "Leather"}, "variants": [ { "external_id": "124", "title": "Brown / 42", "sku": "TRAIL-BR-42", "price": "49.95", "available": true, "metafields": {"color": "Brown", "size": "42"} } ] } ] }

Campos obrigatórios e regras

  • Campos obrigatórios do produto: external_id, title, url, currency, price e available. status tem como padrão published.
  • Inventário opcional: defina tracks_inventory como true e uma quantity não negativa no produto ou variante. A Shoply então deriva a disponibilidade do estoque (quantity > 0) e armazena total_inventory para listas do admin.
  • source nomeia a conexão do catálogo (não necessariamente uma plataforma). Use um nome estável como woocommerce-main. Caracteres permitidos: letras minúsculas, números, sublinhados e hífens; até 64 caracteres. Produtos criados por formulário no admin usam por padrão a source admin.
  • A identidade do produto é a combinação de loja, source e ID externo. Upserts em lote e POST individual são substituições completas, não patches: campos opcionais omitidos são limpos. Use PATCH para atualizações parciais.
  • Lotes contêm de 1 a 50 produtos e no máximo 2.000.000 bytes na solicitação. O JSON validado de cada produto é limitado a 128.000 bytes, com no máximo 250 variantes.
  • Prefira strings decimais para preços. A moeda é um código em maiúsculas de três letras.
  • URLs de produto e imagem devem ser HTTP(S). A importação não busca essas URLs para você.
  • Use metafields públicos para especificações pesquisáveis do produto (o análogo do SiteChat aos metafields de produto da Shopify). Os valores devem ser strings simples. O antigo attributes é aceito como alias. metadata privado do produto não é mais suportado.
  • Produtos draft e archived são deixados de fora do próximo índice publicado. Produtos publicados esgotados permanecem indexados com a disponibilidade associada.
  • Coleções manuais armazenam um título, descrição, status e uma lista de associações de produtos (source + external_id). Coleções inteligentes/baseadas em regras não são suportadas nesta versão.

Exemplo de resposta de sucesso

json
{ "results": [ { "external_id": "123", "product_id": "sitechat_product::woocommerce-main::<sha256-of-external-id>", "status": "stored" } ], "index_status": "pending", "index_revision": 1 }

A Shoply valida toda a solicitação antes de gravar. Um HTTP 200 ainda pode listar alguns resultados failed com error: "storage_error". Inspecione cada resultado e tente novamente os produtos com falha. Se index_status for request_failed, o armazenamento teve sucesso, mas a indexação não foi agendada — tente novamente também os produtos armazenados.

Exemplo em Python

python
import json import os import requests store_key = os.environ["SHOPLY_STORE_KEY"] headers = { "Authorization": json.dumps({ "store_key": store_key, "store_owner_api_secrete": os.environ["SHOPLY_STORE_OWNER_API_SECRETE"], }) } response = requests.post( "https://api.shoplyai.ai/merchant/products/batch", params={"store_key": store_key}, headers=headers, json={ "source": "custom", "products": [{ "external_id": "123", "title": "Trail shoes", "url": "https://example.com/products/trail-shoes", "currency": "USD", "price": "49.95", "available": True, }], }, timeout=60, ) response.raise_for_status() result = response.json() failed = [item["external_id"] for item in result["results"] if item["status"] != "stored"] if failed: raise RuntimeError(f"Products need retry: {failed}") if result["index_status"] == "request_failed": raise RuntimeError("Products saved, but retry the batch to request indexing")

Como Verifico um Produto Importado?

GET https://api.shoplyai.ai/merchant/products?store_key=YOUR_SITECHAT_STORE_KEY&source=woocommerce-main&external_id=123

Use o mesmo cabeçalho Authorization. A resposta inclui schema_version, updated_at, index_status e o product normalizado. Registros ausentes retornam HTTP 404.

Depois que o indexador em segundo plano publica uma reconstrução, o status de leitura por produto passa a ser indexed, excluded (para produtos em rascunho ou arquivados) ou limit_exceeded. Use GET /merchant/products/list para listagem no admin. Faça arquivamento temporário com DELETE /merchant/products (ou defina status como archived / draft) para manter um produto fora do próximo índice publicado; não há exclusão permanente nesta versão.

python
record = requests.get( "https://api.shoplyai.ai/merchant/products", params={ "store_key": store_key, "source": "woocommerce-main", "external_id": "123", }, headers=headers, timeout=30, ) record.raise_for_status() print(record.json()["index_status"], record.json()["product"]["title"])

Como Atualizo Variantes ou Metafields com Segurança?

Para um PATCH contendo variants, metafields ou o campo legado attributes, primeiro leia o produto com GET. Monte a edição a partir dessa resposta e inclua o valor updated_at de nível superior como expected_updated_at no corpo do PATCH. Isso também se aplica ao limpar variantes ou metafields.

python
current_response = requests.get( "https://api.shoplyai.ai/merchant/products", params={"store_key": store_key, "source": "woocommerce-main", "external_id": "123"}, headers=headers, timeout=30, ) current_response.raise_for_status() current = current_response.json() updated_metafields = {**current["product"].get("metafields", {}), "material": "Leather"} response = requests.patch( "https://api.shoplyai.ai/merchant/products", params={"store_key": store_key}, headers=headers, json={ "source": "woocommerce-main", "external_id": "123", "expected_updated_at": current["updated_at"], "metafields": updated_metafields, }, timeout=30, ) response.raise_for_status()

HTTP 409 significa que a versão estava ausente ou que outra atualização alterou o produto. Leia o produto mais recente e mescle novamente as alterações pretendidas antes de tentar de novo. Não anexe uma nova versão a uma lista antiga de variantes: isso pode sobrescrever valores de estoque mais recentes.

Integrações existentes que fazem PATCH desses campos sem uma versão precisam ser atualizadas. Solicitações PATCH apenas com escalares, ajustes dedicados de inventário e substituições completas por meio de POST ou importação em lote não exigem esse campo. Substituições completas ainda substituem o produto inteiro.

Posso Enviar Imagens de Produtos?

Sim. Se uma imagem já estiver disponível em uma URL HTTPS pública duradoura, coloque essa URL na lista images do produto ou no campo image de uma variante. URLs HTTPS públicas do S3 funcionam. Caminhos brutos s3:// e URLs assinadas de curta duração não funcionam.

Para fazer a Shoply hospedar o arquivo, envie bytes brutos da imagem a partir do seu backend:

text
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY Content-Type: image/png

Envie os bytes brutos do arquivo, não JSON, base64 nem dados de formulário multipart. JPEG, PNG e WebP são aceitos, até 10 MiB e 20 milhões de pixels. Imagens animadas não são suportadas. A Shoply converte a imagem para WebP e remove metadados incorporados.

python
with open("trail-shoes.png", "rb") as image_file: response = requests.post( "https://api.shoplyai.ai/merchant/products/images", params={"store_key": store_key}, headers={**headers, "Content-Type": "image/png"}, data=image_file, timeout=60, ) response.raise_for_status() image_url = response.json()["url"]

HTTP 201 retorna url, content_type, size_bytes, width e height. Enviar apenas uma imagem não a vincula a um produto nem solicita indexação. Inclua a URL retornada em um produto completo e envie-o novamente por /merchant/products/batch.

A mesma imagem enviada novamente para a mesma conta reutiliza sua URL. Uma imagem alterada recebe uma nova URL. Não há endpoint para excluir imagens nesta versão.

Quando os Produtos Aparecem no Chat e na Pesquisa?

Após um salvamento em lote bem-sucedido, a Shoply solicita uma reconstrução de índice em segundo plano. As respostas informam index_status: "pending" até que o worker publique o novo índice. Não há garantia fixa de tempo de conclusão.

  • Produtos publicados entram tanto na pesquisa de produtos quanto no conhecimento usado pelo chat do SiteChat.
  • Produtos em rascunho e arquivados são excluídos na próxima reconstrução.
  • Se a indexação não foi agendada (index_status: "request_failed"), tente novamente o lote para os produtos que já foram armazenados com sucesso.

Quais Erros Devo Esperar?

HTTP statusSignificado
403Segredo ausente, inválido, expirado ou revogado; loja errada; ou uma conta que não é SiteChat
404O produto importado solicitado não existe
413A solicitação ou imagem excede o limite de tamanho
415O upload da imagem usou um Content-Type não suportado
422Campos inválidos, IDs duplicados, imagens animadas ou grandes demais, ou limites do modelo excedidos
503Falha temporária de armazenamento

Segredos expiram após 90 dias. Crie uma substituição em Configurações → Segredo da API do proprietário da loja antes do vencimento e revogue qualquer segredo de que você não precise mais. O mesmo segredo também pode chamar endpoints de analytics, conversas e conhecimento documentados no guia da API de Comerciantes.

Para obter ajuda com uma integração, entre em contato com a Shoply AI.