Skip to main content
API Reference

项目源码版本 API

查询项目历史源码版本,恢复指定版本,并处理恢复后的预览。

项目源码版本 API 用于查询项目的历史源码版本,并恢复指定版本。本文中的版本 ID 是项目源码的 Git 提交 ID,不是发布版本 ID。 恢复会基于历史源码创建新提交,保留已有历史,不会自动发布线上站点,也不会修改业务数据库。需要让恢复后的源码在线上生效时,请在恢复完成后单独发布项目。 基础地址:https://meoo.com/open/v1

接口概览

以下路径均相对于基础地址。
功能方法路径所需 Scope
查询历史源码版本GET/projects/{project_id}/source-versionssource.read
恢复源码版本POST/projects/{project_id}/source-versions/{version_id}/restoresource.write

调用约定

凭证获取和授权方式见认证与授权,JSON 格式、时间戳、错误包装和追踪 Header 见通用协议。请求使用 Authorization: Bearer;API Key 同样使用该 Header,不使用 X-API-Key。
  • source.read 与 source.write 相互独立,写 Scope 不包含读 Scope;同时使用两个接口时应同时申请。
  • 除 Scope 外,调用账号还必须具有项目对应的访问和代码操作权限。项目级凭证只能访问绑定的项目。
  • project_id 使用创建或查询项目时返回的 url_id。
  • 版本 ID 必须是完整的 40 位小写十六进制 Git 提交 ID,不接受短 SHA、分支名、标签或 HEAD。
  • 两个源码版本接口成功时均返回 200 OK,直接返回业务对象,不额外包裹 success 或 data。
  • 请求参数严格校验;本文的分页快照和恢复重试规则以各接口说明为准。恢复接口不要求 Idempotency-Key。
以下 cURL 示例使用完整 URL。${ACCESS_TOKEN} 表示有效的 Bearer 凭证;请将 demo-project、示例版本 ID 和分页令牌替换为真实值。各段示例不依赖前文设置的项目或基础地址变量。

查询历史源码版本

GET /projects/{project_id}/source-versions?page_size=20
所需权限:source.read。

请求参数

参数位置类型必填说明
project_idpathstring是项目的公开 url_id
page_sizequeryinteger否不传或传 0 时为 20;大于 100 时按 100 处理
page_tokenquerystring否原样传入上一页的 next_page_token;非空且最长 2048 字符
page_size 必须是非负十进制整数,且不大于 9007199254740991,不接受负数、小数或指数格式,建议传入 1 至 100。每个查询参数只能出现一次,不接受未知参数或数组值。

请求示例

查询第一页:
curl --request GET \
  --url "https://meoo.com/open/v1/projects/demo-project/source-versions?page_size=20" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Accept: application/json" \
  --max-time 180
继续翻页时,将 NEXT_PAGE_TOKEN 替换为上一页返回的令牌:
curl --get \
  --url "https://meoo.com/open/v1/projects/demo-project/source-versions" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Accept: application/json" \
  --data-urlencode "page_size=20" \
  --data-urlencode "page_token=NEXT_PAGE_TOKEN" \
  --max-time 180

响应字段

成功时返回 200 OK。
字段类型说明
versionsarray当前分页快照中的提交历史,按 Git 历史顺序返回,最近提交在前
versions[].version_idstring完整提交 ID,可作为恢复目标
versions[].messagestring提交说明
versions[].created_atinteger提交时间,Unix 毫秒时间戳
versions[].is_currentboolean是否为本次查询时的当前源码版本
current_version_idstring / null本次查询时的当前源码版本,恢复时用作并发校验条件
next_page_tokenstring可选;仅在还有下一页时返回

响应示例

{
  "versions": [
    {
      "version_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "message": "Update page layout",
      "created_at": 1791943200000,
      "is_current": true
    },
    {
      "version_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "message": "Initial version",
      "created_at": 1791939600000,
      "is_current": false
    }
  ],
  "current_version_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  "next_page_token": "<opaque-page-token>"
}
示例中的版本 ID 和分页令牌仅用于展示结构,不可直接用于真实请求。 项目尚无源码提交时,返回:
{
  "versions": [],
  "current_version_id": null
}

分页说明

  • 首次查询固定当时当前提交的历史快照。使用返回的令牌继续分页时,始终读取该快照;期间推送源码或恢复版本产生新提交,不会使令牌失效,也不会导致快照内条目重复或遗漏。
  • 分页结果不包含首次查询之后新增的提交。要查看最新提交,请从不带 page_token 的第一页重新查询。
  • current_version_id 和 is_current 反映本次请求时的最新源码版本,而非快照版本。新提交产生后,当前版本可能不在分页快照中,整页条目也可能都是 is_current: false;这不影响继续翻页。
  • 令牌绑定项目,不可跨项目复用、篡改或自行拼接。无效令牌返回 400 invalid_page_token,请重新查询第一页。
  • 网络或历史快照读取暂时失败时返回 503 service_unavailable,可稍后使用原令牌重试。
  • 没有 next_page_token 表示已到末页;不要将空字符串作为下一页令牌传回。
  • 项目长时间未使用时,首次查询可能需要较长时间,请设置合理的客户端超时。

恢复源码版本

POST /projects/{project_id}/source-versions/{version_id}/restore
所需权限:source.write。

恢复行为与前置条件

  • 目标版本必须来自当前项目的历史列表。
  • expected_current_version_id 必须与项目当前版本一致,否则返回 409 run_conflict。请重新查询并让用户确认,不要静默替换预期版本后强行恢复。
  • 项目不能有仍在运行、等待处理或取消中的生成任务;代码导入必须已完成,且没有其他源码推送或恢复操作。
  • 工作区必须没有未提交修改,包括新增文件、已暂存和未暂存修改。请先提交需要保留的源码;接口不提供强制覆盖选项。
  • 恢复期间请勿同时在网页端修改源码或安装组件;接口不提供跨所有编辑入口的事务隔离。
恢复历史版本时,会执行以下操作:
  1. 基于目标历史源码创建新的恢复提交,保留已有历史及项目当前的 Cloud 环境配置。
  2. 新建对话,并写入版本切换记录;不会自动发起 AI 生成。
  3. 执行与网页端相同的依赖安装和预览强制重启流程;移动应用同时触发安装包重建。接口会等待该流程完成,预览或安装包构建失败时返回错误。
纯技能或尚无可运行应用的历史源码会跳过预览启动,不保证关闭此前已运行的预览。 若目标版本已经是当前版本,且预期版本匹配,则直接跳过:不创建提交或对话,也不重启预览,返回 conversation_id: null。

请求参数

请求体使用 Content-Type: application/json。
参数位置类型必填说明
project_idpathstring是项目的公开 url_id
version_idpathstring是希望恢复的历史源码版本,使用列表返回的完整提交 ID
expected_current_version_idbodystring是最近一次查询得到的非空 current_version_id,防止覆盖其他人刚产生的新提交
{
  "expected_current_version_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
请求体只接受上述一个必填字段,不接受额外字段或查询参数。目标 version_id 仅通过路径传入。项目尚无源码版本时不能发起恢复。

请求示例

示例恢复目标为 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,预期当前版本为 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb。两者都应替换为查询得到的真实完整提交 ID。
curl --request POST \
  --url "https://meoo.com/open/v1/projects/demo-project/source-versions/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/restore" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{"expected_current_version_id":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}' \
  --max-time 180
180 秒为示例客户端超时,可按实际需要调整。依赖安装等处理可能耗时较长。请求超时或返回错误,不代表操作一定未生效;请先查询当前源码版本并核对源码和对话状态。

响应字段

成功时返回 200 OK。
字段类型说明
project_idstring本次操作的项目公开 ID
source_version_idstring本次恢复使用的历史源码版本 ID
current_version_idstring恢复后的实际当前源码版本 ID,通常是新创建的提交 ID
conversation_idstring / null新建对话 ID,包含版本切换记录;目标已是当前版本时为 null
后续操作应采用返回的新 current_version_id,不能继续使用恢复前的版本 ID,也不能假定它等于目标历史版本 ID。具备对应 Agent API 权限时,可使用返回的 conversation_id 继续对话。

响应示例

{
  "project_id": "demo-project",
  "source_version_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "current_version_id": "cccccccccccccccccccccccccccccccccccccccc",
  "conversation_id": "9e68e95e-12a2-4ba4-a83e-84328f354f21"
}

重复请求

  • 无需传入 Idempotency-Key。
  • 成功后 24 小时内,使用相同凭证、相同请求参数,且项目当前版本仍等于上次成功结果时,会复用已有结果,不再创建提交、对话或重启预览。更换凭证后不保证复用。
  • 源码恢复已完成但后续步骤失败时,只有当前版本未变化、工作区无未提交改动,且服务端保留了可继续处理的结果,原请求才能接续后续流程。
  • 依赖安装也可能产生未提交修改。例如目标源码没有 pnpm-lock.yaml 时,安装可能生成该文件;随后预览失败,再次调用恢复可能返回 409 run_conflict。请先核对当前源码与对话状态,不要循环重试或直接删除需要保留的文件。
  • 异常中断后可能已经产生提交或对话,不保证所有失败情形下重复请求都不会新增对话。无法确认实际结果时,请联系支持。
  • 重复请求仍受权限、任务状态和代码操作状态约束。如果之后又产生了新提交,旧请求通常返回 409 run_conflict。
  • 返回已有恢复结果不代表重新覆盖了一次源码。

恢复后预览未就绪

恢复请求超时或返回 503 时,源码与对话可能已经创建。确认源码已恢复、对话状态符合预期,且仅网页预览未就绪时,可单独获取预览链接,不需要再次恢复源码。
POST /projects/{project_id}/agent/preview-links
该接口额外需要 agent.read 权限。请求体可省略或传空对象 {},不接受额外字段,不会创建恢复提交或新对话。
curl --request POST \
  --url "https://meoo.com/open/v1/projects/demo-project/agent/preview-links" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{}' \
  --max-time 180
响应含义与处理
200,status: ready使用响应中的 url 访问预览;expires_at 为链接过期时间
202,status: starting启动仍在进行;按响应头 Retry-After 指定秒数等待,再次调用此预览接口,无需重新调用恢复接口
409 preview_not_ready当前项目暂不可预览,请检查项目是否具备可运行应用
503 service_unavailable稍后有限重试预览接口;持续失败时保留 trace_id 联系支持
独立预览接口不检查未提交源码修改,但会复用已健康运行的预览服务,不会强制重启。ready 表示预览服务可用,不代表已核验页面加载了指定源码版本,请实际访问并确认页面内容。该操作不能补齐未完成的对话创建,也不能替代移动应用安装包重建。 旧预览链接未过期且对应预览环境仍可用时,可以继续使用;预览进程已停止时,仅刷新旧链接不能代替启动预览。预览链接包含临时访问凭证,请勿写入公开日志或发送给无关人员。

限流

维度查询历史源码版本恢复源码版本
默认应用配额600 次 / 60 秒60 次 / 60 秒
单项目恢复频率不适用1 次 / 5 秒
两个源码版本接口分别计数,并受账号适用的其他调用额度约束。收到 429 时,至少等待响应头 Retry-After 指定秒数后再重试。

常见错误

源码版本接口的错误响应使用 Content-Type: application/problem+json:
{
  "type": "about:blank",
  "title": "Conflict",
  "status": 409,
  "detail": "当前源码版本已变化,请重新获取版本历史",
  "code": "run_conflict",
  "trace_id": "<request-trace-id>"
}
按 HTTP 状态码和 code 判断错误类别,不要依赖可能变化的 detail 文案。
HTTPcode常见原因与处理
400invalid_request参数重复、未知参数、非法分页大小、空或过长令牌、缺少字段、非法版本 ID 等;修正请求后提交
400invalid_page_token令牌被修改、跨项目使用或分页位置无效;从第一页重新查询。新增提交本身不会使令牌失效
401invalid_token凭证无效、过期或被撤销;更新凭证
403insufficient_scope缺少接口所需 Scope;补充授权
403forbidden账号不满足访问条件,或超出项目凭证范围;检查账号权限与绑定项目
404not_found项目不存在或无权访问、恢复项目尚无提交、目标不在可达历史中;核对项目与历史列表
409run_conflict版本已变化、任务或导入未完成、其他代码操作进行中,或工作区存在未提交修改;处理冲突后重新查询并确认
429temporarily_unavailable触发应用、项目或其他限流;按 Retry-After 退避
500server_error服务端异常;保留 trace_id,先确认实际结果再排查
503service_unavailable网络或快照读取失败、服务暂不可用、预览失败或恢复结果未确认。查询失败可用原令牌重试;恢复失败先核对源码与对话,仅预览未就绪时按“恢复后预览未就绪”小节单独获取预览,不要循环重试恢复请求
恢复请求超时或失败时,操作可能已部分或全部生效。如果错误提示源码保存失败,即使版本 ID 已变化,也应联系支持确认保存结果。反馈问题时请提供接口路径、请求时间、HTTP 状态码和 trace_id,不要提供 Token、API Key 或完整签名预览链接。

推荐接入流程

  1. 查询历史源码版本,按需继续分页并选择目标。
  2. 用户确认后再次查询当前版本;若已变化,提示重新确认,不静默替换预期版本。
  3. 确认任务和导入结束、没有其他代码操作,并处理需要保留的未提交修改。
  4. 将目标版本放入路径,请求体提交刚确认的 expected_current_version_id。
  5. 成功后采用返回的新 current_version_id,刷新历史、编辑器和对话,实际检查预览内容。
  6. 遇到冲突或失败先核对实际状态;若源码与对话已恢复、仅网页预览未就绪,单独调用预览接口。无法确认结果时联系支持。
  7. 需要更新线上站点时,再执行独立的发布流程。