Come caricare il tuo catalogo per SiteChat

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

Se utilizzi SiteChat sul tuo sito web (non su un negozio Shopify), puoi inviare record di prodotto strutturati a Shoply affinché gli acquirenti possano trovarli nella chat di SiteChat e nella ricerca prodotti.

Questi endpoint usano lo stesso Impostazioni → Secret API del proprietario del negozio del resto della Shoply Merchant API, e la pagina Product Catalog dell’amministrazione di SiteChat può richiamarli con il tuo token di accesso admin autenticato. I negozi Shopify continuano a sincronizzare i dati del catalogo tramite Shopify; queste route di caricamento sono disponibili solo per gli account SiteChat che non sincronizzano già un catalogo Magento.

Nell’amministrazione di SiteChat, Product Catalog apre un’area in stile Shopify con Products, Collections e Inventory. Puoi aggiungere o modificare prodotti, importare CSV/Excel, raggruppare prodotti in collezioni manuali e regolare le quantità di stock.

Quali API sono disponibili?

APIMetodoCosa fa
/merchant/products/batchPOSTCrea o sostituisce completamente fino a 50 prodotti in una richiesta
/merchant/productsPOSTCrea o sostituisce completamente un prodotto
/merchant/productsGETLegge un prodotto importato in base a source e external_id
/merchant/productsPATCHAggiorna parzialmente un prodotto; la sostituzione di varianti o metafield richiede la versione da GET
/merchant/productsDELETEArchivia logicamente un prodotto (status=archived)
/merchant/products/listGETScorre i prodotti importati per le tabelle admin
/merchant/products/imagesPOSTCarica un’immagine prodotto e restituisce un URL HTTPS pubblico
/merchant/collectionsGET / POSTElenca o crea collezioni manuali
/merchant/collections/{id}GET / PUT / DELETELegge, sostituisce o archivia una collezione
/merchant/inventoryGETElenca le righe di stock (quantità di prodotti e varianti)
/merchant/inventory/adjustPOSTImposta la quantità tracciata per un prodotto o una variante

I salvataggi riusciti dei prodotti chiedono a Shoply di ricostruire l’indice del negozio. Finché quella ricostruzione non termina, le risposte riportano index_status: "pending". I prodotti pubblicati compaiono quindi sia nell’indice prodotti sia nella knowledge usata dalla chat di SiteChat.

Chi può usare queste API?

  • Il tuo negozio deve essere un account SiteChat (app_platform è SiteChat).
  • Le chiavi dei negozi Shopify (incluso qualsiasi dominio *.myshopify.com) vengono rifiutate.
  • L’autenticazione deve usare un secret API del proprietario del negozio valido oppure un token di accesso admin di SiteChat per l’esatto store_key nella richiesta.
  • I token Shopify Admin API non possono richiamare queste route.

Crea o ruota il secret del proprietario nello stesso modo delle altre integrazioni Merchant API: Come usare la Shoply Merchant API. Nella console admin di SiteChat, apri Product Catalog per gestire prodotti, collezioni e inventario, oppure importare un file CSV o Excel, senza gestire direttamente il secret.

Come funziona l’autenticazione?

Da un connettore server

Richiama l’API da un backend attendibile tramite HTTPS. Inserisci una stringa JSON nell’header Authorization:

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

store_owner_api_secrete è il nome del campo pubblico, inclusa la grafia storica. Anche store_owner_api_secret è accettato. Non è un token Bearer.

Dall’amministrazione di SiteChat

La pagina Product Catalog invia invece la tua sessione admin autenticata:

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

access_token è accettato come alias di admin_auth_token.

Il parametro di query store_key deve corrispondere all’header. Conserva i secret del proprietario solo in variabili d’ambiente lato server, mai in uno script storefront, URL o repository pubblico.

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

Come carico i prodotti?

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

Campi obbligatori e regole

  • Campi prodotto obbligatori: external_id, title, url, currency, price e available. status predefinito è published.
  • Inventario opzionale: imposta tracks_inventory su true e una quantity non negativa sul prodotto o sulla variante. Shoply allora ricava la disponibilità dallo stock (quantity > 0) e memorizza total_inventory per gli elenchi admin.
  • source indica la connessione del catalogo (non necessariamente una piattaforma). Usa un nome stabile come woocommerce-main. Caratteri consentiti: lettere minuscole, numeri, underscore e trattini; fino a 64 caratteri. I prodotti creati da modulo nell’admin usano come predefinito la source admin.
  • L’identità del prodotto è la combinazione di negozio, source ed external ID. Gli upsert POST batch e singoli sono sostituzioni complete, non patch: i campi opzionali omessi vengono cancellati. Usa PATCH per aggiornamenti parziali.
  • I batch contengono 1–50 prodotti e al massimo 2.000.000 byte di richiesta. Il JSON validato di ciascun prodotto è limitato a 128.000 byte, con al massimo 250 varianti.
  • Preferisci stringhe decimali per i prezzi. La valuta è un codice maiuscolo di tre lettere.
  • Gli URL di prodotti e immagini devono essere HTTP(S). L’importazione non recupera quegli URL per te.
  • Usa metafields pubblici per specifiche di prodotto ricercabili (l’equivalente in SiteChat dei metafield prodotto di Shopify). I valori devono essere semplici stringhe. Il campo legacy attributes è accettato come alias. Il campo privato metadata del prodotto non è più supportato.
  • I prodotti draft e archived vengono esclusi dal successivo indice pubblicato. I prodotti pubblicati esauriti restano indicizzati con la disponibilità associata.
  • Le collezioni manuali memorizzano un titolo, una descrizione, uno stato e un elenco di appartenenze prodotto (source + external_id). Le collezioni smart/basate su regole non sono supportate in questa release.

Esempio di risposta di successo

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 l’intera richiesta prima di scrivere. Un HTTP 200 può comunque elencare alcuni risultati failed con error: "storage_error". Controlla ogni risultato e ritenta i prodotti non riusciti. Se index_status è request_failed, il salvataggio è riuscito ma l’indicizzazione non è stata pianificata: ritenta anche i prodotti già salvati.

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

Come verifico un prodotto importato?

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

Usa lo stesso header Authorization. La risposta include schema_version, updated_at, index_status e il product normalizzato. I record mancanti restituiscono HTTP 404.

Dopo che l’indicizzatore in background pubblica una ricostruzione, lo stato di rilettura per prodotto diventa indexed, excluded (per prodotti draft o archived), oppure limit_exceeded. Usa GET /merchant/products/list per l’elenco admin. Archivia logicamente con DELETE /merchant/products (oppure imposta status su archived / draft) per mantenere un prodotto fuori dal successivo indice pubblicato; in questa release non esiste una hard-delete.

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

Come aggiorno in sicurezza varianti o metafield?

Per una PATCH che contiene variants, metafields o il campo legacy attributes, leggi prima il prodotto con GET. Costruisci la modifica a partire da quella risposta e includi il suo valore updated_at di primo livello come expected_updated_at nel body della PATCH. Questo vale anche quando si cancellano varianti o metafield.

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 che la versione mancava oppure che un altro aggiornamento ha modificato il prodotto. Leggi il prodotto più recente e unisci di nuovo le modifiche desiderate prima di ritentare. Non allegare una nuova versione a un vecchio elenco di varianti: potrebbe sovrascrivere valori di stock più recenti.

Le integrazioni esistenti che eseguono PATCH di questi campi senza una versione devono essere aggiornate. Le richieste PATCH che riguardano solo scalari, le regolazioni di inventario dedicate e le sostituzioni complete tramite POST o import batch non richiedono questo campo. Le sostituzioni complete continuano comunque a sostituire l’intero prodotto.

Posso caricare immagini prodotto?

Sì. Se un’immagine è già disponibile a un URL HTTPS pubblico stabile, inserisci quell’URL nell’elenco images del prodotto o nel campo image di una variante. Gli URL HTTPS pubblici S3 funzionano. I percorsi s3:// grezzi e gli URL firmati di breve durata no.

Per fare in modo che Shoply ospiti il file, carica i byte grezzi dell’immagine dal tuo backend:

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

Invia i byte grezzi del file, non JSON, base64 o dati multipart form. Sono accettati JPEG, PNG e WebP, fino a 10 MiB e 20 milioni di pixel. Le immagini animate non sono supportate. Shoply converte l’immagine in WebP e rimuove i metadati incorporati.

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 restituisce url, content_type, size_bytes, width e height. Caricare solo un’immagine non la collega a un prodotto né richiede l’indicizzazione. Includi l’URL restituito in un prodotto completo e invialo di nuovo tramite /merchant/products/batch.

La stessa immagine caricata di nuovo per lo stesso account riutilizza il proprio URL. Un’immagine modificata riceve un nuovo URL. In questa release non esiste un endpoint per eliminare immagini.

Quando i prodotti compaiono nella chat e nella ricerca?

Dopo un salvataggio batch riuscito, Shoply richiede una ricostruzione dell’indice in background. Le risposte riportano index_status: "pending" finché il worker non pubblica il nuovo indice. Non esiste una garanzia di tempo fisso per il completamento.

  • I prodotti pubblicati entrano sia nella ricerca prodotti sia nella knowledge usata dalla chat di SiteChat.
  • I prodotti draft e archived vengono esclusi alla ricostruzione successiva.
  • Se l’indicizzazione non è stata pianificata (index_status: "request_failed"), ritenta il batch per i prodotti che erano già stati salvati con successo.

Quali errori devo aspettarmi?

HTTP statusSignificato
403Secret mancante, non valido, scaduto o revocato; negozio errato; oppure account non SiteChat
404Il prodotto importato richiesto non esiste
413La richiesta o l’immagine supera il limite di dimensione
415Il caricamento dell’immagine ha usato un Content-Type non supportato
422Campi non validi, ID duplicati, immagini animate o troppo grandi, oppure limiti del modello superati
503Errore temporaneo di storage

I secret scadono dopo 90 giorni. Crea un sostituto in Impostazioni → Secret API del proprietario del negozio prima della scadenza e revoca qualsiasi secret che non ti serve più. Lo stesso secret può anche richiamare gli endpoint analytics, conversation e knowledge documentati nella guida Merchant API.

Per ricevere aiuto con un’integrazione, contatta Shoply AI.