SiteChat 向けにカタログをアップロードする方法
ご自身のウェブサイト上で SiteChat を使用している場合(Shopify ストアではない場合)、構造化された商品レコードを Shoply に送信して、購入者が SiteChat のチャットや商品検索でそれらを見つけられるようにできます。
これらのエンドポイントは、他の Shoply Merchant API と同じ Settings → Store owner API secret を使用し、SiteChat 管理画面の Product Catalog ページは、サインイン済みの管理者アクセストークンでそれらを呼び出せます。Shopify ストアは引き続き Shopify を通じてカタログデータを同期します。これらのアップロード用ルートは、すでに Magento カタログを同期していない SiteChat アカウントでのみ利用できます。
SiteChat 管理画面では、Product Catalog を開くと、Shopify 風の Products、Collections、Inventory の領域が表示されます。商品を追加または編集したり、CSV/Excel をインポートしたり、商品を手動コレクションにまとめたり、在庫数量を調整したりできます。
利用できる API は何ですか?
| API | Method | 何をするか |
|---|---|---|
/merchant/products/batch | POST | 1 回のリクエストで最大 50 件の商品を作成または完全置換します |
/merchant/products | POST | 1 件の商品を作成または完全置換します |
/merchant/products | GET | source と external_id で、取り込み済みの商品 1 件を読み戻します |
/merchant/products | PATCH | 商品 1 件を部分更新します(read-merge-write) |
/merchant/products | DELETE | 商品をソフトアーカイブします(status=archived) |
/merchant/products/list | GET | 管理画面のテーブル向けに、取り込み済み商品をページングして取得します |
/merchant/products/images | POST | 商品画像をアップロードし、公開 HTTPS URL を受け取ります |
/merchant/collections | GET / POST | 手動コレクションを一覧表示または作成します |
/merchant/collections/{id} | GET / PUT / DELETE | コレクション 1 件を読み取り、置換、またはアーカイブします |
/merchant/inventory | GET | 在庫行(商品およびバリアント数量)を一覧表示します |
/merchant/inventory/adjust | POST | 商品またはバリアントの追跡在庫数量を設定します |
商品保存が成功すると、Shoply にストアインデックスの再構築が要求されます。その再構築が完了するまで、レスポンスには index_status: "pending" が返されます。その後、公開済み商品は商品インデックスと SiteChat チャットで使用されるナレッジの両方に表示されます。
これらの API は誰が使えますか?
- あなたのストアは SiteChat アカウントである必要があります(
app_platformは SiteChat)。 - Shopify ストアのキー(任意の
*.myshopify.comドメインを含む)は拒否されます。 - 認証には、有効なストアオーナー API シークレット、またはリクエスト内の正確な
store_keyに対する SiteChat 管理者アクセストークンのいずれかを使用する必要があります。 - Shopify Admin API トークンでは、これらのルートを呼び出せません。
オーナーシークレットの作成またはローテーションは、他の Merchant API 連携と同じ方法で行います: How to Use the Shoply Merchant API。SiteChat 管理コンソールでは、Product Catalog を開いて、商品、コレクション、在庫の管理、または CSV / Excel ファイルのインポートを行えます。シークレットを自分で管理する必要はありません。
認証はどのように機能しますか?
サーバーコネクタから
信頼できるバックエンドから HTTPS 経由で API を呼び出します。Authorization ヘッダーには JSON 文字列を入れます:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"store_owner_api_secrete": "YOUR_STORE_OWNER_API_SECRET"
}store_owner_api_secrete は、歴史的なスペルを含む公開フィールド名です。store_owner_api_secret も受け付けられます。これは Bearer トークンではありません。
SiteChat 管理画面から
Product Catalog ページでは、代わりにサインイン済みの管理者セッションを送信します:
{
"store_key": "YOUR_SITECHAT_STORE_KEY",
"admin_auth_token": "YOUR_SITECHAT_ACCESS_TOKEN"
}access_token は admin_auth_token の別名として受け付けられます。
store_key クエリパラメータは、ヘッダーと一致している必要があります。オーナーシークレットはサーバーサイドの環境変数にのみ保存してください。ストアフロントのスクリプト、URL、または公開リポジトリには絶対に置かないでください。
export SHOPLY_STORE_KEY="your-sitechat-store-key"
export SHOPLY_STORE_OWNER_API_SECRETE="shoply_owner_key_example123.secret-value"商品をアップロードするにはどうすればよいですか?
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"}
}
]
}
]
}必須フィールドとルール
- 必須の商品フィールド:
external_id、title、url、currency、price、available。statusのデフォルトはpublishedです。 - 任意の在庫: 商品またはバリアントに
tracks_inventoryをtrue、かつ 0 以上のquantityを設定します。すると Shoply は在庫から可用性を導出し(quantity > 0)、管理一覧用にtotal_inventoryを保存します。 sourceはカタログ接続名を表します(必ずしもプラットフォームではありません)。woocommerce-mainのような安定した名前を使用してください。使用可能な文字: 英小文字、数字、アンダースコア、ハイフン。最大 64 文字です。管理画面でフォームから作成された商品は、デフォルトで sourceadminになります。- 商品の識別子は、ストア、source、external ID の組み合わせです。バッチおよび単一の
POSTアップサートは 完全置換 であり、パッチではありません。省略された任意フィールドはクリアされます。部分更新にはPATCHを使用してください。 - バッチには 1~50 件の商品を含めることができ、リクエストサイズは最大 2,000,000 バイトです。各商品の検証済み JSON は 128,000 バイトまで、バリアントは最大 250 件です。
- 価格には 10 進文字列を推奨します。通貨は 3 文字の大文字コードです。
- 商品 URL と画像 URL は HTTP(S) である必要があります。インポート時にそれらの URL を自動取得することはありません。
- 検索可能な商品仕様には公開
metafieldsを使用してください(SiteChat における Shopify 商品メタフィールド相当)。値はプレーンな文字列である必要があります。旧来のattributesも別名として受け付けられます。非公開の商品metadataは現在サポートされていません。 draftおよびarchivedの商品は、次回の公開インデックスから除外されます。売り切れの公開済み商品は、可用性情報付きで引き続きインデックスされます。- 手動コレクションには、タイトル、説明、ステータス、および商品の所属リスト(
source+external_id)が保存されます。スマート / ルールベースのコレクションは、このリリースではサポートされていません。
成功レスポンスの例
{
"results": [
{
"external_id": "123",
"product_id": "sitechat_product::woocommerce-main::<sha256-of-external-id>",
"status": "stored"
}
],
"index_status": "pending",
"index_revision": 1
}Shoply は書き込み前にリクエスト全体を検証します。HTTP 200 であっても、一部の failed 結果に error: "storage_error" が含まれる場合があります。各結果を必ず確認し、失敗した商品を再試行してください。index_status が request_failed の場合、保存には成功していますがインデックス処理がスケジュールされていません。その場合も保存済みの商品を再試行してください。
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")取り込まれた商品を確認するにはどうすればよいですか?
GET https://api.shoplyai.ai/merchant/products?store_key=YOUR_SITECHAT_STORE_KEY&source=woocommerce-main&external_id=123
同じ Authorization ヘッダーを使用します。レスポンスには schema_version、updated_at、index_status、および正規化された product が含まれます。レコードが存在しない場合は HTTP 404 が返ります。
バックグラウンドのインデクサーが再構築を公開すると、商品ごとの読み戻しステータスは indexed、excluded(draft または archived 商品の場合)、または limit_exceeded になります。管理一覧には GET /merchant/products/list を使用してください。次回の公開インデックスから商品を除外したい場合は、DELETE /merchant/products でソフトアーカイブするか(または status を archived / draft に設定してください)。このリリースではハードデリートはありません。
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"])商品画像をアップロードできますか?
はい。画像がすでに永続的な公開 HTTPS URL で利用可能な場合は、その URL を商品の images リスト、またはバリアントの image フィールドに入れてください。公開 S3 の HTTPS URL は利用できます。生の s3:// パスや短期間で失効する署名付き URL は利用できません。
Shoply にファイルをホストさせるには、バックエンドから生の画像バイトをアップロードします:
POST https://api.shoplyai.ai/merchant/products/images?store_key=YOUR_SITECHAT_STORE_KEY
Content-Type: image/png送信するのは 生のファイルバイト であり、JSON、base64、multipart form data ではありません。JPEG、PNG、WebP が受け付けられ、上限は 10 MiB、2,000 万ピクセル です。アニメーション画像はサポートされていません。Shoply は画像を WebP に変換し、埋め込みメタデータを削除します。
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 では url、content_type、size_bytes、width、height が返されます。画像のみをアップロードしても、それだけでは商品への関連付けやインデックス要求は行われません。返された URL を完全な商品データに含め、/merchant/products/batch を通じて再度送信してください。
同じアカウントに対して同じ画像を再度アップロードすると、URL は再利用されます。画像が変更されている場合は、新しい URL が発行されます。このリリースには画像削除エンドポイントはありません。
商品はいつチャットと検索に表示されますか?
バッチ保存が成功すると、Shoply はバックグラウンドでインデックス再構築を要求します。ワーカーが新しいインデックスを公開するまでは、レスポンスに index_status: "pending" が返されます。完了時間の固定保証はありません。
- 公開済み商品は、商品検索と SiteChat チャットで使われるナレッジの両方に追加されます。
- 下書き商品とアーカイブ済み商品は、次回の再構築で除外されます。
- インデックス処理がスケジュールされていない場合(
index_status: "request_failed")、すでに保存に成功している商品についてバッチを再試行してください。
想定されるエラーは何ですか?
| HTTP status | 意味 |
|---|---|
403 | シークレットがない、無効、期限切れ、失効済み、ストアが違う、または SiteChat 以外のアカウント |
404 | 要求された取り込み済み商品が存在しません |
413 | リクエストまたは画像がサイズ制限を超えています |
415 | 画像アップロードで未対応の Content-Type が使用されました |
422 | 無効なフィールド、重複 ID、アニメーション画像や oversized 画像、またはモデル制限超過 |
503 | 一時的な保存失敗 |
シークレットの有効期限は 90 日 です。有効期限前に Settings → Store owner API secret で置き換え用を作成し、不要になったシークレットは失効させてください。同じシークレットは、Merchant API guide に記載されている分析、会話、ナレッジの各エンドポイントも呼び出せます。
連携についてサポートが必要な場合は、Shoply AI にお問い合わせください。
