Como fazer upload do seu catálogo para o SiteChat
Se você usa o SiteChat no seu próprio site (não em uma loja Shopify), pode enviar registros estruturados de produtos para a Shoply para que os compradores possam encontrá-los no chat do SiteChat e na busca de produtos.
Esses endpoints usam o mesmo Configurações → Segredo da API do proprietário da loja que o restante da API do Comerciante da Shoply, e a página Catálogo de Produtos do admin do SiteChat pode chamá-los com o token de acesso de admin da sua sessão autenticada. 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 do SiteChat que ainda não sincronizam um catálogo Magento.
No admin do SiteChat, Catálogo de Produtos abre uma área no estilo da 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?
| API | Método | O que faz |
|---|---|---|
/merchant/products/batch | POST | Cria ou substitui completamente até 50 produtos em uma solicitação |
/merchant/products | POST | Cria ou substitui completamente um produto |
/merchant/products | GET | Lê de volta um produto importado por source e external_id |
/merchant/products | PATCH | Atualiza parcialmente um produto (ler-mesclar-gravar) |
/merchant/products | DELETE | Arquiva temporariamente um produto (status=archived) |
/merchant/products/list | GET | Pagina pelos produtos importados para tabelas de admin |
/merchant/products/images | POST | Faz upload de uma imagem de produto e retorna uma URL HTTPS pública |
/merchant/collections | GET / POST | Lista ou cria coleções manuais |
/merchant/collections/{id} | GET / PUT / DELETE | Lê, substitui ou arquiva uma coleção |
/merchant/inventory | GET | Lista linhas de estoque (quantidades de produto e variante) |
/merchant/inventory/adjust | POST | Define a quantidade controlada de um produto ou variante |
Salvamentos de produto bem-sucedidos pedem à Shoply que reconstrua o índice da loja. Até que essa reconstrução termine, as respostas informam index_status: "pending". Os 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_keyexato da solicitação. - Tokens da Shopify Admin API não podem chamar essas rotas.
Crie ou rotacione o segredo do proprietário da mesma forma que em outras integrações da Merchant API: Como usar a API do Comerciante 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 a autenticação funciona?
A partir de um conector de servidor
Chame a API a partir de um backend confiável via HTTPS. Coloque uma string JSON no cabeçalho Authorization:
{
"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, em vez disso, sua sessão de admin autenticada:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN"
}access_token é aceito como um alias para admin_auth_token.
O parâmetro de consulta store_key deve corresponder ao cabeçalho. Mantenha os segredos do proprietário apenas em variáveis de ambiente no lado do servidor — nunca em um script da vitrine, URL ou repositório público.
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
{
"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,priceeavailable.statustem o valor padrãopublished. - Inventário opcional: defina
tracks_inventorycomotruee umaquantitynão negativa no produto ou na variante. A Shoply então deriva a disponibilidade do estoque (quantity > 0) e armazenatotal_inventorypara listas de admin. sourcenomeia a conexão do catálogo (não necessariamente uma plataforma). Use um nome estável, comowoocommerce-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 origemadmin.- A identidade do produto é a combinação de loja, origem e ID externo. Upserts em lote e
POSTúnico são substituições completas, não patches: campos opcionais omitidos são apagados. UsePATCHpara atualizações parciais. - Lotes contêm de 1 a 50 produtos e no máximo 2.000.000 bytes de 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
metafieldspúblicos para especificações pesquisáveis de produtos (o análogo no SiteChat aos metafields de produto da Shopify). Os valores devem ser strings simples. Oattributeslegado é aceito como alias.metadataprivado de produto não é mais suportado. - Produtos
draftearchivedficam fora do próximo índice publicado. Produtos publicados esgotados permanecem indexados com a disponibilidade anexada. - 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
{
"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 foi bem-sucedido, mas a indexação não foi agendada — tente novamente também os produtos armazenados.
Exemplo em 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.
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"])Posso fazer upload de 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:
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY
Content-Type: image/pngEnvie os bytes brutos do arquivo, não JSON, base64 ou 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.
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. Fazer upload de uma imagem sozinha não a associa 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 busca?
Após um salvamento em lote bem-sucedido, a Shoply solicita uma reconstrução do índice em segundo plano. As respostas informam index_status: "pending" até que o worker publique o novo índice. Não há garantia de tempo fixo para conclusão.
- Produtos publicados entram tanto na busca 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.
Que erros devo esperar?
| HTTP status | Significado |
|---|---|
403 | Segredo ausente, inválido, expirado ou revogado; loja errada; ou uma conta que não é SiteChat |
404 | O produto importado solicitado não existe |
413 | A solicitação ou imagem excede o limite de tamanho |
415 | O upload da imagem usou um Content-Type não suportado |
422 | Campos inválidos, IDs duplicados, imagens animadas ou grandes demais, ou limites do modelo excedidos |
503 | Falha temporária de armazenamento |
Os 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, conversa e conhecimento documentados no guia da Merchant API.
Para obter ajuda com uma integração, entre em contato com a Shoply AI.
