# API 密钥与开放 API

除了在开发者工作台手动上传，飞块拓展商店还提供开放 API。你可以为 Agent、CI 或脚本生成 API 密钥，让它自动上传 `.flyext` 安装包、补全公开资料、提交审核并跟踪状态。

---

## 1. 生成与管理 API 密钥

1. 登录拓展商店，进入「账户设置」中的「API 密钥」区域。
2. 输入用途名称（例如 `release-bot`），点击「生成密钥」。
3. 明文密钥只显示一次，请立即复制并保存到密钥管理服务；服务端仅保存 SHA-256 摘要。
4. 不再使用时随时撤销；撤销后，使用该密钥的请求立即失效。

- 密钥形如 `fdk_` 加 43 位 Base64URL 字符。
- 每个账户最多保留 20 个有效密钥。
- 密钥只能访问 `/api/v1/open/*`，不能替代浏览器或桌面端登录态访问 `/account/*`、`/developer/*` 或 `/admin/*`。
- 密钥的权限与所属账户一致，只能操作该账户拥有命名空间下的插件。

---

## 2. 认证方式

所有开放接口使用 Bearer 认证：

```sh
curl -H "Authorization: Bearer $FLYON_KEY" \
  "$BASE/open/me"
```

其中 `BASE` 为 `https://<商店域名>/api/v1`。与浏览器 Cookie 请求不同，开放接口不要求 `Origin` 请求头，因为 Bearer 凭据不属于浏览器环境自动携带的授权。请求仍受账户速率限制；密钥无效、已被撤销或账户被停用时返回 401。

---

## 3. 接口一览

| 方法 / 路径                     | 用途                                              |
| ------------------------------- | ------------------------------------------------- |
| GET /open/me                    | 当前密钥对应的账户                                |
| GET /open/namespaces            | 可用命名空间与插件数量                            |
| GET /open/plugins               | 本人插件列表及发布状态                            |
| GET /open/plugins/:id           | 插件详情、版本与审计活动                          |
| PATCH /open/plugins/:id         | 保存插件公开资料草稿，字段与开发者页面一致        |
| POST /open/plugins              | multipart `file` 上传 `.flyext`，自动创建插件草稿 |
| POST /open/plugins/:id/releases | multipart `file` 追加不可覆盖的新版本             |
| POST /open/images               | multipart `file` 上传 16:9 截图，返回资产 UUID    |
| GET /open/releases/:id          | 版本状态、检查报告、驳回原因与提交快照            |
| PATCH /open/releases/:id        | 更新版本说明 `{changelog}`（0–5000 字）           |
| POST /open/releases/:id/submit  | 提交审核；检查中提交会冻结资料快照                |
| POST /open/releases/:id/cancel  | 撤回审核中的提交                                  |
| POST /open/releases/:id/retry   | 重新检查 `check_failed` 的同一不可变包            |

---

## 4. 发布第一个版本

插件 ID、名称与版本号由安装包根目录的 `manifest.json` 决定，请求中不需要也无法手工指定。首次上传会自动创建私有插件草稿，并返回版本记录 UUID：

```sh
curl -H "Authorization: Bearer $FLYON_KEY" \
  -F file=@demo.flyext \
  -F changelog="首个版本" \
  "$BASE/open/plugins"
```

资料字段与开发者页面一致：`name`、`summary`、`description`、`category`、`tags`、`icon`、`screenshots`（`POST /open/images` 返回的资产 UUID）、`repository`、`website`、`support`、`privacyPolicy` 与 `license`。网站、支持与隐私政策链接必须是 HTTPS 或空字符串；介绍为纯文本。也可以提供 `i18n` 译文，规则与商店资料一致。

```sh
curl -X PATCH -H "Authorization: Bearer $FLYON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Demo","summary":"Summary","description":"Details","category":"productivity","tags":[],"icon":"🧩","screenshots":[],"repository":"","license":"MIT"}' \
  "$BASE/open/plugins/demo.plugin"
```

首次上传只创建草稿，必须补全必填资料并等待包体检查通过后才能提交审核。提交可以发生在检查完成之前：此时资料快照立即冻结，后台检查成功后自动进入内容审核队列。

---

## 5. 发布新版本与更新说明

版本号必须递增并重新打包。已上传的同版本包体不可覆盖，重复版本返回 409：

```sh
curl -H "Authorization: Bearer $FLYON_KEY" \
  -F file=@demo-1.1.0.flyext \
  -F changelog="修复若干问题" \
  "$BASE/open/plugins/demo.plugin/releases"
```

上传后仍可补充或修改版本说明：

```sh
curl -X PATCH -H "Authorization: Bearer $FLYON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"changelog":"本次更新修复了若干问题"}' \
  "$BASE/open/releases/<release-id>"
```

- `changelog` 为可选字段，去空白后最多 5000 字，缺省为空字符串。
- 仅所有者可编辑检查中、检查失败、待提交或驳回的版本。
- 提交审核后须先撤回才能修改；已发布及已下架版本不可改写。

---

## 6. 提交与跟踪状态

```sh
# 提交审核
curl -X POST -H "Authorization: Bearer $FLYON_KEY" \
  "$BASE/open/releases/<release-id>/submit"

# 轮询状态：checking → pending → published / rejected
curl -H "Authorization: Bearer $FLYON_KEY" \
  "$BASE/open/releases/<release-id>"
```

- `checking`：后台正在检查归档结构、清单、权限与资源，不执行插件代码。
- `check_failed`：检查失败，可修正后上传新版本，或对同一不可变包调用 `retry`。
- `pending`：已进入人工审核队列。
- `rejected`：审核驳回，响应中的 `reason` 给出原因；修改资料或上传修复版本后重新提交。
- `published`：版本已公开，用户可在商店与桌面端安装。

`GET /open/releases/:id` 还会返回检查报告、权限差异、提交快照与审核说明，便于 Agent 根据稳定字段决定下一步操作。提交期间可调用 `cancel` 撤回整次提交，再继续修改资料或版本说明。

---

## 7. 错误与限流

错误响应为 JSON，包含 `statusCode`、`message`、`requestId` 与稳定的 `code`；请根据 `code` 而非错误句子做分支。响应头 `X-Request-ID` 便于排查单次请求。

认证写请求限制为每分钟 30 次，一般写请求 120 次，读取 1200 次。超限返回 429 和 `Retry-After` 秒数。客户端应对 429 与临时 503 做指数退避，不要并发重试同一个提交。

发布流程中的命名空间申请、资料完整性与人工审核规则，与[手动发布](marketplace.md)完全一致。
