weaverse-content-api について
認証付きREST APIを通じてWeaverseのプロジェクトコンテンツを読み書きするスキルです。コンテンツ担当者や自動化処理向けに、即時編集、下書き、公開、予約、バージョン復元の手順を権限範囲とともに扱います。
主な機能
- 01ページとテーマ設定の読み書き
- 02ロケール翻訳の管理
- 03ページコンテンツの一括編集
- 04下書きの保存とレビュー公開
- 05公開予約やバージョン復元
- 06プロジェクトの作成、複製、管理
活用シーン
- 01複数ページの文言を一括更新
- 02AI生成文や翻訳をプロジェクトに反映
- 03編集内容を確認して公開または予約
- 04公開履歴を調べて以前の版を復元
MCP 対応
APIは委任型MCP OAuthトークンを受け付けますが、このスキルパック自体はMCPサーバーのホストやコネクターの有効化を行いません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ weaverse/ shopify-hydrogen-skills --skill weaverse-content-apiインストール後、Claude Code で/weaverse-content-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/endpoints.mdportable-text.mdscripts/weaverse_content_api.mjs詳細
Weaverse Content API
Studio エディターの外部から、認証済み REST API を使用して Weaverse のコンテンツ(プロジェクト、ページ、テーマ設定、翻訳)を読み取り、編集できます。一括編集、AI/自動化コンテンツパイプライン、下書きのステージングから公開までのフロー、予約またはバージョン管理されたコンテンツ変更に使用します。
- ベース URL:
https://studio.weaverse.io/api/v1/content - 機械可読仕様:
GET https://studio.weaverse.io/api/v1/content/openapi.json(OpenAPI 3.1、認証不要)— 正式な仕様です。フィールド単位の正確なスキーマを確認するには取得してください。このスキルはワークフローガイドです。 - エンドポイントの詳細:
references/endpoints.md。リッチテキスト/Portable Text の詳細:references/portable-text.md。 - ヘルパースクリプト:
scripts/weaverse_content_api.mjs(依存関係なし、Node 18 以降)。
最初に理解しておくべき重要事項
すべての書き込みが公開されるわけではありません。API には 3 種類の書き込みモデルがあります。
- ライブ編集 —
PATCH .../pages/:type/*handle(アイテムデータ)、PATCH .../theme-settings、および翻訳の書き込みは即時に適用され、キャッシュを無効化してapi.weaverse.io経由で公開されます。Studio で保存した場合と同じ経路です。 - ステージングされた書き込みと明示的な反映 — ページの下書き(
GET/PUT/DELETE .../page-drafts/:pageId)、グローバルセクションの下書き(op=save-draft/discard-draft)、保留中バージョンの置き換え(PUT /versions/{versionId}、CAS による保護あり。下書きは拒否されます)は、それだけではライブコンテンツを変更しません。反映はライブ書き込みです。POST /publish-versions/{versionId}(保存済みの下書きを公開)、POST /versions/{versionId}/publish-now(予約済みバージョンを即時公開)、またはPOST /versions/{versionId}/restore(ライブコンテンツを即時に上書き — 確認が必要なロールバック)を使用します。POST /versions/{versionId}/scheduleも何も起こらない操作ではありません。追加の呼び出しなしでpublishAtに自動的なライブ変更を確定するため、すでに予約済みのバージョンをPUTで置き換えた場合も、その時刻にライブへ反映されます。これらすべてにcontent:publishが必要です(復元にはcontent:deleteも必要です)。 - プロジェクトのライフサイクル —
POST /projectsとop=create|copy|delete|set-settings|purge-cache(スコープproject:manage。削除にはcontent:deleteとconfirmも必要です)。API からプロジェクトを作成できます。空のプロジェクト、テーマを適用したプロジェクト、またはこのショップ自身のプロジェクトや公開デモストアのプロジェクトのバックグラウンドコピーを作成できます。
ライフサイクルは次のとおりです。
Create project → POST /projects (op=create) — or start from Weaverse Builder / demo store
Create initial pages → import a project JSON into Studio (generating-weaverse-project-json)
OR create pages one by one via POST /projects/:projectId/pages
Update content → live PATCH (item edits, theme settings) when immediacy is wanted
OR draft → review → publish / schedule when it must be gated
Fix a bad publish → restore a version (confirm-gated) or re-PATCH
使用する場面
- AI が生成した、または翻訳した文言を既存のライブプロジェクトに反映する
- 多数のページ/アイテムにわたってコンテンツを一括編集する
- 差分比較や往復更新のために、現在のページコンテンツ/アイテムを読み取る
- ページに新しい型付きアイテムを追加する(新しい ID に
typeを指定したPATCHを使用)か、childrenを再リンクする CUSTOMページ、またはリソースに紐づくテンプレートページを作成する(POST /projects/:projectId/pages)- 編集内容を下書きとしてステージングし、即時公開、予約公開、または破棄する
- 以前のページ/テーマバージョンを復元する、または公開履歴を確認する
- ページ単位のロケール別翻訳、またはプロジェクト全体の翻訳単位を読み書きする
- プロジェクトを作成/コピー/削除する、または名前/デフォルトロケールを変更する(
POST /projectsのライフサイクル操作) - ページを一括削除する
- 画像/動画を Shopify にアップロードし、その CDN URL を Weaverse アイテムで参照する
認証
openapi.json を除くすべてのエンドポイントで、ベアラートークンが必要です。
Authorization: Bearer <WEAVERSE_API_KEY>
- Weaverse Studio → Dashboard → Account/Settings → API Keys からショップキーを取得します。環境変数(
WEAVERSE_API_KEY)に保存してください。ハードコードしないでください。また、ローカルテスト以外では?apiKey=クエリパラメーターとして渡さないでください。クエリパラメーターはサーバー/CDN のログに記録される可能性があります。 - ショップキーは 1 つのショップに限定されます。別のショップが所有するプロジェクトへのリクエストは失敗します(403/404 — API は他のテナントの情報を開示しません)。
- 同じトークンで Shopify プロキシも認証できます(「Shopify へのリソースのアップロード」を参照)。
スコープとトークンの種類
bearerAuth スキームでは、ショップ API キー、スコープ付き API キー、委任された MCP OAuth トークン、または(翻訳ユニットのルートのみ)プロジェクトに紐付けられた翻訳エージェントトークンを受け付けます。スコープは次のとおりです。
| スコープ | 許可される操作 |
|---|---|
content:read | プロジェクト、ページ、テーマ設定、バージョン、下書き、翻訳ユニットの読み取り |
content:write | 下書きと非破壊的な編集(アイテム、メタデータ、SEO、割り当て、言語、用語集)の保存。明示的な公開/スケジュール/復元/削除のエンドポイントは呼び出せません。ただし、ライブ編集(PATCH .../pages/...、ページ作成)はすぐにストアフロントに反映されます |
content:publish | 下書きの公開、公開のスケジュール設定/再スケジュール/キャンセル、バージョンの復元、グローバルセクションの公開 |
content:delete | ページ/グローバルセクション/言語/静的キーの削除、上書きの取り消し。プロジェクトの削除には project:manage との併用が必要です |
project:manage | プロジェクトの作成/コピー/削除、設定、バリアント、階層、バックアップ、プレビュー、ホスト名ポリシーの管理 |
translations:read / translations:write | 翻訳ユニットのルートのみ。一般的なコンテンツへのアクセス権はありません |
- スコープ付き認証情報に必要なスコープがない場合は、何も書き込まれずに
403 INSUFFICIENT_SCOPEが返されます。 - 従来のスコープなしキーは、読み取り/書き込み/翻訳の基本アクセス権と、スコープ導入前のすべてのエンドポイントを引き続き利用できます。ただし、暗黙的に公開/削除/プロジェクト管理の権限を得ることはありません。例外は、従来から利用できる一括ページ削除のアクセス権です(スコープ導入前に発行されたキーでは、引き続き
DELETE .../pagesが機能します)。このようなキーは破壊的な操作が可能なものとして扱い、スコープ付きキーに置き換えてください。 - 委任された(MCP OAuth)トークンで書き込みを行う場合は、リビジョントークンを送信する必要があります。ページのパッチでは
expectedUpdatedAt、テーマ設定ではexpectedRevisionが必要です。省略すると428 PRECONDITION_REQUIREDが返されます。API キーでは省略できますが、送信することが引き続き安全な既定の方法です。 - スコープ付きキーは、タスクに必要な権限だけに絞って発行できます(例:翻訳エージェント向けの
content:readとtranslations:write)。そのため、キーが漏洩したりスクリプトが暴走したりしても、削除や公開はできません。自動化にはこの方法を優先してください。
仕様で委任された MCP OAuth トークンが受け付けられるのは、認証上の事実にすぎません。MCP サーバーのホスティングや Claude/ChatGPT コネクターの掲載は別途有効化が必要であり、このスキルパックでは行いません。
ライブ更新の基本ワークフロー
編集する前にお読みください。 既存のコンテンツを変更するには、実在するアイテム ID を指定する必要があるため、まずページを読み取ってください。確認せずにパッチを適用することはできません。新しいアイテムだけは例外です。新しいアイテムには新しい ID と type を指定し、ページツリーに適合させる必要があります(children の参照先は、ページ上にすでに存在する ID、または同じリクエスト内で作成される ID でなければなりません)。
- プロジェクトを見つける —
GET /projectsを実行し、名前で照合してidを保持します。 - ロケールを選ぶ —
GET /projects/:projectId/languagesを実行します。isDefault: trueのコード(例:en-us)を保持してください。data: []は有効な状態です。プロジェクトに設定済みの言語がなく、すべてがベースロケールに存在することを意味します。コードを推測したり、作り出したりしないでください。明示的にlocale=en-usを指定して読み取ると、フォールバックチェーンを通じてベースページにアクセスできます。 - ページを読み取る —
GET /projects/:projectId/pages/:type/*handle?locale=<code>を実行します。必ずlocaleを渡してください。 解決時には、要求されたロケール → プロジェクトのデフォルト →en-defaultの順にフォールバックします。そのため、ロケールを省略しても処理が成功し、別のロケールのページが返されることがあります。そのまま編集すると、誤ったページに変更が適用されます。デフォルトのweaverse形式では、すべてのアイテムとそのidがすでに返されます。この ID がパッチに必要な値です(?meta=trueが必要なのは、portable-textの読み取りの場合のみです)。レスポンスのupdatedAtを保持してください。これはパッチで使う楽観的同時実行制御のトークンです。 - パッチを作成する — 各アイテムについて、
data内には変更するフィールドだけを送信します(浅いマージが行われ、ネストされたオブジェクトは全体が置き換えられます)。各エントリにはidとdataの両方が必要です。トポロジーのみを再リンクする場合でもdataは省略できないため、"data": {}を指定してください。新しいアイテムを作成するには、新しいidとtypeを指定します。読み取り時と同じlocaleと、読み取り時のupdatedAtをexpectedUpdatedAtとして含めてください。{ "locale": "en-us", "expectedUpdatedAt": "2026-10-21T12:00:00.000Z", "items": [ { "id": "itm1", "data": { "heading": "New heading" } }, { "id": "itm-new", "type": "Hero", "data": { "heading": "Fresh section" }, "children": [{ "id": "itm1" }] } ] } - パッチを適用する —
PATCH /projects/:projectId/pages/:type/*handleを実行します(クライアントやプロキシがPATCHのボディを送信できない場合は、POST も使用できます)。1 リクエストあたり最大 100 個のアイテムです。より大きな編集は分割してください。"exact": trueを追加すると、ロケール/ハンドルのフォールバックを拒否し、保存されている(type, handle, locale)が指定先と完全に一致する割り当てだけに書き込みます(委任された書き込みは常に exact です)。 - レスポンスを確認する —
{ object: "page_update", requested, updated, created, notFound, failed, updatedIds, createdIds, notFoundIds, failedIds }。notFoundIdsが空でない場合、該当 ID は解決されたページ上にありません(ページ/ロケールの誤り、古い ID、またはtypeを指定せずに送信された新しい ID)。正しいロケールで再度読み取り、確認せずに再試行しないでください。failedIdsは、リクエスト途中で古さが検出され、結果が未確認のアイテムです。再度読み取ってこれらを適用し、適用済みだと決めつけないでください。
古いデータに対する拒否: 読み取り後にページが変更されていた場合(例:Studio で同時に保存された場合)、書き込みが行われる前にリクエスト全体が 409 STALE_PAGE で拒否されます。再読み取りし、新しい内容を基に変更を適用してください。同じパッチを再試行してはいけません。テーマ設定も expectedRevision を使用し、同様に動作します(409 STALE_PROJECT)。
ライブパッチが成功するとキャッシュが無効化され、Studio での保存と同じ経路で api.weaverse.io を通じて配信されます。レスポンスが不明瞭な場合(failedIds、または公開/削除時の cacheDelivery: "degraded")は、成功を報告する前にリソースを再読み取りして実際の状態を確認してください。
新規ページまたは空のページを 1 回のリクエストで設定する
POST /pages で作成したページ(または空のテンプレート)には、ルートの main アイテムしかありません。インポート形式の JSON からページ全体を構築するには、次の手順を実行します。
- ページを読み取り、ルートの
mainアイテム ID を取得します。 - 1 回の PATCH(100 アイテム以下)で、ルートの
{ "id": <rootId>, "data": {}, "children": [...] }(dataは空でも必須)と、id、type、data、childrenを指定したすべてのセクション/ブロックを新しいアイテムとして送信します。 updated: 1, created: N, notFound: 0となることを確認します。
ページごとに新しい ID を使用してください(別のページや以前のテストレンダーで使った ID を再利用しないでください)。この方法で送信されたコンテンツは Studio のインポート処理を経由しないため、スキーマの プリセットは適用されません。デフォルト以外の値はすべて data に指定してください。
テーマ設定
PATCH /projects/:projectId/theme-settings に { "theme": { ...changedKeys } } を指定すると、トップレベルのテーマキーが浅くマージされます(ネストされたオブジェクトは全体が置き換えられるため、先に読み取ってください)。プロジェクト独自の設定のみを書き込み、復元可能な ThemeVersion を記録します。GET のレスポンスに含まれる revision を expectedRevision として送信してください。テーマキーはグローバルです。商品カードのキーを変更すると、サイト内のすべての商品カードにスタイルが適用されます。レスポンスには、マージ後のテーマ全体と updatedKeys が含まれます。
ページのメタデータ(名前、SEO)
GET/POST /projects/:projectId/page-settings/:pageId — op=rename(name/prefix)、op=rename-custom(name + handle、assignmentId)、op=set-seo(seo オブジェクト)。SEO はここで書き込み可能です。ページコンテンツの PATCH には含まれません。
下書き → 公開のワークフロー
変更をすぐに公開せず、レビューや承認を経る必要がある場合は、下書きを使用します。指定には pageId を使用します。ロケールやハンドルへのフォールバックはないため、下書きが別の割り当てに適用されることはありません。
- 基準を読み取る —
GET /projects/:projectId/page-drafts/:pageId。下書きヘッドが存在する場合は現在の下書きヘッドを、存在しない場合は公開中のコンテンツを返します。また、保存時に再送するリビジョントークンheadVersionId、pageUpdatedAt、projectUpdatedAtも返します。下書きヘッドがある場合、ページとプロジェクトのトークンは、その下書きの作成基準となったリビジョンです。公開中の内容がそれ以降に更新されていると、保存は拒否されます。 - 下書きを保存する —
PUT .../page-drafts/:pageIdに項目の全リスト(項目数は 200 以下。各項目にはidと、任意でtype/data/childrenを指定。形式が不正なグラフは 400)と、3 つのexpected*トークンを GET のレスポンスとまったく同じ値で指定します(nullもそのまま含めてください)。下書きヘッド、公開中のページ、またはプロジェクトが更新されている場合は409 STALE_PAGEで拒否されます。何も保存されないため、再読み込みしてください。公開中の内容には一切触れません。 - 公開する —
{ "projectId", "pageId" }を指定してPOST /publish-versions/:versionIdを実行します(既存の予約済みバージョンをアトミックに置き換える場合は、任意でreplaceScheduledVersionIdを指定します)。Studio での公開と同じ昇格処理およびキャッシュへの反映が行われます。content:publishが必要です。公開のコミット後にキャッシュの無効化が失敗した場合は、cacheDelivery: "degraded"が返されます。コンテンツは変更済みで、配信はキューに登録されています。 - または破棄する — ヘッドに対する完全一致の CAS で
DELETE .../page-drafts/:pageIdを実行します。
グローバルセクション
GET /projects/:projectId/global-sections は、使用箇所とともにセクションの一覧を返します。POST .../global-sections で { itemId, name } を指定すると、セクションを作成します。各セクションでは、GET .../global-sections/:sectionId で下書きヘッド(存在しない場合は null)を読み取れます。POST .../global-sections/:sectionId は op=save-draft/discard-draft/publish-draft/rename/delete を実行します。save-draft/discard-draft には content:write、publish-draft には content:publish、delete には content:delete と confirm="<sectionId>" が必要です。save-draft には項目の全リストと expectedHeadVersionId CAS トークンを指定します。
バージョン:履歴、スケジュール、復元
- 一覧 —
GET /projects/:projectId/versions?pageId=<id>(そのページのバージョン)、?kind=theme(テーマのバージョン)、?kind=retired-pages(退役したページのバージョン、復元用)、デフォルトの?kind=scheduled(現在のスケジュール、ページ+テーマ)。 - 1 件を取得 —
GET /versions/:versionId?type=page|theme&projectId=<id>。 - スケジュール —
POST /versions/:versionId/schedule{ projectId, type, publishAt }(ページのバージョンではreplaceScheduledVersionIdも指定可能。テーマでは 400 で拒否されます)。バージョンはpublishAtに自動的に公開されます。追加の呼び出しは不要です。スケジュール設定は、変更を公開する承認として扱ってください。publishAtは未来の日時である必要があります。ページまたはプロジェクトにすでにスケジュール済みのバージョンがある場合は409となり、変更はありません。 - 移動/キャンセル — スケジュール済みの公開に限り、
PATCH /versions/:versionId(再スケジュール)およびDELETE /versions/:versionId(キャンセル)を使用します。バージョンがすでにスケジュールされていない場合は409/404 になります。 - 今すぐ公開 —
POST /versions/:versionId/publish-now{ projectId, type }。 - 復元 —
POST /versions/:versionId/restore{ projectId, type, confirm: "<versionId>" }。復元すると公開中のコンテンツが上書きされるため、content:publishとcontent:deleteの両方に加え、確認文字列が必要です。通常の編集ではなく、マーチャントが承認したロールバックとして扱ってください。409(同時に変更が適用され、何も変更されなかった)の場合は、決して再実行しないでください。バージョンと公開対象を再取得し、現在の状態についてマーチャントに再確認してください。
翻訳
プロトコルは 2 種類あり、どちらも Translation 行だけを書き込みます。ベースページのコンテンツ、アイテム、その他すべてのロケールには影響せず、プロジェクトのデフォルト言語を翻訳先に指定することはできません(他の言語の翻訳元となる言語です)。
- ページ単位 —
GET /projects/:projectId/page-translations/:pageId?locale=<code>は、翻訳可能なキーすべてについて、source、現在のtranslation、および書き戻し時に再送する必要があるtargetGenerationを返します。同じ URL にPOSTし、translation以外のエントリをそのまま返します(1 リクエストにつき ≤250 件)。各エントリは、対象となるsourceと読み取ったtargetGenerationの両方に対して比較後に設定されます。遅れて処理されたエージェントが、マーチャントによる新しいソーステキストや別の書き込み元による新しい翻訳を上書きすることはありません。拒否されたエントリはstaleに返され、書き込まれていません。translation: ""はキーをクリアします(未翻訳の状態とは区別されます)。書き込み後は、再度 GET して結果を読み取ってください。 - プロジェクト全体のユニット —
GET /projects/:projectId/translation-units?targetLocale=<code>(kind=text|image、status、カーソルページング)では、保存済みのプロジェクトスキーマで承認されたすべてのユニットを一覧表示します。保存済みスキーマのないコンポーネントや、その他の入力型のフィールドは一覧に表示されず、書き込みもできません。POST /projects/:projectId/translations/validateは、書き込みを一切行わずにすべてのチェックを実行します(ドライラン)。POST .../translations/applyは、プロジェクトのロック下でバッチをアトミックに書き込みます。ソース/翻訳先のいずれかが古い場合、バッチ全体が拒否され(409 STALE_TRANSLATION)、何も書き込まれません。同じ内容で再試行すると、変更なしの状態に収束します。これらのルートは、プロジェクトに紐づく翻訳エージェントトークン(translations:read/translations:writeのみ)も受け付けます。
プロジェクトのライフサイクル
op を指定した POST /projects(スコープ project:manage):
op | Body | 効果 |
|---|---|---|
create | name?、projectId?、config.themeName? | 空のプロジェクト、またはテーマをシードしたプロジェクト |
copy | sourceProjectId、name? | バックグラウンドで複製(202 + targetProjectId)。ソースは、このショップ所有のプロジェクトか、公開デモストアのプロジェクトである必要があります。複製の完了は、複製先のページ一覧で確認できます |
delete | projectId、confirm(= projectId) | 削除前のバックアップを伴う論理削除。content:delete も必要です |
set-settings | projectId、expectedUpdatedAt、name?、defaultLocale? | リビジョンで保護された、機密情報以外の設定 |
purge-cache | projectId | Studio の「キャッシュをクリア」 |
PATCH /projects/:projectId はプロジェクト名を変更します(name のみ。未知のフィールドは 400)。作成/複製/削除の前にマーチャントに確認してください。これらは、1 ページのコンテンツだけでなく、アカウントレベルの状態を変更します。
Content API ではできないこと
- Shopify のリソースを販売チャネルに公開すること — プロキシトークンには
read_publications/write_publicationsがありません。 - API キーでマーケット設定を行うこと —
PATCH /projects/:projectIdで受け付けるのはnameのみです。(階層 — バリアント、親へのリンク/切り離し、ページのオーバーライド — はproject:manageの権限で専用ルートPOST /projects/:projectId/hierarchyを通じて書き込み可能です。破壊的な操作には確認が必要です。詳しくはreferences/endpoints.mdをご覧ください。)
ページの指定方法
ページは、ページタイプとハンドルの組み合わせで指定します。
INDEX, PRODUCT, ALL_PRODUCTS, COLLECTION, COLLECTION_LIST, PAGE, BLOG,
ARTICLE, CART, CUSTOMER, NOT_FOUND, PASSWORD, SEARCH, CUSTOM
- シングルトン(
INDEX、ALL_PRODUCTS、COLLECTION_LIST、CART、CUSTOMER、NOT_FOUND、PASSWORD、SEARCH) — プロジェクトごとに1ページです。ハンドルは省略してください。 - CUSTOM — パスで指定します(スプラットにはスラッシュを含められます。例:
blogs/news)。 - テンプレート化されたページ(
PRODUCT、COLLECTION、PAGE、BLOG、ARTICLE) — 空のハンドルには共有のデフォルトテンプレートがあるため、ハンドルを省略すると拒否されます(テンプレートが暗黙に編集されることはありません)。実際のハンドルを渡してください。 - 実際のハンドルを指定しても、リソースごとのページがあるとは限りません。
…/pages/PRODUCT/<real-handle>の読み取りは、リソースごとのオーバーライドが存在しなくても成功します(200)。リゾルバーはそのタイプの共有デフォルトテンプレートにフォールバックし、返されるidはその共有ページを示します。この状態で PATCH すると、そのタイプのすべてのリソースが表示するテンプレートが編集されます。PATCH の前に返されたidを確認してください。変更を1つのリソースに限定する場合は、先にリソースごとのオーバーライドを作成します(POST /pagesは共有デフォルトを複製します)。共有テンプレートを意図的に編集するのも問題ありませんが、その点を理解したうえで行ってください。
ロケールは常に重要です。 読み取り/更新時には、実際の locale コードを必ず渡してください(List languages から取得します)。list-pages のレスポンスでは、マーケット優先のプロジェクトの場合、行の locale が null のことがあります(行はロケールではなくマーケットをキーにしています)。null をそのまま返さず、実際のコードを渡してください。解決処理によってマーケットにマッピングされます(例:locale=en-us はマーケット us に解決されます)。
エンドポイント一覧、クエリパラメーター、レスポンスの形式については references/endpoints.md をご覧ください。
Shopify にリソースをアップロードする
Content API 自体にアップロードエンドポイントはありません。メディアを Weaverse アイテムに追加するには、まず Shopify にアップロードしてから、返された CDN URL を参照します。
アップロードには、同じ Weaverse トークンを受け付ける Weaverse Shopify プロキシを使用します。
POST https://studio.weaverse.io/api/admin-graphql
Authorization: Bearer <WEAVERSE_API_KEY>
Content-Type: application/json
本文は通常の Shopify Admin GraphQL リクエストです({ "query": "...", "variables": {...} })。アップロードでは、Shopify の標準的な2段階のフローを使用します。
stagedUploadsCreate→urlとparameters(事前署名済みの送信先)、およびresourceUrlを取得します。- 返された
parametersを使って、ステージングされたurlにファイルのバイトデータをアップロードします(マルチパート POST。プロキシ経由ではありません)。 originalSource: <resourceUrl>を指定してfileCreateを実行します。Shopify がファイルを取り込み、永続的な CDN ファイルを返します。- ファイルの
image.url/sourcesを読み取り、上記の更新ワークフローを使ってその CDN URL を Weaverse アイテムのdataに設定します。
ビルダーリポジトリにある参照実装:app/backend/admin/file.server.ts(generateStagedUploadLinks → stagedUploadsCreate、続いて fileCreate)。判断に迷った場合は、そのミューテーションとフィールド選択を参考にしてください。
代わりに、接続済みの Shopify MCP が利用可能な場合は、その画像アップロード/
graphql_mutationツールを使えば、プロキシを介さずに同じ処理を行えます。接続されているものを使用してください。
ヘルパースクリプトの upload コマンドは、4つのステップをすべて実行し、ファイルごとに CDN URL、ID、サイズを出力します。プロキシへの呼び出しには User-Agent ヘッダーを付けてください。ヘッダーがないリクエストは 403 で拒否されます。プロキシは通常の Admin GraphQL エンドポイントであるため、トークンで許可されている他の Admin ミューテーション(ナビゲーションメニューの menuUpdate、fileDelete など)も利用できます。
ヘルパースクリプト
scripts/weaverse_content_api.mjs は認証と一般的な API 呼び出しをラップします。環境変数 WEAVERSE_API_KEY を読み込みます。
export WEAVERSE_API_KEY=...
node scripts/weaverse_content_api.mjs projects
node scripts/weaverse_content_api.mjs languages <projectId>
node scripts/weaverse_content_api.mjs theme <projectId>
node scripts/weaverse_content_api.mjs theme-update <projectId> <theme.json> # flat { "key": value }; the script wraps it in { theme } and replays the current revision as expectedRevision (409 STALE_PROJECT on a concurrent change)
node scripts/weaverse_content_api.mjs pages <projectId> [type]
node scripts/weaverse_content_api.mjs page <projectId> <type> [handle] [locale] # reads with ?locale
node scripts/weaverse_content_api.mjs create-page <projectId> <type> <handle> [name]
node scripts/weaverse_content_api.mjs update <projectId> <type> [handle] <patch.json> # omit handle for INDEX & other singletons
node scripts/weaverse_content_api.mjs delete <projectId> <type> <handle...>
node scripts/weaverse_content_api.mjs delete-ids <projectId> <pageId...> # projects without languages
node scripts/weaverse_content_api.mjs upload <file...> # → Shopify Files, prints CDN URLs
これを使ってプロジェクトをすばやく確認し、パッチファイルを適用してください。スクリプトで対応していない操作(下書き、公開、バージョン、翻訳、ライフサイクル操作)については、REST エンドポイントを直接呼び出す(references/endpoints.md を参照)か、openapi.json を確認してください。
注意事項
- 書き込みがステージングされていると思い込む — 下書きの保存(
PUT page-drafts、グローバルセクションのsave-draft)と保留中バージョンのPUT /versions/{id}だけは、それ単独ではライブに反映されません(置き換えられた予約済みバージョンは、publishAtにライブに反映されます)。content:writeのみで行うライブアイテムのPATCHとPOST /pagesは、ストアフロントに即時反映されます。scheduleはpublishAtに自動反映され、publish-versions/publish-now/restoreは即時反映されます。 - マーチャントの承認なしにプロジェクトを作成/コピー/削除する — ライフサイクル操作(
project:manage、削除にはcontent:deleteとconfirmも必要)は、アカウントレベルの状態を変更します。op=copyは202を返し、バックグラウンドで処理を続けます。完了を確認するには、コピー先のページ一覧を取得してください。 - バージョンを安易に復元する —
POST /versions/:id/restoreはライブコンテンツを上書きします(content:publish、content:delete、およびconfirm="<versionId>"が必要です)。マーチャントが承認したロールバックに限ってください。 409 STALE_PAGE/STALE_PROJECT/STALE_TRANSLATIONの拒否に対し、同じ内容をそのまま再試行する — リソースが更新されています。再読み込みし、新しいコンテンツを基に編集内容を作り直してから書き込んでください。page_updateのfailedIdsは結果未確認の項目を示します。何かを決めつける前に、それらの項目を再読み込みしてください。- 委任された(MCP OAuth)トークンで
expectedUpdatedAt/expectedRevisionを省略する —428 PRECONDITION_REQUIREDが返されます。API キーでは省略できますが、指定して送るのが安全なデフォルトです。 - ページの読み取り/更新で
localeを省略する — 解決時は、リクエストされた言語 → デフォルト →en-defaultの順でフォールバックするため、リクエストは別の言語のページに対して成功し、編集内容が「見つからない」ように見えることがあります(PAGE_NOT_FOUNDとは異なります)。必ず「言語の一覧」から実際のコードを渡してください。書き込み時にフォールバックを確実に防ぐには"exact": trueを使用してください。 - PATCH で新しいアイテム ID を
typeなしで送る — 未知の ID はtypeが指定されている場合にのみ作成されます。指定がなければnotFoundIdsに入ります。childrenの ID は、すでにページ上に存在するか、同じリクエスト内で作成する必要があります。 - ID を先に読み取らず、既存のアイテムにパッチを適用する — 実在するアイテム ID を指定する必要があります。先にページを読み込んでください(正しい
localeを指定してください)。weaverse形式の読み取りには、すべてのアイテムのidが含まれているため、?meta=trueは不要です。 dataのない、子要素のみのエントリを送る —itemsの各エントリにはdataオブジェクトが必要です。トポロジーのみの変更でも"data": {}を送信してください(item.data must be an object)。- 「言語の一覧」の
data: []をエラーとみなす(または言語を推測する) — 空のリストは、設定済みの言語がないことを意味します(ベースロケールのレイアウト)。ロケールをでっち上げないでください。明示的にen-usを指定すると、フォールバックチェーンを通じてベースページに到達します。 locale: nullをそのまま返す — マーケット優先のプロジェクトでは、list-pages の行の値がnullになることがあります。nullは送らず、実際のコードを渡して解決時にマーケットへマッピングさせてください。- 通常の編集で
?meta=trueを追加する — これはportable-textの読み取りにのみ影響します。weaverse形式の読み取りでは何も変わりません。 - レスポンスの
notFoundIds/staleを無視する — 指定した ID が解決されたページに存在しないか、ソース/ターゲットが更新されています。正しいロケールで再読み込みするか、GET を再実行してください。同じペイロードを再試行しないでください。 - 1 回の更新で 100 件を超えるアイテムを送る(下書き保存は 200 件、翻訳は 250 件、削除対象は 500 件)— リクエストを分割してください。
- ハンドルが空のテンプレート型を編集する — 仕様上、拒否されます。実際のハンドルを渡してください。
- トークンをハードコードする、または
?apiKey=を使用する — 環境変数からAuthorization: Bearerを使用してください。自動化には、ショップ全体のキーではなくタスク限定のキーを発行してください。 dataオブジェクト全体を置き換える — 更新は浅いマージで行われます。変更したフィールドのみを送信してください。読み取っていないネスト値を消してしまう危険があるため、data全体を再送しないでください。- 「アップロード」後に Shopify 以外の URL をメディアフィールドに入れる —
fileCreateの手順を完了し、ステージング用/一時的なresourceUrlではなく、返された Shopify CDN URL を使用してください。 - 一括削除に
locale: ""を送る — 拒否されます("locale" cannot be an empty string)。言語が設定されていないプロジェクトでは、pageIds(delete-ids)で削除してください。 - PATCH の直後にローカル開発環境のレンダリング結果を信頼する — 実行中の Hydrogen 開発サーバーには、以前にレンダリングしたアイテム ID のキャッシュが残っている場合があり、ページに古いデータが表示されることがあります。パッチが適用されていないと判断する前に、開発サーバーを再起動するか、デプロイ済みのストアフロントで確認してください。
- デプロイ済みコードにまだ存在しないセクションをライブページにパッチする — 新しいセクションタイプや設定は、コードがデプロイされるまで本番環境で正しく表示されません。先にデプロイするか、デプロイの直前にパッチを適用する場合は、その旨を伝えてください。
- バックアップなしでグローバルテーマキーを変更する —
theme-updateの前にGET theme-settingsで現在の値を保存してください(そのrevisionは CAS トークンも兼ねます)。ThemeVersions は Studio またはバージョンの復元機能から復元できます。 - theme-update のファイルを
{ "theme": … }で囲む — スクリプトはすでにラップしているため、これを行うと設定ではなく、余分なthemeキーが書き込まれます。レスポンスのupdatedKeysを確認してください。
関連スキル
generating-weaverse-project-json— この API が後から更新する構造を定義したインポート JSON を作成します。ここでパッチするアイテム ID は、その JSON(または適切なlocaleを指定して読み込んだページ)から取得します。cloning-websites-to-weaverse/figma-to-weaverse— JSON ジェネレーターに渡すセクションプランを作成します。hydrogen-markets-localization— この API の翻訳ルートが対応する、マーケット/ローカライズのエンドツーエンドのワークフローです。