mcpField
W
weaverse-content-api

weaverse-content-api

github.com/weaverse开发9297 次安装2 周前更新
代码仓库

关于 weaverse-content-api

用于通过经过身份验证的 REST API 读取和编辑 Weaverse 项目内容的技能,适合内容运营与自动化流程。涵盖即时写入、草稿审核、发布和定时变更,并强调版本控制与权限范围。

主要功能

  1. 01读取和编辑页面及主题设置
  2. 02管理多语言翻译
  3. 03批量修改页面内容
  4. 04保存草稿并审核发布
  5. 05定时发布或恢复版本
  6. 06创建、复制和管理项目

适用场景

  1. 01批量更新多个页面的文案
  2. 02将 AI 生成或翻译内容写入项目
  3. 03审核后发布或安排内容变更
  4. 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.md
portable-text.md
scripts/
weaverse_content_api.mjs

详细介绍

Weaverse 内容 API

通过经过身份验证的 REST API,在 Studio 编辑器之外读取和编辑 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 有三种写入模式:

  1. 实时编辑 — PATCH .../pages/:type/*handle(条目数据)、PATCH .../theme-settings 和翻译写入会立即生效并使缓存失效,通过 api.weaverse.io 上线——与 Studio 保存操作走的是同一条路径。
  2. 暂存写入 + 显式发布 — 页面草稿(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)。
  3. 项目生命周期 — 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,并在 Weaverse 条目中引用其 CDN URL

身份验证

除 openapi.json 外,每个端点都需要 bearer token:

Authorization: Bearer <WEAVERSE_API_KEY>
  • 从 Weaverse Studio → Dashboard → Account/Settings → API Keys 获取商店密钥。将其存储在环境变量(WEAVERSE_API_KEY)中;切勿将其硬编码,也不要在本地测试以外的场景中将其作为 ?apiKey= 查询参数传递——查询参数会泄露到服务器/CDN 日志中。
  • 商店密钥仅适用于一个商店。请求其他商店拥有的项目会失败(403/404——API 不会披露其他租户的信息)。
  • 同一令牌也可授权 Shopify 代理(参见“将资源上传到 Shopify”)。
范围和令牌类型

bearerAuth 方案接受商店 API 密钥、带范围的 API 密钥、委派的 MCP OAuth 令牌,或(仅适用于翻译单元路由)绑定到项目的翻译 Agent 令牌。范围如下:

范围授予权限
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 密钥可以省略这些参数,但仍建议默认发送。
  • 带范围的密钥可以按任务严格限定权限(例如,为翻译 Agent 配置 content:read + translations:write),这样即使密钥泄露或脚本失控,也无法删除或发布内容。自动化任务应优先采用这种配置。

规范接受委派的 MCP OAuth 令牌,这只是关于身份验证的一项事实。托管 MCP 服务或列出 Claude/ChatGPT 连接器,是需要单独启用的功能,本技能包不会执行这些操作。

核心实时更新工作流

编辑前先阅读。 要更改现有内容,必须指定真实的项目条目 ID,因此请先读取页面——不能盲目打补丁。新增条目是唯一例外:它们使用全新的 ID 和一个 type,并且必须符合页面树结构(children 引用必须指向页面上已有的 ID,或在同一请求中创建的 ID)。

  1. 查找项目 — GET /projects,按名称匹配并记下其 id。
  2. 选择语言区域 — GET /projects/:projectId/languages。记下 isDefault: true 的代码(例如 en-us)。空的 data: [] 是有效状态:项目没有配置语言,所有内容都在基础语言区域中——不要猜测或编造代码;显式使用 locale=en-us 读取时,会通过回退链访问基础页面。
  3. 读取页面 — GET /projects/:projectId/pages/:type/*handle?locale=<code>。务必传入 locale。解析时会依次回退到请求的语言区域 → 项目默认语言区域 → en-default,因此缺少语言区域仍可能成功,但返回其他语言区域的页面——随后编辑就会落到错误的页面上。默认的 weaverse 格式已经返回每个条目的 id——补丁正需要这个 ID(只有读取 portable-text 时,?meta=true 才有用)。保留响应中的 updatedAt;它是补丁的乐观并发控制令牌。
  4. 构建补丁 — 对每个条目,只在 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" }] }
      ]
    }
    
  5. 应用补丁 — PATCH /projects/:projectId/pages/:type/*handle(如果客户端或代理无法发送 PATCH 请求体,也接受 POST)。每个请求最多 100 个条目——较大的编辑请分批处理。添加 "exact": true,以拒绝语言区域或句柄回退,并且只写入存储的 (type, handle, locale) 与请求目标完全一致的分配项(委托写入始终是精确匹配)。
  6. 检查响应 — { object: "page_update", requested, updated, created, notFound, failed, updatedIds, createdIds, notFoundIds, failedIds }。notFoundIds 非空 = ID 不在解析出的页面上(页面或语言区域错误、ID 过期,或发送的新 ID 缺少 type)——请用正确的语言区域重新读取,不要盲目重试。failedIds = 在请求中途检测到过期后,结果未能确认的条目——请重新读取并重新应用;不要假定它们已应用。

**过期拒绝:**如果页面在读取后发生变化(例如 Studio 中有并发保存),整个请求会在写入任何内容之前被拒绝,并返回 409 STALE_PAGE。请重新读取,并基于更新后的内容重新应用——绝不要重试相同的补丁。主题设置对 expectedRevision 也采用相同处理方式(409 STALE_PROJECT)。

成功的实时补丁会使缓存失效,并通过 api.weaverse.io 提供服务——与 Studio 保存所使用的路径相同。如果响应含糊不清(存在 failedIds,或发布/删除时出现 cacheDelivery: "degraded"),请重新读取资源以确认实际状态,然后再报告成功。

在一个请求中填充新建或空白页面

通过 POST /pages 创建的页面(或空白模板)只有一个根 main 条目。要从导入格式的 JSON 构建整个页面:

  1. 读取页面并获取根 main 条目的 ID。
  2. 发送一个 PATCH(≤100 个条目),包含:根条目 { "id": <rootId>, "data": {}, "children": [...] }(即使 data 为空也必须提供),以及作为新条目的每个 section/block,包含 id、type、data、children。
  3. 预期结果:updated: 1, created: N, notFound: 0。

每个页面都要使用全新的 ID(不要复用其他页面或先前测试渲染中的 ID)。通过这种方式发送的内容会跳过 Studio 的导入,因此不会应用 schema 预设——所有非默认值都必须包含在 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;SEO 不属于页面内容 PATCH。

草稿 → 发布工作流

当编辑需要审核或审批,而不是立即上线时,请使用草稿。通过 pageId 定位——不会回退到 locale/handle,因此草稿绝不会应用到其他 assignment。

  1. 读取依据 — GET /projects/:projectId/page-drafts/:pageId。如果存在草稿头,则返回当前草稿头;否则返回线上内容,同时返回保存时必须沿用的修订令牌:headVersionId、pageUpdatedAt、projectUpdatedAt。如果存在草稿头,页面和项目令牌是构建该草稿时依据的修订;线上内容一旦有更新,保存就会被拒绝。
  2. 保存草稿 — 使用完整项目列表(≤200 个项目,每项包含 id + 可选的 type/data/children;格式错误的图结构会返回 400)和 GET 原样返回的三个 expected* 令牌(包括原样传入的 null)调用 PUT .../page-drafts/:pageId。如果草稿头、线上页面或项目有更新,则会以 409 STALE_PAGE 拒绝保存——不会保存任何内容,请重新读取。绝不会触及线上内容。
  3. 发布 — 使用 { "projectId", "pageId" } 调用 POST /publish-versions/:versionId(可选传入 replaceScheduledVersionId,以原子方式替换已有的计划版本)。与 Studio 发布使用相同的提升和缓存扇出机制;需要 content:publish 权限。提交发布后若缓存失效操作失败,响应会报告 cacheDelivery: "degraded"——内容已更改,交付已排队。
  4. 或丢弃 — 通过与草稿头进行精确 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(当前计划发布,页面 + 主题)。
  • 读取单个版本 — 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(并发占用,未作任何更改)时,绝不要重放请求:重新读取版本和线上目标,并先就当前状态再次与商家确认。

翻译

有两种协议;两者都只写入 Translation 行 — 基础页面内容、条目和其他所有语言区域均保持不变;项目默认语言不能作为目标语言(它是其他语言进行翻译的源语言)。

  • 按页面翻译 — GET /projects/:projectId/page-translations/:pageId?locale=<code> 会返回每个可翻译键及其 source、当前 translation,以及写回时必须重放的 targetGeneration。对同一 URL 发送 POST,并原样回传条目,仅修改 translation(每次请求最多 250 条)。每个条目都会基于其对应的 source 和读取到的 targetGeneration 进行比较并设置 — 延迟的 Agent 绝不会覆盖商家更新后的源文本或其他写入者更新后的翻译;被拒绝的条目会出现在 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),且不会写入任何内容;重试相同请求会收敛为无变化。这些路由也接受绑定到项目的翻译 Agent 令牌(仅限 translations:read / translations:write)。

项目生命周期

使用 op 调用 POST /projects(权限范围 project:manage):

op正文效果
createname?、projectId?、config.themeName?创建空白项目或以主题为基础的项目
copysourceProjectId、name?在后台克隆(返回 202 + targetProjectId);源项目必须是本商店自有项目或公开的演示商店项目;通过列出目标项目的页面来确认完成
deleteprojectId、confirm(= projectId)软删除,并在删除前备份;还需要 content:delete
set-settingsprojectId、expectedUpdatedAt、name?、defaultLocale?设置带修订版本校验的非机密设置
purge-cacheprojectIdStudio 的“清除缓存”

PATCH /projects/:projectId 会重命名项目(仅限 name,未知字段会返回 400)。创建、复制或删除前请先征求商家同意 — 这些操作会更改账户级状态,而不只是单个页面的内容。

Content API 无法执行的操作
  • 将 Shopify 资源发布到销售渠道 — 代理令牌缺少 read_publications/write_publications 权限。
  • 通过 API 密钥设置市场设置 — PATCH /projects/:projectId 仅接受 name。(层级结构 — 变体、父级链接/解除链接、页面覆盖 — 可通过专用的 POST /projects/:projectId/hierarchy 路由在 project:manage 权限下写入;破坏性操作需要确认;详见 references/endpoints.md。)
页面寻址

页面通过页面类型 + handle 寻址:

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)— 每个项目只有一个页面,省略 handle。
  • CUSTOM — 通过其路径寻址(通配部分可包含斜杠,例如 blogs/news)。
  • 模板化页面(PRODUCT、COLLECTION、PAGE、BLOG、ARTICLE)— 将共享默认模板保留在空 handle 下,因此缺少 handle 时会被拒绝(不会静默编辑模板)。请传入真实的 handle。
  • 真实 handle 并不保证存在针对单个资源的页面。 即使不存在针对单个资源的覆盖,在读取 …/pages/PRODUCT/<real-handle> 时也会成功(200) — 解析器会回退到该类型的共享默认模板,返回的 id 标识该共享页面。随后执行 PATCH 会编辑该类型所有资源都会渲染的模板。PATCH 前请检查返回的 id;如果更改仅针对一个资源,请先创建针对该资源的覆盖(POST /pages 会克隆共享默认模板)。有意编辑共享模板也可以 — 请确认了解其影响。

Locale 始终重要。 读取/更新时,请始终传入真实的 locale 代码(来自 List languages)。在 list-pages 响应中,市场优先型项目的行的 locale 可能为 null(行按市场而非 locale 编号)— 不要将 null 原样传回;请传入真实代码,让解析器将其映射到市场(例如,locale=en-us 会解析到市场 us)。

完整的端点列表、查询参数和响应结构请参阅 references/endpoints.md。

将资源上传到 Shopify

Content API 本身没有上传端点。要将媒体添加到 Weaverse 项目,请先将其上传到 Shopify,然后引用返回的 CDN URL。

上传通过 Weaverse Shopify 代理进行,该代理接受相同的 Weaverse 令牌:

POST https://studio.weaverse.io/api/admin-graphql
Authorization: Bearer <WEAVERSE_API_KEY>
Content-Type: application/json

请求正文是标准的 Shopify Admin GraphQL 请求({ "query": "...", "variables": {...} })。上传遵循 Shopify 的标准两步流程:

  1. stagedUploadsCreate → 获取 url + parameters(预签名目标)以及 resourceUrl。
  2. 使用返回的 parameters 将文件字节上传到该暂存 url(multipart POST,不通过代理)。
  3. 使用 originalSource: <resourceUrl> 调用 fileCreate → Shopify 导入文件并返回永久 CDN 文件。
  4. 读取文件的 image.url / sources,并通过上述更新工作流将该 CDN URL 放入 Weaverse 项目 data 中。

builder 仓库中的参考实现:app/backend/admin/file.server.ts(generateStagedUploadLinks → stagedUploadsCreate,然后是 fileCreate)。如有疑问,请参照其中的 mutations 和字段选择。

或者,如果有已连接的 Shopify MCP,其图片上传 / graphql_mutation 工具也能完成相同工作,无需使用代理。使用已连接的工具即可。

辅助脚本的 upload 命令会执行全部四个步骤,并打印每个文件的 CDN URL、id 和大小。代理调用时请发送 User-Agent 标头 — 不带该标头的请求会被拒绝并返回 403。该代理是标准的 Admin GraphQL 端点,因此令牌允许的其他管理 mutations(例如用于导航菜单的 menuUpdate、fileDelete)也可以通过它执行。

辅助脚本

scripts/weaverse_content_api.mjs 封装了身份验证和常用调用。它会从环境变量中读取 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 不同)。务必传入 List languages 返回的真实代码;写入时使用 "exact": true,可确保不会发生回退。
  • 在 PATCH 中发送不带 type 的新条目 ID——只有在提供 type 时才会创建未知 ID;否则这些 ID 会进入 notFoundIds。children 中的 ID 必须已存在于页面上,或在同一请求中创建。
  • 未先读取 ID 就 PATCH 现有条目——必须指定真实的条目 ID。先读取页面(并使用正确的 locale);weaverse 格式的读取已包含每个条目的 id(无需 ?meta=true)。
  • 发送不带 data 的仅含 children 的条目——每个 items 条目都必须带有 data 对象;仅修改拓扑结构时也必须发送 "data": {}(item.data must be an object)。
  • 将 List languages 返回的 data: [] 视为错误(或猜测语言)——列表为空表示未配置语言(基础语言布局)。不要自行编造语言代码;显式传入 en-us 会通过回退链访问基础页面。
  • 原样回传 locale: null——对于优先按市场区分的项目,list-pages 的行中 locale 可能为 null。不要发送 null;传入真实代码,让解析过程映射到对应市场。
  • 普通编辑时添加 ?meta=true——它只影响 portable-text 读取。对于 weaverse 格式的读取,它不会产生任何变化。
  • 忽略响应中的 notFoundIds/stale——你的 ID 不在解析到的页面上,或源/目标已发生变化。使用正确的语言重新读取 / 重新运行 GET;不要重试相同的载荷。
  • 单次更新发送超过 100 个条目(草稿保存为 200 个,翻译为 250 个,删除目标为 500 个)——请拆分请求。
  • 编辑 handle 为空的模板化类型——这会按设计被拒绝。请传入真实的 handle。
  • 硬编码令牌或使用 ?apiKey=——请从环境变量中读取 Authorization: Bearer;自动化应使用任务范围的密钥,而非完整的商店密钥。
  • 替换整个 data 对象——更新采用浅合并。只发送发生变化的字段;不要重新发送整个 data,以免清除未读取的嵌套值。
  • “上传”后在媒体字段中放入非 Shopify URL——请完成 fileCreate 步骤,并使用返回的 Shopify CDN URL,而不是暂存/临时的 resourceUrl。
  • 批量删除时发送 locale: ""——会被拒绝("locale" cannot be an empty string)。对于未配置语言的项目,请通过 pageIds 删除(delete-ids)。
  • PATCH 后立刻相信本地开发渲染结果——正在运行的 Hydrogen 开发服务器可能会保留之前渲染过的条目 ID 的缓存副本,因此页面仍显示旧数据。下结论认为 PATCH 未生效之前,请重启开发服务器(或在已部署的店面上验证)。
  • 用已部署代码尚不支持的区段 PATCH 线上页面——在代码部署前,新的区段类型或设置在生产环境中会渲染异常。请先部署,或在部署前不久执行 PATCH 并说明情况。
  • 更改全局主题键却不备份——执行 theme-update 前,先从 GET theme-settings 保存当前值(其 revision 同时用作 CAS 令牌)。可在 Studio 中恢复 ThemeVersions,也可通过版本恢复功能恢复。
  • 将 theme-update 文件包装在 { "theme": … } 中——脚本本身已添加包装,因此这样会写入一个多余的 theme 键,而不是你的设置。请检查响应中的 updatedKeys。

相关技能

  • generating-weaverse-project-json — 创建导入 JSON,用于建立此 API 随后更新的结构。你在此处修改的项目 ID 来自该 JSON(或使用正确的 locale 读回的页面)。
  • cloning-websites-to-weaverse / figma-to-weaverse — 生成传递给 JSON 生成器的版块规划。
  • hydrogen-markets-localization — 此 API 的翻译路由所服务的端到端市场/本地化工作流。

评论

支持 Markdown