Cum să îți încarci catalogul pentru SiteChat

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

Dacă folosești SiteChat pe propriul tău website (nu un magazin Shopify), poți trimite înregistrări structurate de produse către Shoply, astfel încât cumpărătorii să le poată găsi în chatul SiteChat și în căutarea de produse.

Aceste endpointuri folosesc același Settings → Store owner API secret ca restul API-ului Shoply Merchant, iar pagina Product Catalog din adminul SiteChat le poate apela cu tokenul tău de acces admin atunci când ești autentificat. Magazinele Shopify continuă să sincronizeze datele catalogului prin Shopify; aceste rute de încărcare sunt disponibile doar pentru conturile SiteChat care nu sincronizează deja un catalog Magento.

În adminul SiteChat, Product Catalog deschide o zonă în stil Shopify cu Products, Collections și Inventory. Poți adăuga sau edita produse, importa CSV/Excel, grupa produse în colecții manuale și ajusta cantitățile din stoc.

Ce API-uri sunt disponibile?

APIMetodăCe face
/merchant/products/batchPOSTCreează sau înlocuiește complet până la 50 de produse într-o singură cerere
/merchant/productsPOSTCreează sau înlocuiește complet un produs
/merchant/productsGETCitește un produs importat după source și external_id
/merchant/productsPATCHActualizează parțial un produs; înlocuirea variantelor sau a metafield-urilor necesită versiunea din GET
/merchant/productsDELETEArhivează logic un produs (status=archived)
/merchant/products/listGETParcurge paginat produsele importate pentru tabelele din admin
/merchant/products/imagesPOSTÎncarcă o imagine de produs și primește un URL public HTTPS
/merchant/collectionsGET / POSTListează sau creează colecții manuale
/merchant/collections/{id}GET / PUT / DELETECitește, înlocuiește sau arhivează o colecție
/merchant/inventoryGETListează rândurile de stoc (cantități pentru produse și variante)
/merchant/inventory/adjustPOSTSetează cantitatea urmărită pentru un produs sau o variantă

Salvările reușite de produse cer Shoply să reconstruiască indexul magazinului. Până când reconstrucția se finalizează, răspunsurile raportează index_status: "pending". Produsele publicate apar apoi atât în indexul de produse, cât și în baza de cunoștințe folosită de chatul SiteChat.

Cine poate folosi aceste API-uri?

  • Magazinul tău trebuie să fie un cont SiteChat (app_platform este SiteChat).
  • Cheile magazinelor Shopify (inclusiv orice domeniu *.myshopify.com) sunt respinse.
  • Autentificarea trebuie să folosească fie un secret API valid de proprietar al magazinului, fie un token de acces admin SiteChat pentru exact store_key din cerere.
  • Tokenurile Shopify Admin API nu pot apela aceste rute.

Creează sau rotește secretul proprietarului în același mod ca pentru alte integrări Merchant API: Cum să folosești Shoply Merchant API. În consola de administrare SiteChat, deschide Product Catalog pentru a gestiona produse, colecții și inventar — sau pentru a importa un fișier CSV ori Excel — fără să gestionezi tu însuți secretul.

Cum funcționează autentificarea?

Dintr-un conector server

Apelează API-ul dintr-un backend de încredere prin HTTPS. Pune un șir JSON în headerul Authorization:

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

store_owner_api_secrete este numele public al câmpului, inclusiv ortografia istorică. store_owner_api_secret este de asemenea acceptat. Acesta nu este un token Bearer.

Din adminul SiteChat

Pagina Product Catalog trimite în schimb sesiunea ta de admin autentificată:

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

access_token este acceptat ca alias pentru admin_auth_token.

Parametrul de interogare store_key trebuie să corespundă cu headerul. Păstrează secretele proprietarului doar în variabile de mediu de pe server — niciodată într-un script de storefront, într-un URL sau într-un repository public.

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

Cum încarc produse?

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

Câmpuri necesare și reguli

  • Câmpuri obligatorii pentru produs: external_id, title, url, currency, price și available. status are implicit valoarea published.
  • Inventar opțional: setează tracks_inventory la true și o quantity nenegativă pe produs sau pe variantă. Shoply deduce apoi disponibilitatea din stoc (quantity > 0) și stochează total_inventory pentru listele din admin.
  • source denumește conexiunea catalogului (nu neapărat o platformă). Folosește un nume stabil precum woocommerce-main. Caractere permise: litere mici, cifre, underscore și cratimă; maximum 64 de caractere. Produsele create din formular în admin folosesc implicit sursa admin.
  • Identitatea produsului este combinația dintre magazin, sursă și ID extern. Operațiile upsert POST batch și single sunt înlocuiri complete, nu patch-uri: câmpurile opționale omise sunt șterse. Folosește PATCH pentru actualizări parțiale.
  • Batch-urile conțin între 1 și 50 de produse și cel mult 2.000.000 de bytes în cerere. JSON-ul validat al fiecărui produs este limitat la 128.000 de bytes, cu maximum 250 de variante.
  • Preferă șiruri zecimale pentru prețuri. Moneda este un cod cu trei litere majuscule.
  • URL-urile produselor și imaginilor trebuie să fie HTTP(S). Importul nu preia aceste URL-uri în locul tău.
  • Folosește metafields publice pentru specificații de produs care pot fi căutate (echivalentul SiteChat pentru metafield-urile de produs Shopify). Valorile trebuie să fie șiruri simple. attributes, varianta legacy, este acceptată ca alias. metadata privată pentru produse nu mai este suportată.
  • Produsele draft și archived sunt omise din următorul index publicat. Produsele publicate, dar epuizate, rămân indexate cu informația de disponibilitate atașată.
  • Colecțiile manuale stochează un titlu, o descriere, un status și o listă de apartenențe de produse (source + external_id). Colecțiile smart/bazate pe reguli nu sunt suportate în această versiune.

Exemplu de răspuns de succes

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

Shoply validează întreaga cerere înainte de a scrie datele. Un HTTP 200 poate totuși să listeze unele rezultate failed cu error: "storage_error". Inspectează fiecare rezultat și reîncearcă produsele eșuate. Dacă index_status este request_failed, stocarea a reușit, dar indexarea nu a fost programată — reîncearcă și produsele deja stocate.

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

Cum verific un produs importat?

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

Folosește același header Authorization. Răspunsul include schema_version, updated_at, index_status și product normalizat. Înregistrările lipsă returnează HTTP 404.

După ce indexatorul din fundal publică o reconstrucție, statusul de recitire per produs devine indexed, excluded (pentru produse draft sau arhivate) ori limit_exceeded. Folosește GET /merchant/products/list pentru listarea în admin. Fă soft-archive cu DELETE /merchant/products (sau setează status la archived / draft) pentru a ține un produs în afara următorului index publicat; în această versiune nu există 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"])

Cum actualizez în siguranță variantele sau metafield-urile?

Pentru un PATCH care conține variants, metafields sau câmpul legacy attributes, citește mai întâi produsul cu GET. Construiește modificarea pornind de la acel răspuns și include valoarea sa updated_at de nivel superior ca expected_updated_at în corpul PATCH. Acest lucru se aplică și atunci când golești variantele sau metafield-urile.

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 înseamnă că versiunea lipsea sau că o altă actualizare a modificat produsul. Citește cea mai recentă versiune a produsului și îmbină din nou modificările dorite înainte de a reîncerca. Nu atașa o versiune nouă unei liste vechi de variante: asta ar putea suprascrie valori de stoc mai noi.

Integrările existente care fac PATCH acestor câmpuri fără o versiune trebuie actualizate. Cererile PATCH doar cu scalari, ajustările dedicate de inventar și înlocuirile complete prin POST sau import batch nu necesită acest câmp. Înlocuirile complete înlocuiesc în continuare întregul produs.

Pot încărca imagini de produs?

Da. Dacă o imagine este deja disponibilă la un URL public HTTPS stabil, pune acel URL în lista images a produsului sau în câmpul image al unei variante. URL-urile publice HTTPS S3 funcționează. Căile brute s3:// și URL-urile semnate cu durată scurtă nu funcționează.

Pentru ca Shoply să găzduiască fișierul, încarcă bytes-ul brut al imaginii din backendul tău:

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

Trimite bytes-ii brut ai fișierului, nu JSON, base64 sau date multipart form. Sunt acceptate JPEG, PNG și WebP, până la 10 MiB și 20 de milioane de pixeli. Imaginile animate nu sunt suportate. Shoply convertește imaginea în WebP și elimină metadatele încorporate.

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 returnează url, content_type, size_bytes, width și height. Încărcarea unei imagini de una singură nu o atașează la un produs și nu solicită indexare. Include URL-ul returnat într-un produs complet și retrimite-l prin /merchant/products/batch.

Aceeași imagine încărcată din nou pentru același cont își reutilizează URL-ul. O imagine modificată primește un URL nou. În această versiune nu există endpoint pentru ștergerea imaginilor.

Când apar produsele în chat și căutare?

După o salvare batch reușită, Shoply solicită o reconstrucție de index în fundal. Răspunsurile raportează index_status: "pending" până când workerul publică noul index. Nu există o garanție fixă privind timpul de finalizare.

  • Produsele publicate intră atât în căutarea de produse, cât și în baza de cunoștințe folosită de chatul SiteChat.
  • Produsele draft și arhivate sunt excluse la următoarea reconstrucție.
  • Dacă indexarea nu a fost programată (index_status: "request_failed"), reîncearcă batch-ul pentru produsele care au fost deja stocate cu succes.

La ce erori ar trebui să mă aștept?

HTTP statusSemnificație
403Secret lipsă, invalid, expirat sau revocat; magazin greșit; sau un cont care nu este SiteChat
404Produsul importat solicitat nu există
413Cererea sau imaginea depășește limita de dimensiune
415Încărcarea imaginii a folosit un Content-Type nesuportat
422Câmpuri invalide, ID-uri duplicate, imagini animate sau supradimensionate ori limite ale modelului depășite
503Eșec temporar de stocare

Secretele expiră după 90 de zile. Creează un înlocuitor în Settings → Store owner API secret înainte de expirare și revocă orice secret de care nu mai ai nevoie. Același secret poate apela și endpointurile de analytics, conversation și knowledge documentate în ghidul Merchant API.

Pentru ajutor cu o integrare, contactează Shoply AI.