# SKV 使用文档与账户 API

更新：2026-11-06 · 服务入口：https://skv.disk.zone

SKV 把每个用户的 JSON 对象放在独立命名的空间（spacename）里。修改先排队，定时或手动发布后，从静态 CDN 读取。已有空间只需同一个 `?apikey=` 就能读取、写入和删除属性，不需要登录或账户 Key。也可以在网页操作，或用账户 API Key 创建和管理自己的空间。

- [个人空间](https://skv.disk.zone/app)
- [创建、管理账户 API Key](https://disk.zone/app/account)
- [给 AI 的操作手册](https://skv.disk.zone/ai.md)
- [OpenAPI 接口定义](https://skv.disk.zone/openapi.json)
- [Markdown 原文](https://skv.disk.zone/docs.md)

## 1. 接入 AI

**已有空间：**直接把空间 `apikey` 和本页交给 AI，用 `GET /属性?apikey=KEY` 读取、`PUT /属性?apikey=KEY` 写入、`PATCH` 批量修改、`DELETE` 删除属性。无需账户 Key、登录、用户 ID 或 spacename。详见第 10 节。原有空间 Key 也具备同样的读写能力。

**需要新建空间、列出空间、立即发布或换 Key 时：**使用以下账户 Key 流程。

1. 登录 disk.zone，打开“账号 → API Key”。普通用户也可以创建，不需要成为管理员。
2. 新建一把 Key，例如备注“SKV 调试 AI”，选择有效期。完整 Key 只在创建时显示一次。
3. 将 Key 配置到 AI 工具的密钥配置或环境变量 `DZ_KEY`，并把本页或 `/ai.md` 地址交给 AI。
4. AI 先调用 `GET /api/me` 确认身份，再创建、查询、修改和发布该用户自己的空间。
5. 不再需要时，在账户页吊销这把 Key。无需修改 SKV 或重新部署。

账户由 disk.zone 管理，SKV 不另设密码系统，也不要求普通用户打开管理员后台。名字相同但账户不同的空间互不混用；服务端从登录凭据确定归属，不能通过传 `owner`、用户 ID 或文件路径冒充其他用户。

### 一键复制文档与账户 Key

打开[文档顶部的“复制给 AI”](https://skv.disk.zone/docs#ai-copy)，粘贴自己的完整账户 Key，然后点击“复制完整文档 + 账户 Key”。剪贴板会包含真实 Bearer 凭据、完整使用文档和 AI 操作手册，直接粘贴给 AI 即可。

个人空间也有“复制给 AI”按钮，会带上当前账户和空间名称；如果粘贴的 Key 不属于该账户，会拒绝复制，避免混用账号。当前空间只是给 AI 的任务上下文，不限制账户 Key 的实际权限。

已有 Key 的原值无法从服务器反查，所以首次需要粘贴一次；没有 Key 时，点击旁边的账户页入口创建后再粘贴。Key 只在当前页面内存中使用，不会存入公开文档或浏览器本地存储。关闭页面后需要重新填写。浏览器阻止自动复制时，页面会提供已准备好的完整文本供手动复制。

## 2. 两种密钥，作用不同

| 项目 | 账户 API Key | 空间 Key |
| --- | --- | --- |
| 示例格式 | `dzk.<用户ID>.<keyid>.<secret>` | 64 位小写十六进制，或 `<worker-name>_<48位十六进制>` |
| 创建位置 | disk.zone 账户页 | SKV 创建空间时自动生成 |
| 请求位置 | `Authorization: Bearer ...` | URL 查询参数 `apikey=...` |
| 能力 | 以账户身份创建、修改、删除、发布自己的空间和轮换空间 Key | 读写该空间整个 JSON 或任意属性；不能新建空间、列出其他空间或换 Key |
| 数量 | 每账户最多 20 把未吊销 Key | 每空间当前发布版本一把生效 Key，可有一把待发布的新 Key |
| 失效方式 | 账户页吊销、到期或账户停用；下次认证即失败 | 轮换后等部署完成，旧文件路径被移除 |
| 是否查询账户/DO | 是，管理请求需要认证 | 读取不查 DO；写入查询节点与文件索引并记录变化，无需账户认证 |

**账户 Key 权限继承账户本身，当前没有“仅某个 spacename”“仅 SKV”或只写某个字段的 Key scope。** 备注名只是用途说明，不限制权限。普通用户 Key 在 SKV 可以管理该用户所有空间；如果这个账户还有其他项目权限，Key 也可能用于那些项目。因此，把自己的普通用户 Key 给 AI 即可，不需要平台管理员 Key。

**空间 Key 是整个空间的读写凭据。** 分享任意属性 URL 或 CDN 文件 URL 都会暴露这把 Key；持有人能读写该空间其他属性。它不授予账户管理或其他空间权限。Key 解析得到 CDN Worker，写入时经节点索引找到对应 DO，再以当前文件名精确查询内部 path、owner、spacename；请求方无需提供这些字段。

吊销账户 Key 不会自动更换空间 Key；轮换空间 Key 也不会吊销账户 Key。这是两件独立的操作。

## 3. 创建、查看与吊销账户 API Key

最方便的方式是使用 [disk.zone 账户页](https://disk.zone/app/account)。也可以调用主站接口：

| 方法 | 主站地址 | 用途 |
| --- | --- | --- |
| GET | `https://disk.zone/api/me/keys` | 列出自己账户的 Key 元数据，不返回完整秘密 |
| POST | `https://disk.zone/api/me/keys` | 创建自己的 Key，必须使用登录 Cookie 或登录获得的访问令牌 |
| DELETE | `https://disk.zone/api/me/keys/{id}` | 吊销自己的 Key；`id` 是创建/列表返回的 Key ID |

创建请求体：

```json
{"label":"SKV 调试 AI","expires_days":30}
```

`label` 必填，1–60 字符；`expires_days` 可选，1–3650，不传则长期有效。每账户最多 20 把未吊销 Key，过期但未吊销的记录也占名额。返回结构：

```json
{"ok":true,"data":{"id":"<keyid>","label":"SKV 调试 AI","key":"dzk.<用户ID>.<keyid>.<secret>","expires_at":1234567890000,"notice":"完整密钥只显示这一次，请立即保存"}}
```

以下用已登录获得的访问令牌 `$DZ_ACCESS_TOKEN` 创建 Key。不要把账户密码交给 AI：

```bash
curl --fail-with-body -sS -X POST 'https://disk.zone/api/me/keys' \
  -H "Authorization: Bearer $DZ_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"label":"SKV 调试 AI","expires_days":30}'
```

API Key 不能再创建新的 API Key，服务器会返回 `403 api_key_not_allowed`。需要新 Key 时由用户在已登录的账户页创建。吊销示例：

```bash
curl --fail-with-body -sS -X DELETE 'https://disk.zone/api/me/keys/<keyid>' \
  -H "Authorization: Bearer $DZ_ACCESS_TOKEN"
```

## 4. SKV 鉴权与响应格式

账户管理请求统一发送：

```http
Authorization: Bearer dzk.<用户ID>.<keyid>.<secret>
Content-Type: application/json
```

SKV 同时接受 `X-Api-Key`，也接受主站登录获得的 Bearer 访问令牌。示例统一使用 `Authorization`，不要同时发送互相矛盾的凭据。账户 Key 不要放入 `?apikey=`：这个参数专用于单空间读写，且会优先进入空间 Key 路由。

网页使用 disk.zone SSO Cookie；Cookie 写请求要求同源。AI、服务器脚本使用 Bearer，不需要浏览器 Cookie 或额外授权页面。管理 API 不提供任意网站携带账户凭据的跨域访问；请从自己的服务器或 AI 工具调用。

管理接口成功：`{"ok":true,"data":...}`。失败：`{"ok":false,"error":{"code":"...","message":"..."}}`。JSON 数据读取接口直接返回选中的 JSON 值，不加 `ok/data` 包装。

```bash
# 先在工具的密钥配置中设置 DZ_KEY
SKV='https://skv.disk.zone'
curl --fail-with-body -sS "$SKV/api/me" -H "Authorization: Bearer $DZ_KEY"
```

`/api/me` 返回当前用户、余额信息及 SKV 当前业务定价。当前 SKV 不从用户余额扣费；这与 Cloudflare 的基础设施账单是不同概念。

## 5. 用户接口总表

推荐以查询参数传空间名，能正确处理中文、空格、斜杠、`.` 和 `..`。下表 `NAME` 都应通过 URL 编码传入。

| 方法 | SKV 地址 | 结果 |
| --- | --- | --- |
| GET | `/api/me` | 当前账户信息 |
| GET | `/api/spaces?limit=100&offset=0` | 自己的空间列表 |
| POST | `/api/spaces` | 创建空间，请求体 `{"name":"demo"}` |
| GET | `/api/space?name=NAME` | 空间信息及发布状态 |
| GET | `/api/space?name=NAME&action=status` | 同上，显式查询状态 |
| GET | `/api/space?name=NAME&action=content` | 用账户身份读取已发布完整 JSON |
| PATCH | `/api/space?name=NAME` | 排队修改指定属性 |
| PUT | `/api/space?name=NAME` | 排队替换整个 JSON 对象 |
| DELETE | `/api/space?name=NAME` | 排队删除已发布内容 |
| POST | `/api/space?name=NAME&action=publish` | 请求立即发布 |
| POST | `/api/space?name=NAME&action=key` | 排队轮换空间 Key |

同样支持路径写法 `/api/spaces/{name}`，以及后接 `/status`、`/content`、`/publish`、`/key`。特殊名称优先使用查询参数形式，避免浏览器对 `.`、`..` 的路径归一化。

`GET /api` 是公开接口目录，`GET /api/health` 是公开健康检查。

## 6. 创建与列出空间

```bash
curl --fail-with-body -sS -X POST "$SKV/api/spaces" \
  -H "Authorization: Bearer $DZ_KEY" -H 'Content-Type: application/json' \
  --data '{"name":"demo"}'

curl --fail-with-body -sS "$SKV/api/spaces?limit=100&offset=0" \
  -H "Authorization: Bearer $DZ_KEY"
```

空间名在自己的账户内唯一，为 1–200 个 UTF-8 字节，不得含控制字符；中文按字节计长度。重复创建同名空间返回现有空间（HTTP 200），新建返回 201。新空间会排队初始化为 `{}`，首次部署前读取可能为 404。

列表 `data.items` 为本页记录，`data.total` 为总数。`limit` 范围 1–100，默认 100；`offset` 默认 0，按实际返回数量递增直到取完。

空间响应中的字段：

| 字段 | 含义 |
| --- | --- |
| `name` | 空间名 |
| `apikey` | 当前文件名对应的空间 Key；新空间首次部署前可排队写入，但尚不能读取 |
| `pending_apikey` | 已排队但未生效的新 Key，通常为 null |
| `read_url` | 当前统一公开读取地址 |
| `cdn_url` | 当前 CDN 完整文件直读地址 |
| `content_url` | 使用账户凭据读取已发布文件的地址 |
| `path` | 空间内部稳定索引 ID；轮换后不等于当前文件路径 |
| `cdn_id`、`cdn_origin` | 分配到的静态节点信息 |

**保存并使用 API 返回的 `read_url`、`cdn_url` 和 `apikey`，不要用内部 `path` 自行拼接当前读取地址。**

## 7. 增量修改：PATCH

以下只更新 `profile.name`、`settings.theme` 并删除 `obsolete`，其他字段保持原样：

```bash
curl --fail-with-body -sS -X PATCH "$SKV/api/space?name=demo" \
  -H "Authorization: Bearer $DZ_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: demo-update-001' \
  --data '{"operations":[{"op":"set","path":["profile","name"],"value":"Hans"},{"op":"set","path":["settings","theme"],"value":"dark"},{"op":"delete","path":["obsolete"]}]}'
```

这是 SKV 自己的修改协议，不是 RFC 6902 JSON Patch：操作是 `set` / `delete`，`path` 是字符串数组。

- `set` 的 `value` 可以是标准 JSON 值：对象、数组、字符串、数字、布尔或 null。
- 对象里缺失的中间层会创建为空对象；如果中间层已是非容器值，发布会失败，需要修正修改。
- `set` 一个对象/数组会替换该位置的整个值。只改其中一个字段时，应写到更深的路径。
- `delete` 删除字段；设置为 null 是保留字段且值为空，两者不同。
- 数组索引用字符串，例如 `["users","0","name"]`。索引等于数组长度可以追加，不允许稀疏数组；删除数组项使用 splice，后续索引会移动。
- 空格、中文、`.`、空字符串可以作为对象键；任何层级的键名都不能包含 `/`。

顶层简写：

```json
{"set":{"enabled":true,"version":2},"delete":["oldField"],"idempotency_key":"demo-update-002"}
```

一次 PATCH 的多项操作作为同一条修改记录保存；状态中的修改数量不是字段数量。

## 8. 替换、删除、幂等与并发

整体替换会覆盖空间原有内容，使用 `value` 包装：

```bash
curl --fail-with-body -sS -X PUT "$SKV/api/space?name=demo" \
  -H "Authorization: Bearer $DZ_KEY" -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: demo-replace-001' \
  --data '{"value":{"profile":{"name":"Hans"},"enabled":true}}'
```

删除内容：

```bash
curl --fail-with-body -sS -X DELETE "$SKV/api/space?name=demo" \
  -H "Authorization: Bearer $DZ_KEY" -H 'Idempotency-Key: demo-delete-001'
```

DELETE 是删除已发布文件内容，需部署后生效；空间名、归属和索引墓碑仍可能保留，不是注销账户。之后对同一空间重新写入并发布，可以恢复内容。

对 PATCH、PUT、DELETE、空间 Key 轮换，使用 `Idempotency-Key` 请求头，或 JSON 里的 `idempotency_key`；两者都有时请求头优先。键为 1–128 位可见 ASCII。

- 同一操作重试：沿用同一个幂等键和相同请求体，不重复入队。
- 新操作：使用全新的键，推荐 UUID，不要跨空间重复使用同一个键。
- 相同幂等键却发送不同内容：返回 `409 idempotency_key_reused`。
- 不提供时服务端会生成随机键，因此网络失败后重新请求可能重复执行。尤其数组删除不要这样重试。
- 创建空间按“账户 + 名称”去重；账户 Key 的创建不幂等，不要因超时盲目反复创建。

当前没有 compare-and-swap / If-Match 写入锁。修改按接收顺序应用，后来的修改可能覆盖较早修改；多个 AI 同时工作时尽量 PATCH 精确字段，不要拿旧快照 PUT 整个对象。HTTP 202 仅表示修改已入队，某些与旧值有关的路径错误会到发布阶段才被发现。

## 9. 发布与确认生效

```bash
curl --fail-with-body -sS -X POST "$SKV/api/space?name=demo&action=publish" \
  -H "Authorization: Bearer $DZ_KEY"

curl --fail-with-body -sS "$SKV/api/space?name=demo&action=status" \
  -H "Authorization: Bearer $DZ_KEY"
```

写入、删除、轮换及发布请求通常返回 HTTP 202，**不能把 202 当作已经发布成功**。空队列触发发布会返回 `data.empty: true`。

状态重要字段：

| 字段 | 含义 |
| --- | --- |
| `file_pending_changes` | 当前空间尚待发布的修改记录数 |
| `file.hash`、`file.revision` | 当前已发布文件的内容哈希、发布版本 |
| `file.deleted` | 已删除时为 1 |
| `file.current_apikey`、`file.pending_apikey` | 当前及待发布空间 Key |
| `job.phase` | 节点发布阶段：preparing、committing、done、failed 等 |
| `job.error_code`、`job.error` | 发布失败信息 |
| `scheduled_at` | 下一次执行时间，Unix 毫秒或 null |
| `auto_publish`、`interval_seconds` | 当前节点自动发布开关及间隔 |
| `pending_changes`、`pending_files` | 整个 CDN 节点的总待发布量，不是当前空间的数量 |

通常每 1–3 秒查一次状态：等待当前空间 `file_pending_changes === 0`，并核对发布文件/版本，再读取 `read_url` 验证预期值。删除则核对 `file.deleted === 1` 和读取 404；轮换则核对新 Key 已成为当前 Key。其他用户继续写同一 CDN 节点时，节点总待发布数可能不为零，不必等整个节点完全空闲。

发布以 CDN 节点为批次。请求自己的空间发布，可能一并发布该节点已经排队的其他文件，但不会赋予调用者修改其他用户数据的能力。正在发布时收到的新修改保留到下一批，当前任务可能尚未包含它们。

默认自动发布间隔 60 秒，节点管理员可调整为 10–86400 秒或关闭；从最早待发布变化安排执行，空闲时不会无意义反复部署。自动发布关闭时可手动发布；节点暂停时写入与手动发布会被拒绝。边缘传播有延迟，第一次读到旧版本时稍后重试。

## 10. 同一个 apikey 直接读写

只需要空间 Key。无需 Cookie、Authorization、用户 ID 或空间名称；兼容现有 Key。

| 方法 | 地址 | 请求体与效果 |
| --- | --- | --- |
| GET / HEAD | `/属性/子属性?apikey=KEY` | 读取已发布值或头部；根路径读取整个 JSON |
| PUT | `/属性/子属性?apikey=KEY` | body 就是新 JSON 值，直接替换该属性；支持对象、数组、字符串、数字、布尔和 null |
| PUT | `/?apikey=KEY` | body 为完整 JSON 对象，替换根对象，不需要 `{"value":...}` 包装 |
| PATCH | `/属性路径?apikey=KEY` | 使用 `operations` 或 `set` / `delete`，路径相对于 URL 所选对象 |
| DELETE | `/属性/子属性?apikey=KEY` | 删除对应属性；删除数组项后后续索引前移 |
| DELETE | `/?apikey=KEY` | 清空为 `{}`，保留空间和 Key，仍可继续写入 |

`PUT /field` 的 body 为 `{"value":1}` 时，field 的新值就是整个 `{"value":1}` 对象，不会拆包装。账号 API 的整体替换仍使用原来的 `{"value":{...}}` 格式。

```bash
SKV='https://skv.disk.zone'
# 将现有空间 Key 配置到 SPACE_KEY
curl --fail-with-body -sS -X PUT "$SKV/settings/theme?apikey=$SPACE_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: theme-dark-001' \
  --data '"dark"'

curl --fail-with-body -sS -X PATCH "$SKV/settings?apikey=$SPACE_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: settings-002' \
  --data '{"set":{"theme":"light","enabled":true},"delete":["obsolete"]}'

curl --fail-with-body -sS -X DELETE "$SKV/settings/obsolete?apikey=$SPACE_KEY" \
  -H 'Idempotency-Key: delete-obsolete-003'
```

写入成功返回 `202 {"ok":true,"data":{"queued":true,"seq":123,"duplicate":false,"scheduled_at":...}}`，表示修改已记录，**不代表 CDN 已更新**。自动部署后再 GET 验证；需要立即发布仍使用账户或管理员发布 API。写入不会当场拉取、合并或上传整份 JSON。新空间首次部署前也能排队写入；尚未部署的新轮换 Key 不可使用，部署完成后旧 Key 写入返回 404。

`Idempotency-Key` 用于安全重试。PUT 的所有 body 字段都是业务数据，幂等键只能放请求头；PATCH 也接受 body.idempotency_key；DELETE 使用请求头。每次新操作用新键，重试使用相同键和内容。空间 Key 写入的幂等记录按空间 Key 隔离。单次 body 和标准化修改各不超过 64 KiB，路径不超过 64 层，最外层保持 JSON 对象。创建空间、查看账户列表、轮换 Key、请求发布仍走账户 API。

### 读取整个文件或属性

先从创建/状态接口拿到真正的 `apikey` 或 `read_url`，设置环境变量 `SPACE_KEY`。这个变量是空间 Key，不是 `DZ_KEY`。

```bash
curl --fail-with-body -sS --get "$SKV/" \
  --data-urlencode "apikey=$SPACE_KEY"

curl --fail-with-body -sS --get "$SKV/profile/name" \
  --data-urlencode "apikey=$SPACE_KEY"

curl --fail-with-body -sS --get "$SKV/users/0/name" \
  --data-urlencode "apikey=$SPACE_KEY"
```

根路径返回整个 JSON；每一层路径选择一个对象键或数组索引。响应仍是 JSON，例如名字返回 `"Hans"`，数字返回 `42`，不是包在 `data` 里，也不是去掉引号的纯文本。缺失属性返回 404。

路径段应分别使用 `encodeURIComponent`，不能把整个多级路径一起编码。对于空键、`.`、`..`，使用无损查询参数形式：

```bash
curl --fail-with-body -sS --get "$SKV/" \
  --data-urlencode "apikey=$SPACE_KEY" \
  --data-urlencode 'path=["settings",".."]'
```

`path` 必须是 JSON 字符串数组，只能与根路径 `/` 一起使用；`[]` 表示完整对象。键名仍不允许包含 `/`。

CDN 直接地址为 `https://<cdn-worker域名>/<空间Key>`，无文件后缀，返回完整 JSON。**纯静态 CDN 本身不解析 `/Key/属性`；属性选择在 SKV 入口 Worker 完成。**

整个公开读取链路不触碰 UserDO、索引 DO、数据库或账户认证，也不提供即时撤销账户身份的检查。管理 API、账户身份读取 `action=content` 和状态查询则需要认证及 DO 操作。

## 11. HEAD、Range、ETag 与浏览器调用

公开读取支持 GET、HEAD、OPTIONS，以及单个 HTTP 字节 Range：

```bash
curl -sS --get "$SKV/profile/name" \
  --data-urlencode "apikey=$SPACE_KEY" \
  -H 'Range: bytes=0-5' -i
```

合法范围返回 206 和 `Content-Range`；不可满足的范围返回 416。范围相对于“所选 JSON 值的 UTF-8 字节表示”，不是原文件的绝对偏移，也不是字符数；数组、对象、字符串都一样。一次请求不支持多个区间。响应包含 ETag，并支持 If-Range；当前没有通过 If-None-Match 直接返回 304 的逻辑。属性范围读取可能需要两次 CDN 请求，仍不查询数据库。

空间 Key 读写均返回 `Access-Control-Allow-Origin: *`。OPTIONS 无需查询 DO，允许 GET、HEAD、PUT、PATCH、DELETE 和 Content-Type / Idempotency-Key；浏览器调用时使用 `credentials: 'omit'`：

```js
const readURL = new URL('https://skv.disk.zone/settings/theme');
readURL.searchParams.set('apikey', SPACE_KEY);
const response = await fetch(readURL, { credentials: 'omit' });
if (!response.ok) throw new Error(`读取失败：${response.status}`);
const value = await response.json();
```

## 12. 轮换空间 Key

```bash
curl --fail-with-body -sS -X POST "$SKV/api/space?name=demo&action=key" \
  -H "Authorization: Bearer $DZ_KEY" \
  -H 'Idempotency-Key: demo-rotate-001'
```

响应返回 `current_apikey` 和 `pending_apikey`。此时旧 Key 仍可读写，新 Key 尚不能读写。手动发布或等待自动发布；成功后，新 Key 成为文件名，旧文件路径从部署清单移除。完成后旧 Key 的写入被 DO 拒绝，不能通过旧的内部 path 绕过。纯换名可以复用原内容哈希，不必重写整个 JSON。

Key 轮换不会追溯删除别人已经下载的数据。部署传播期间旧地址可能短暂仍可读。完成后重新获取空间状态里的 `read_url`、`cdn_url`，不要继续使用原先保存的地址。

## 13. 网页编辑器

“JSON / 编辑内容”使用普通 textarea，支持标准 JSON、JS 对象字面量、单引号、注释、表达式、尾逗号，以及 `const data = {...};`。点击“转为标准 JSON”或“保存修改”时才求值一次，浏览器独立执行环境最长执行 3 秒；输入过程中不会执行。

```js
const data = {
  name: 'Hans',
  count: 1 + 2,
  tags: ['test', 'demo',],
}
```

结果用 JSON.stringify 转成 JSON：例如 Date 转成字符串，undefined/函数值按 JSON 的序列化规则省略，BigInt 或循环引用会报错。最外层必须是对象，键名不得包含 `/`。

**HTTP 写入接口只接收标准 JSON，不执行 JavaScript。** AI 调用 API 时直接发 JSON；网页编辑器的 JS 求值只是输入便利功能。

编辑器初始读取的是已发布内容，不包含其他客户端尚在队列中的修改。保存只提交与编辑器基线相比发生变化的属性，保存不等于发布。

## 14. 当前应用限制

| 项目 | 当前限制 |
| --- | --- |
| 单空间发布后 JSON | 8 MiB；这是 SKV 合并过程的应用内存保护，Cloudflare 静态单文件平台上限是 25 MiB |
| 单次 HTTP 写入 body | 64 KiB，包含 JSON 协议包装 |
| 单条修改记录 | 64 KiB；最多 1000 个操作 |
| 修改路径深度 | 1–64 段；每段最多 512 个 UTF-8 字节 |
| JSON 嵌套深度 | 最多 64 层 |
| 空间名 | 1–200 个 UTF-8 字节 |
| 列表分页 | 每页 1–100 条 |
| 自动发布间隔 | 10–86400 秒，默认 60 秒 |

较大对象可以按不同属性分批 PATCH，但单个超大属性本身无法绕过 64 KiB 单次写入限制；当前没有大对象分块上传接口。空间数量不设用户级固定数量上限，实际容量仍受节点/Cloudflare 配额影响。

## 15. 错误与排查

| 状态/代码 | 含义与处理 |
| --- | --- |
| 400 `invalid_json` / `invalid_input` | body、分页、幂等键等格式错误 |
| 400 `invalid_patch` / `invalid_property_name` | 修改格式或对象键名不合法 |
| 401 `unauthorized` / `invalid_api_key` | 没有正确发送账户凭据，或 Key 不正确 |
| 401 `api_key_revoked` / `api_key_expired` / `account_disabled` | 账户凭据已失效，返回账户页处理 |
| 403 `bad_origin` | Cookie 写请求不是同源；AI 改用 Bearer |
| 404 `namespace_not_found` | 账户 API：当前账户没有此空间；空间 Key API：Key 不存在、已轮换或文件已被账户删除 |
| 404 公开内容 | 尚未发布、Key 已轮换、内容已删除、属性不存在，或 Key 对应文件不存在 |
| 409 `idempotency_key_reused` | 相同幂等键被用于不同内容，新的操作须用新键 |
| 413 `payload_too_large` | 单次修改过大，拆成较小的属性修改 |
| 503 `project_paused` / `platform_unavailable` | 节点/项目暂停或账户服务暂时不可用 |
| `job.phase = failed` | HTTP 排队成功但部署失败，查看 job.error_code / error |

网络超时、5xx：保留原幂等键和原请求体再重试，不要把一个数组删除变成两次不同操作。发布任务失败时，读取仍可能是上一个成功版本；不要向用户报告已更新。修正数据后可再次请求发布；节点配置、外部部署冲突等问题需由管理员处理。

没有读取到刚保存的内容时，依次检查：HTTP 是否只是 202 → 当前空间待发布量 → 发布失败信息 → 当前 Key 是否已轮换 → CDN 是否尚在传播。

## 16. 可直接交给 AI 的任务说明

仅操作一个已有空间时：

```text
我的空间 Key 已配置为 SPACE_KEY。
阅读 https://skv.disk.zone/ai.md，直接用 /属性路径?apikey=SPACE_KEY 读写。
无需索要账户 Key、登录信息、用户 ID 或 spacename，也不要调用 /api/me。
PUT 请求体直接发送 JSON 值；优先修改具体属性，或使用 PATCH 批量修改。
每次写入使用 Idempotency-Key；202 仅表示已排队，自动发布后再读取验证。
只操作我指定的数据，不回显 Key。
```

需要管理账户下的空间时：

```text
你可以通过 HTTPS 管理我的 SKV 数据。
先阅读 https://skv.disk.zone/ai.md 和 https://skv.disk.zone/docs.md。
账户 API Key 已配置在 DZ_KEY，不要将它当成空间 apikey，不要回显到回复或日志。
先 GET /api/me 确认账户身份，只操作我指定的 spacename 和字段。
普通操作优先 PATCH，避免用旧快照 PUT 覆盖其他字段。
每个新写操作生成唯一 Idempotency-Key；重试同一操作沿用原键和原请求体。
需要立即生效时请求 publish，然后查 status，并读取已发布数据核对结果。
202 只表示排队；尚未部署或部署失败时明确说明，不要报告已经生效。
按我已经授权的范围操作；删除、整体覆盖或换 Key 若超出任务范围，先向我确认。
```

AI 只需要能够发出 HTTPS 请求，不需要专门的 MCP、SDK 或管理员角色。接口的 JSON 定义在 `/openapi.json`，更短的执行手册在 `/ai.md`。
