Cómo subir tu catálogo para SiteChat

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

Si usas SiteChat en tu propio sitio web (no en una tienda Shopify), puedes enviar registros de productos estructurados a Shoply para que los compradores puedan encontrarlos en el chat de SiteChat y en la búsqueda de productos.

Estos endpoints usan el mismo Configuración → Secreto de API del propietario de la tienda que el resto de la API de Merchant de Shoply, y la página Product Catalog del administrador de SiteChat puede llamarlos con tu token de acceso de administrador autenticado. Las tiendas Shopify siguen sincronizando los datos del catálogo a través de Shopify; estas rutas de carga solo están disponibles para cuentas de SiteChat que no sincronizan ya un catálogo de Magento.

En el administrador de SiteChat, Product Catalog abre un área al estilo de Shopify con Products, Collections e Inventory. Puedes agregar o editar productos, importar CSV/Excel, agrupar productos en colecciones manuales y ajustar cantidades de stock.

¿Qué API están disponibles?

APIMétodoQué hace
/merchant/products/batchPOSTCrea o reemplaza por completo hasta 50 productos en una sola solicitud
/merchant/productsPOSTCrea o reemplaza por completo un producto
/merchant/productsGETVuelve a leer un producto importado por source y external_id
/merchant/productsPATCHActualiza parcialmente un producto (leer-fusionar-escribir)
/merchant/productsDELETEArchiva de forma lógica un producto (status=archived)
/merchant/products/listGETPagina entre productos importados para tablas de administración
/merchant/products/imagesPOSTSube una imagen de producto y recibe una URL HTTPS pública
/merchant/collectionsGET / POSTLista o crea colecciones manuales
/merchant/collections/{id}GET / PUT / DELETELee, reemplaza o archiva una colección
/merchant/inventoryGETLista filas de stock (cantidades de productos y variantes)
/merchant/inventory/adjustPOSTEstablece la cantidad controlada para un producto o variante

Los guardados exitosos de productos piden a Shoply que reconstruya el índice de la tienda. Hasta que esa reconstrucción termine, las respuestas informan index_status: "pending". Luego, los productos publicados aparecen tanto en el índice de productos como en el conocimiento usado por el chat de SiteChat.

¿Quién puede usar estas API?

  • Tu tienda debe ser una cuenta de SiteChat (app_platform es SiteChat).
  • Las claves de tiendas Shopify (incluido cualquier dominio *.myshopify.com) se rechazan.
  • La autenticación debe usar un secreto de API válido del propietario de la tienda o un token de acceso de administrador de SiteChat para el store_key exacto de la solicitud.
  • Los tokens de la API de administración de Shopify no pueden llamar a estas rutas.

Crea o rota el secreto del propietario de la misma forma que en otras integraciones de la API de Merchant: Cómo usar la API de Merchant de Shoply. En la consola de administración de SiteChat, abre Product Catalog para gestionar productos, colecciones e inventario, o importar un archivo CSV o Excel, sin tener que gestionar el secreto por tu cuenta.

¿Cómo funciona la autenticación?

Desde un conector del servidor

Llama a la API desde un backend de confianza a través de HTTPS. Coloca una cadena JSON en el encabezado Authorization:

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

store_owner_api_secrete es el nombre de campo público, incluida la ortografía histórica. store_owner_api_secret también se acepta. Esto no es un token Bearer.

Desde el administrador de SiteChat

La página Product Catalog envía en su lugar tu sesión de administrador autenticada:

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

access_token se acepta como alias de admin_auth_token.

El parámetro de consulta store_key debe coincidir con el encabezado. Conserva los secretos del propietario solo en variables de entorno del lado del servidor; nunca en un script del storefront, una URL o un repositorio público.

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

¿Cómo subo productos?

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 obligatorios y reglas

  • Campos obligatorios del producto: external_id, title, url, currency, price y available. status usa published por defecto.
  • Inventario opcional: establece tracks_inventory en true y una quantity no negativa en el producto o la variante. Entonces Shoply deriva la disponibilidad del stock (quantity > 0) y almacena total_inventory para las listas de administración.
  • source nombra la conexión del catálogo (no necesariamente una plataforma). Usa un nombre estable como woocommerce-main. Caracteres permitidos: letras minúsculas, números, guiones bajos y guiones medios; hasta 64 caracteres. Los productos creados con formularios en el administrador usan por defecto la fuente admin.
  • La identidad del producto es la combinación de tienda, fuente e ID externo. Los upserts por lotes y de un solo POST son reemplazos completos, no parches: los campos opcionales omitidos se borran. Usa PATCH para actualizaciones parciales.
  • Los lotes contienen de 1 a 50 productos y como máximo 2,000,000 bytes por solicitud. El JSON validado de cada producto está limitado a 128,000 bytes, con un máximo de 250 variantes.
  • Prefiere cadenas decimales para los precios. La moneda es un código en mayúsculas de tres letras.
  • Las URL de productos e imágenes deben ser HTTP(S). La importación no recupera esas URL por ti.
  • Usa metafields públicos para especificaciones de producto que se puedan buscar (el equivalente en SiteChat de los metacampos de producto de Shopify). Los valores deben ser cadenas simples. attributes heredado se acepta como alias. metadata privado del producto ya no es compatible.
  • Los productos draft y archived se excluyen del siguiente índice publicado. Los productos publicados agotados permanecen indexados con la disponibilidad asociada.
  • Las colecciones manuales almacenan un título, descripción, estado y una lista de membresías de productos (source + external_id). Las colecciones inteligentes/basadas en reglas no son compatibles en esta versión.

Ejemplo de respuesta exitosa

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

Shoply valida toda la solicitud antes de escribir. Un HTTP 200 aún puede incluir algunos resultados failed con error: "storage_error". Revisa cada resultado y vuelve a intentar los productos fallidos. Si index_status es request_failed, el almacenamiento se realizó correctamente pero no se programó la indexación; vuelve a intentar también los productos almacenados.

Ejemplo en 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")

¿Cómo verifico un producto importado?

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

Usa el mismo encabezado Authorization. La respuesta incluye schema_version, updated_at, index_status y el product normalizado. Los registros ausentes devuelven HTTP 404.

Después de que el indexador en segundo plano publique una reconstrucción, el estado de lectura por producto pasa a ser indexed, excluded (para productos en borrador o archivados) o limit_exceeded. Usa GET /merchant/products/list para listados de administración. Archiva de forma lógica con DELETE /merchant/products (o establece status en archived / draft) para mantener un producto fuera del siguiente índice publicado; no hay eliminación definitiva en esta versión.

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"])

¿Puedo subir imágenes de productos?

Sí. Si una imagen ya está disponible en una URL HTTPS pública y duradera, coloca esa URL en la lista images del producto o en el campo image de una variante. Las URL HTTPS públicas de S3 funcionan. Las rutas s3:// sin procesar y las URL firmadas de corta duración no.

Para que Shoply aloje el archivo, sube bytes de imagen sin procesar desde tu backend:

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

Envía los bytes sin procesar del archivo, no JSON, base64 ni datos de formulario multipart. Se aceptan JPEG, PNG y WebP, hasta 10 MiB y 20 millones de píxeles. Las imágenes animadas no son compatibles. Shoply convierte la imagen a WebP y elimina los metadatos incrustados.

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 devuelve url, content_type, size_bytes, width y height. Subir una imagen por sí sola no la vincula a un producto ni solicita indexación. Incluye la URL devuelta en un producto completo y envíalo de nuevo mediante /merchant/products/batch.

La misma imagen subida de nuevo para la misma cuenta reutiliza su URL. Una imagen modificada recibe una nueva URL. No hay un endpoint para eliminar imágenes en esta versión.

¿Cuándo aparecen los productos en el chat y la búsqueda?

Después de guardar correctamente un lote, Shoply solicita una reconstrucción del índice en segundo plano. Las respuestas informan index_status: "pending" hasta que el worker publique el nuevo índice. No hay una garantía de tiempo fijo de finalización.

  • Los productos publicados entran tanto en la búsqueda de productos como en el conocimiento usado por el chat de SiteChat.
  • Los productos en borrador y archivados se excluyen en la siguiente reconstrucción.
  • Si no se programó la indexación (index_status: "request_failed"), vuelve a intentar el lote para los productos que ya se almacenaron correctamente.

¿Qué errores debo esperar?

HTTP statusSignificado
403Secreto faltante, inválido, vencido o revocado; tienda incorrecta; o una cuenta que no es de SiteChat
404El producto importado solicitado no existe
413La solicitud o la imagen supera el límite de tamaño
415La carga de la imagen usó un Content-Type no compatible
422Campos no válidos, ID duplicados, imágenes animadas o demasiado grandes, o límites del modelo superados
503Fallo temporal de almacenamiento

Los secretos vencen después de 90 días. Crea un reemplazo en Configuración → Secreto de API del propietario de la tienda antes del vencimiento, y revoca cualquier secreto que ya no necesites. El mismo secreto también puede llamar a endpoints de analítica, conversación y conocimiento documentados en la guía de la API de Merchant.

Para obtener ayuda con una integración, contacta a Shoply AI.