Comment téléverser votre catalogue pour SiteChat
Si vous utilisez SiteChat sur votre propre site web (et non une boutique Shopify), vous pouvez envoyer des enregistrements de produits structurés à Shoply afin que les acheteurs puissent les trouver dans le chat SiteChat et dans la recherche de produits.
Ces points de terminaison utilisent le même Settings → Store owner API secret que le reste de la Shoply Merchant API, et la page Product Catalog de l’admin SiteChat peut les appeler avec votre jeton d’accès administrateur connecté. Les boutiques Shopify continuent de synchroniser les données du catalogue via Shopify ; ces routes de téléversement sont disponibles uniquement pour les comptes SiteChat qui ne synchronisent pas déjà un catalogue Magento.
Dans l’admin SiteChat, Product Catalog ouvre un espace de style Shopify avec Products, Collections et Inventory. Vous pouvez ajouter ou modifier des produits, importer des fichiers CSV/Excel, regrouper des produits dans des collections manuelles et ajuster les quantités en stock.
Quelles API sont disponibles ?
| API | Méthode | Ce qu’elle fait |
|---|---|---|
/merchant/products/batch | POST | Crée ou remplace entièrement jusqu’à 50 produits en une seule requête |
/merchant/products | POST | Crée ou remplace entièrement un produit |
/merchant/products | GET | Relit un produit importé par source et external_id |
/merchant/products | PATCH | Met partiellement à jour un produit ; remplacer des variantes ou des metafields nécessite la version issue de GET |
/merchant/products | DELETE | Archive en douceur un produit (status=archived) |
/merchant/products/list | GET | Parcourt les produits importés page par page pour les tableaux d’administration |
/merchant/products/images | POST | Téléverse une image de produit et renvoie une URL HTTPS publique |
/merchant/collections | GET / POST | Liste ou crée des collections manuelles |
/merchant/collections/{id} | GET / PUT / DELETE | Lit, remplace ou archive une collection |
/merchant/inventory | GET | Liste les lignes de stock (quantités des produits et variantes) |
/merchant/inventory/adjust | POST | Définit la quantité suivie pour un produit ou une variante |
Les enregistrements réussis de produits demandent à Shoply de reconstruire l’index de la boutique. Tant que cette reconstruction n’est pas terminée, les réponses indiquent index_status: "pending". Les produits publiés apparaissent ensuite à la fois dans l’index produit et dans les connaissances utilisées par le chat SiteChat.
Qui peut utiliser ces API ?
- Votre boutique doit être un compte SiteChat (
app_platformest SiteChat). - Les clés de boutique Shopify (y compris tout domaine
*.myshopify.com) sont rejetées. - L’authentification doit utiliser soit un secret API propriétaire de boutique valide, soit un jeton d’accès administrateur SiteChat pour le
store_keyexact de la requête. - Les jetons Shopify Admin API ne peuvent pas appeler ces routes.
Créez ou faites tourner le secret propriétaire de la même manière que pour les autres intégrations Merchant API : How to Use the Shoply Merchant API. Dans la console d’administration SiteChat, ouvrez Product Catalog pour gérer les produits, collections et inventaire — ou importer un fichier CSV ou Excel — sans gérer vous-même le secret.
Comment fonctionne l’authentification ?
Depuis un connecteur serveur
Appelez l’API depuis un backend de confiance via HTTPS. Placez une chaîne JSON dans l’en-tête Authorization :
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"store_owner_api_secrete": "YOUR_STORE_OWNER_API_SECRET"
}store_owner_api_secrete est le nom de champ public, y compris son orthographe historique. store_owner_api_secret est également accepté. Il ne s’agit pas d’un jeton Bearer.
Depuis l’admin SiteChat
La page Product Catalog envoie à la place votre session administrateur connectée :
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN"
}access_token est accepté comme alias de admin_auth_token.
Le paramètre de requête store_key doit correspondre à l’en-tête. Conservez les secrets propriétaire uniquement dans des variables d’environnement côté serveur — jamais dans un script de vitrine, une URL ou un dépôt public.
export SHOPLY_STORE_KEY="your-sitechat-store-key"
export SHOPLY_STORE_OWNER_API_SECRETE="shoply_owner_key_example123.secret-value"Comment téléverser des produits ?
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"}
}
]
}
]
}Champs obligatoires et règles
- Champs produit obligatoires :
external_id,title,url,currency,priceetavailable.statusprend par défaut la valeurpublished. - Inventaire optionnel : définissez
tracks_inventorysurtrueet unequantitynon négative sur le produit ou la variante. Shoply déduit alors la disponibilité du stock (quantity > 0) et stocketotal_inventorypour les listes d’administration. sourcenomme la connexion du catalogue (pas nécessairement une plateforme). Utilisez un nom stable commewoocommerce-main. Caractères autorisés : lettres minuscules, chiffres, underscores et tirets ; jusqu’à 64 caractères. Les produits créés via formulaire dans l’admin utilisent par défaut la sourceadmin.- L’identité du produit est la combinaison de la boutique, de la source et de l’ID externe. Les upserts
POSTpar lot et unitaires sont des remplacements complets, pas des patchs : les champs optionnels omis sont effacés. UtilisezPATCHpour les mises à jour partielles. - Les lots contiennent 1 à 50 produits et au plus 2 000 000 octets de requête. Le JSON validé de chaque produit est limité à 128 000 octets, avec au maximum 250 variantes.
- Préférez des chaînes décimales pour les prix. La devise est un code majuscule à trois lettres.
- Les URL de produits et d’images doivent être en HTTP(S). L’importation ne récupère pas ces URL pour vous.
- Utilisez des
metafieldspublics pour les spécifications produit recherchables (l’équivalent dans SiteChat des metafields produit Shopify). Les valeurs doivent être de simples chaînes. L’ancien champattributesest accepté comme alias. Lesmetadataproduit privées ne sont plus prises en charge. - Les produits
draftetarchivedsont exclus du prochain index publié. Les produits publiés en rupture de stock restent indexés avec leur disponibilité associée. - Les collections manuelles stockent un titre, une description, un statut et une liste d’appartenances produit (
source+external_id). Les collections intelligentes/basées sur des règles ne sont pas prises en charge dans cette version.
Exemple de réponse réussie
{
"results": [
{
"external_id": "123",
"product_id": "sitechat_product::woocommerce-main::<sha256-of-external-id>",
"status": "stored"
}
],
"index_status": "pending",
"index_revision": 1
}Shoply valide l’intégralité de la requête avant l’écriture. Un HTTP 200 peut tout de même lister certains résultats failed avec error: "storage_error". Inspectez chaque résultat et relancez les produits en échec. Si index_status vaut request_failed, le stockage a réussi mais l’indexation n’a pas été planifiée — relancez également les produits stockés.
Exemple 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")Comment vérifier un produit importé ?
GET https://api.shoplyai.ai/merchant/products?store_key=YOUR_SITECHAT_STORE_KEY&source=woocommerce-main&external_id=123
Utilisez le même en-tête Authorization. La réponse inclut schema_version, updated_at, index_status et le product normalisé. Les enregistrements manquants renvoient HTTP 404.
Après qu’un nouvel index a été publié par l’indexeur en arrière-plan, le statut de relecture par produit devient indexed, excluded (pour les produits brouillon ou archivés) ou limit_exceeded. Utilisez GET /merchant/products/list pour l’affichage d’administration. Archivez en douceur avec DELETE /merchant/products (ou définissez status sur archived / draft) pour exclure un produit du prochain index publié ; il n’y a pas de suppression définitive dans cette version.
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"])Comment mettre à jour en toute sécurité des variantes ou des metafields ?
Pour un PATCH contenant variants, metafields ou l’ancien champ attributes, commencez par lire le produit avec GET. Construisez la modification à partir de cette réponse et incluez sa valeur updated_at de niveau supérieur comme expected_updated_at dans le corps du PATCH. Cela s’applique également lors de la suppression de variantes ou de metafields.
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 signifie que la version était absente ou qu’une autre mise à jour a modifié le produit. Relisez le produit le plus récent et fusionnez à nouveau les changements souhaités avant de réessayer. N’attachez pas une nouvelle version à une ancienne liste de variantes : cela pourrait écraser des valeurs de stock plus récentes.
Les intégrations existantes qui effectuent un PATCH de ces champs sans version doivent être mises à jour. Les requêtes PATCH limitées aux scalaires, les ajustements d’inventaire dédiés et les remplacements complets via POST ou importation par lot ne nécessitent pas ce champ. Les remplacements complets remplacent toujours l’intégralité du produit.
Puis-je téléverser des images de produit ?
Oui. Si une image est déjà disponible à une URL HTTPS publique durable, placez cette URL dans la liste images du produit ou dans le champ image d’une variante. Les URL HTTPS S3 publiques fonctionnent. Les chemins bruts s3:// et les URL signées de courte durée ne fonctionnent pas.
Pour que Shoply héberge le fichier, téléversez les octets bruts de l’image depuis votre backend :
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY
Content-Type: image/pngEnvoyez les octets bruts du fichier, et non du JSON, du base64 ou des données de formulaire multipart. Les formats JPEG, PNG et WebP sont acceptés, jusqu’à 10 MiB et 20 millions de pixels. Les images animées ne sont pas prises en charge. Shoply convertit l’image en WebP et supprime les métadonnées intégrées.
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 renvoie url, content_type, size_bytes, width et height. Téléverser une image seule ne l’attache pas à un produit et ne demande pas d’indexation. Incluez l’URL renvoyée dans un produit complet et soumettez-le à nouveau via /merchant/products/batch.
La même image téléversée à nouveau pour le même compte réutilise son URL. Une image modifiée reçoit une nouvelle URL. Il n’existe pas de point de terminaison de suppression d’image dans cette version.
Quand les produits apparaissent-ils dans le chat et la recherche ?
Après un enregistrement par lot réussi, Shoply demande une reconstruction d’index en arrière-plan. Les réponses indiquent index_status: "pending" jusqu’à ce que le worker publie le nouvel index. Il n’existe aucune garantie de délai d’achèvement fixe.
- Les produits publiés entrent à la fois dans la recherche produit et dans les connaissances utilisées par le chat SiteChat.
- Les produits brouillon et archivés sont exclus lors de la prochaine reconstruction.
- Si l’indexation n’a pas été planifiée (
index_status: "request_failed"), relancez le lot pour les produits déjà stockés avec succès.
Quelles erreurs dois-je prévoir ?
| Statut HTTP | Signification |
|---|---|
403 | Secret absent, invalide, expiré ou révoqué ; mauvaise boutique ; ou compte non-SiteChat |
404 | Le produit importé demandé n’existe pas |
413 | La requête ou l’image dépasse la limite de taille |
415 | Le téléversement d’image a utilisé un Content-Type non pris en charge |
422 | Champs invalides, IDs dupliqués, images animées ou trop volumineuses, ou limites du modèle dépassées |
503 | Échec temporaire de stockage |
Les secrets expirent après 90 jours. Créez un remplacement dans Settings → Store owner API secret avant l’expiration, et révoquez tout secret dont vous n’avez plus besoin. Le même secret peut également appeler les points de terminaison d’analytics, de conversations et de connaissances documentés dans le guide Merchant API.
Pour obtenir de l’aide sur une intégration, contactez Shoply AI.
