> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 仅部署接入

# 仅部署接入：上传静态产物

适用于接入方已自行完成构建，只把静态产物交给 Meoo 托管并获得网站链接。当前支持根目录包含 `index.html` 的 zip；平台不启动沙箱，也不执行构建。

## 前置选择

按[认证与授权](https://app.mintlify.com/alibaba-b47c397f/alibaba-b47c397f/~/757c99e3-fa24-43b5-848e-3c86fe532fb0)选择身份。系统集成统一使用团队版：需要按最终用户隔离资源和审计时使用虚拟成员临时 Token；只识别一个大账号时使用团队 Owner 临时 Token。用户 API Key 仅用于个人测试，不推荐系统集成。最小 Scope：`project.write project.read release.write release.read`。

```text theme={null}
创建或选择项目
  → release prepare 获取一次性上传 URL
  → PUT 静态 zip 到对象存储
  → release complete 等待解压并审核文本、图片，通过后发布
  → 保存 access_url
```

## 1. 准备产物

```text theme={null}
ZIP_FILE=dist.zip
CONTENT_LENGTH=$(wc -c < "${ZIP_FILE}" | tr -d ' ')
CONTENT_MD5=$(openssl dgst -md5 -binary "${ZIP_FILE}" | openssl base64)
```

`content_length` 必传，用于提前限制大小并在完成发布时校验；MD5 可选，但推荐服务端接入携带。

## 2. 创建或选择项目

```text theme={null}
curl --request POST \
  --url "${MEOO_BASE_URL}/open/v1/projects" \
  --header "Authorization: Bearer ${MEOO_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{"name":"静态网站","type":"web"}'
```

保存 `project_id`，并在接入方服务端校验业务对象与项目的访问关系。

## 3. Release Prepare

```text theme={null}
# 示例：从现在起 7 天后过期，单位为毫秒
EXPIRES_AT=$((($(date +%s) + 7 * 24 * 60 * 60) * 1000))

curl --request POST \
  --url "${MEOO_BASE_URL}/open/v1/projects/${PROJECT_ID}/releases/prepare" \
  --header "Authorization: Bearer ${MEOO_TOKEN}" \
  --header "Content-Type: application/json" \
  --data "{\"runtime\":\"static\",\"expires_at\":${EXPIRES_AT},\"artifact\":{\"type\":\"static_site\",\"filename\":\"dist.zip\",\"content_type\":\"application/zip\",\"content_length\":${CONTENT_LENGTH},\"checksum\":{\"algorithm\":\"md5\",\"value\":\"${CONTENT_MD5}\"}}}"
```

保存 `release_token`、`artifact_id` 和 `upload`。`runtime` 与 `artifact.type` 显式存在，是为未来兼容全栈产物；当前公开组合仅为 `static + static_site`。

**可选参数 expires\_at**：在 prepare 请求体顶层设置发布访问过期时间，类型为整数或 null，单位为 Unix 毫秒时间戳（不是秒数或有效时长）。省略或传 `null` 表示永久有效。上例设置为从调用 prepare 起 7 天后过期；需要永久有效时删除该字段或传 null。请使用未来时间并预留上传、审核时间，过期后发布访问地址返回 404。

这里的 `expires_at` 控制发布后网站的访问有效期；prepare 响应中的 `upload.expires_at` 只控制临时上传链接的有效期，两者相互独立。设置网站有效期不会延长上传链接或 release\_token 的有效期。

## 4. PUT 上传

严格使用响应中的 method、URL 和 headers。上传地址不是 Meoo API，不要携带 `Authorization`。

```text theme={null}
curl --request PUT \
  --url "${UPLOAD_URL}" \
  --header "Content-Type: application/zip" \
  --header "x-oss-forbid-overwrite: true" \
  --header "Content-MD5: ${CONTENT_MD5}" \
  --upload-file "${ZIP_FILE}"
```

若 prepare 未传 checksum，响应不会要求 `Content-MD5`，PUT 时也不要自行增加。

## 5. Release Complete

```text theme={null}
curl --request POST \
  --url "${MEOO_BASE_URL}/open/v1/projects/${PROJECT_ID}/releases/complete" \
  --header "Authorization: Bearer ${MEOO_TOKEN}" \
  --header "Content-Type: application/json" \
  --data "{\"release_token\":\"${RELEASE_TOKEN}\"}"
```

成功响应包含 `release_id`、`version`、`status`、`published_at`、正式 `access_url` 和 `expires_at`。其中 `expires_at` 是本次发布的访问过期时间（Unix 毫秒时间戳），`null` 表示永久有效。

complete 请求仍只提交 `release_token`，无需重复传 expires\_at；服务端使用 prepare 时设置的值。相同 release\_token 可安全重试并返回同一 Release，重试不会延长发布有效期；若解压仍在进行，按错误建议使用原 Token 重试。

## 完成标准

* zip 根目录包含 `index.html`，且不包含服务端 Secret。
* prepare、PUT、complete 使用同一 artifact；prepare 与 complete 使用同一业务身份。
* Token 过期时，为同一 Owner 或虚拟成员重新签发即可继续 complete。
* 接入方保存 `external_app_id → project_id` 和最终 `access_url`。
* 失败时保存 Problem JSON 中的 `code`、`detail`、`trace_id`，以及响应头 `X-Meoo-Trace-Id`；不要记录凭证或签名上传 URL。

团队虚拟账号流程见[团队系统集成指南](https://app.mintlify.com/alibaba-b47c397f/alibaba-b47c397f/~/8b2e4f11-3395-4dd1-b58e-2e6935dd1392)，字段定义见 [Release API](https://app.mintlify.com/alibaba-b47c397f/alibaba-b47c397f/~/b31b1b0b-7d62-41df-a2f9-3643354ac937)。

## 上传、审核和重试

* 这里上传的是已构建的静态产物，不需要 `mise.toml`，不会创建沙箱、运行 AI 或执行构建；源码工程请使用[源码导入 API](https://alidocs.dingtalk.com/i/nodes/kDnRL6jAJMLgNkw7t9LgEPEzVyMoPYe1)。
* 必须原样使用 `upload.headers`，包括 `x-oss-forbid-overwrite: true`。每个对象只允许首次成功上传；修改 ZIP 必须重新 prepare 获取新地址。PUT 结果不确定时，先用原 `release_token` 调用 complete 确认，不能覆盖重传。
* complete 内部等待根目录 `index.html` 出现，然后读取自动解压后的文本和图片送绿网，不需要截图。审核支持的格式与大小见[发布 API](https://app.mintlify.com/alibaba-b47c397f/alibaba-b47c397f/~/b31b1b0b-7d62-41df-a2f9-3643354ac937)；未通过不会替换现有线上版本。
* complete 是普通 JSON 接口，不是 SSE。成功返回发布记录；已经成功的 Token 再次 complete 返回原记录，不重新激活旧版本。审核最长 90 秒，请为请求保留足够等待时间。
* `403 forbidden`：内容未通过审核，修改产物后重新 prepare 和上传。`400 artifact_invalid`：文件格式或大小超出范围，调整产物后重新上传。`503 service_unavailable` 或 `503 release_interrupted`：审核暂不可用或入口未就绪，可用原 Token 重试；持续未就绪应检查 ZIP 根目录是否有 index.html。`409 release_state_expired`：票据已过期或不可用，重新 prepare 和上传。

失败返回 `application/problem+json`，例如（trace\_id 为示例）：

```text theme={null}
{
  "type": "about:blank",
  "title": "Forbidden",
  "status": 403,
  "detail": "静态产物内容未通过安全审核，请修改后重新上传",
  "code": "forbidden",
  "trace_id": "example-trace-id"
}
```

认证 Token 与 release\_token 是两类票据。为同一 Owner/成员续签认证 Token 不会延长 release\_token 或上传 URL 的有效期。
