{
  "openapi": "3.1.0",
  "info": {
    "title": "SKV 用户 API 与账户 Key 接入",
    "version": "1.2.0",
    "description": "账户 Key 用 Bearer 管理自己的空间；同一个空间 Key 通过 apikey 查询参数 GET/HEAD 读取、PUT/PATCH/DELETE 修改，无需登录。写入返回202只代表排队。完整语义见 /docs.md；AI 手册见 /ai.md。账户 Key 当前没有单空间或单项目 scope。"
  },
  "servers": [
    {
      "url": "https://skv.disk.zone"
    }
  ],
  "externalDocs": {
    "url": "https://skv.disk.zone/docs"
  },
  "paths": {
    "/api": {
      "get": {
        "operationId": "getApiDirectory",
        "summary": "公开接口目录",
        "security": [],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "健康检查",
        "security": [],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/me": {
      "get": {
        "operationId": "getCurrentUser",
        "summary": "确认账户身份、余额和 SKV 业务定价",
        "security": [
          {
            "accountKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces": {
      "get": {
        "operationId": "listSpaces",
        "summary": "列出当前用户空间",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "data.items 是当前页，data.total 为总数",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createSpace",
        "summary": "创建自己的空间；同名返回现有空间",
        "security": [
          {
            "accountKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "1–200 UTF-8 字节，不能含控制字符。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "同名空间已经存在",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "201": {
            "description": "新建空间，初始化 {} 已排队，发布前读取可能404",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/space": {
      "get": {
        "operationId": "getSpace",
        "summary": "空间信息/状态，或已发布完整内容",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "name",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "status",
                "content"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "action=content 直接返回 JSON；其余返回 Envelope，data.space 包含当前 Key/URL，data.file_pending_changes 为本空间待发布数",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "$ref": "#/components/schemas/JSONValue"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchSpace",
        "summary": "只修改指定属性，稍后发布",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "name",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "replaceSpace",
        "summary": "替换整个 JSON 对象，稍后发布",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "name",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSpaceContent",
        "summary": "排队删除已发布内容，保留空间元数据",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "name",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "publishOrRotateSpace",
        "summary": "立即请求发布，或排队轮换空间 Key",
        "description": "action=publish 按整个 CDN 节点批次发布；action=key 返回 current_apikey/pending_apikey，新 Key 到部署后才生效。",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "name",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "query",
            "name": "action",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "publish",
                "key"
              ]
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "operationId": "readSpaceByKey",
        "summary": "用空间 Key 读完整对象或 path 指定的任意层级",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "description": "可选 JSON 字符串数组，URL 编码。例如 [\"settings\",\"theme\"]，空数组表示完整对象。支持空键和点号键，不允许键内含 /。最多64段。",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          },
          {
            "in": "header",
            "name": "Range",
            "schema": {
              "type": "string"
            },
            "example": "bytes=0-5",
            "description": "仅支持一个 bytes 区间。"
          },
          {
            "in": "header",
            "name": "If-Range",
            "schema": {
              "type": "string"
            },
            "description": "ETag 或 HTTP 日期。不匹配时返回完整所选 JSON 值。"
          }
        ],
        "responses": {
          "200": {
            "description": "选中的 JSON 值；没有 ok/data 包装",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JSONValue"
                }
              }
            }
          },
          "206": {
            "description": "单个字节区间，范围相对于所选 JSON 值的 UTF-8 字节；片段可能不是独立有效 JSON",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "416": {
            "description": "Range 不可满足"
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "head": {
        "operationId": "headSpaceByKey",
        "summary": "查询完整或所选 JSON 的头部",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          }
        ],
        "responses": {
          "200": {
            "description": "无 body，Content-Length 为所选 JSON 字节数，返回 ETag。"
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "replaceWithSpaceKey",
        "summary": "用空间 Key 替换根 JSON 对象",
        "description": "无需登录或账户 Key。body 直接是新 JSON 值，不加 value 包装。根对象必须是 JSON 对象，path 选中的属性允许任意 JSON 值。返回202后等待发布。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "description": "可选 JSON 字符串数组，URL 编码。例如 [\"settings\",\"theme\"]，空数组表示完整对象。支持空键和点号键，不允许键内含 /。最多64段。",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JSONValue"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchWithSpaceKey",
        "summary": "用空间 Key 批量修改指定位置下的属性",
        "description": "operations 或 set/delete 中的路径相对 URL/path 所选位置；只能修改此空间数据，不能换 Key 或管理账户。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "description": "可选 JSON 字符串数组，URL 编码。例如 [\"settings\",\"theme\"]，空数组表示完整对象。支持空键和点号键，不允许键内含 /。最多64段。",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "clearWithSpaceKey",
        "summary": "用空间 Key 清空根对象或删除 path 选中的属性",
        "description": "根路径且未选属性时清空为 {}，保留空间和 Key；删除数组项会前移后续索引。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "description": "可选 JSON 字符串数组，URL 编码。例如 [\"settings\",\"theme\"]，空数组表示完整对象。支持空键和点号键，不允许键内含 /。最多64段。",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "preflightSpaceKey",
        "summary": "空间 Key 读写 CORS 预检，不访问 DO",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "description": "可选 JSON 字符串数组，URL 编码。例如 [\"settings\",\"theme\"]，空数组表示完整对象。支持空键和点号键，不允许键内含 /。最多64段。",
            "schema": {
              "type": "string"
            },
            "example": "[\"settings\",\"theme\"]"
          }
        ],
        "responses": {
          "204": {
            "description": "允许 GET、HEAD、PUT、PATCH、DELETE；Content-Type、Idempotency-Key 和 Range 等请求头。"
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/{property}": {
      "get": {
        "operationId": "readTopLevelProperty",
        "summary": "读取一个顶层属性；多层可用根路径的 path 数组",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "property",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^/]+$"
            },
            "description": "单段键名。点号或空键改用根路径 path 参数。"
          },
          {
            "in": "header",
            "name": "Range",
            "schema": {
              "type": "string"
            },
            "example": "bytes=0-5",
            "description": "仅支持一个 bytes 区间。"
          },
          {
            "in": "header",
            "name": "If-Range",
            "schema": {
              "type": "string"
            },
            "description": "ETag 或 HTTP 日期。不匹配时返回完整所选 JSON 值。"
          }
        ],
        "responses": {
          "200": {
            "description": "选中的 JSON 值；没有 ok/data 包装",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JSONValue"
                }
              }
            }
          },
          "206": {
            "description": "单个字节区间，范围相对于所选 JSON 值的 UTF-8 字节；片段可能不是独立有效 JSON",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "416": {
            "description": "Range 不可满足"
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "setPropertyWithSpaceKey",
        "summary": "用空间 Key 设置属性（多层可用根路径 path 参数）",
        "description": "无需登录或账户 Key。body 直接是新 JSON 值，不加 value 包装。根对象必须是 JSON 对象，path 选中的属性允许任意 JSON 值。返回202后等待发布。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "property",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^/]+$"
            },
            "description": "单段键名。点号或空键改用根路径 path 参数。"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JSONValue"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchPropertyWithSpaceKey",
        "summary": "用空间 Key 批量修改指定位置下的属性",
        "description": "operations 或 set/delete 中的路径相对 URL/path 所选位置；只能修改此空间数据，不能换 Key 或管理账户。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "property",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^/]+$"
            },
            "description": "单段键名。点号或空键改用根路径 path 参数。"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deletePropertyWithSpaceKey",
        "summary": "用空间 Key 删除属性",
        "description": "根路径且未选属性时清空为 {}，保留空间和 Key；删除数组项会前移后续索引。",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "property",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^/]+$"
            },
            "description": "单段键名。点号或空键改用根路径 path 参数。"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "相同操作重试使用相同键和 body；按空间 Key 隔离。PUT/DELETE 仅使用此请求头，PATCH 也支持 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "preflightPropertyKey",
        "summary": "空间 Key 读写 CORS 预检，不访问 DO",
        "security": [
          {
            "spaceKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "property",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[^/]+$"
            },
            "description": "单段键名。点号或空键改用根路径 path 参数。"
          }
        ],
        "responses": {
          "204": {
            "description": "允许 GET、HEAD、PUT、PATCH、DELETE；Content-Type、Idempotency-Key 和 Range 等请求头。"
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces/{spacename}": {
      "get": {
        "operationId": "getSpaceByPath",
        "summary": "空间信息/状态，或已发布完整内容",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "action=content 直接返回 JSON；其余返回 Envelope，data.space 包含当前 Key/URL，data.file_pending_changes 为本空间待发布数",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "$ref": "#/components/schemas/JSONValue"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patchSpaceByPath",
        "summary": "只修改指定属性，稍后发布",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "replaceSpaceByPath",
        "summary": "替换整个 JSON 对象，稍后发布",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSpaceContentByPath",
        "summary": "排队删除已发布内容，保留空间元数据",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces/{spacename}/status": {
      "get": {
        "operationId": "statusSpaceByPath",
        "summary": "查询空间发布状态",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces/{spacename}/content": {
      "get": {
        "operationId": "contentSpaceByPath",
        "summary": "读取已发布完整 JSON",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JSONValue"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces/{spacename}/publish": {
      "post": {
        "operationId": "publishSpaceByPath",
        "summary": "请求立即发布",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/spaces/{spacename}/key": {
      "post": {
        "operationId": "keySpaceByPath",
        "summary": "排队轮换空间 Key",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "spacename",
            "required": true,
            "description": "空间名，URL 编码；1–200 UTF-8 字节。",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "新操作用新键；相同操作重试复用原键和原 body。请求头优先于 body.idempotency_key。",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[!-~]+$"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "已排队，未必已部署。查询 status 并读取公开内容验证。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/me/keys": {
      "servers": [
        {
          "url": "https://disk.zone"
        }
      ],
      "get": {
        "operationId": "listAccountKeys",
        "summary": "主站：列出自己的账户 API Key 元数据",
        "security": [
          {
            "accountKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAccountKey",
        "summary": "主站：普通用户创建自己的账户 API Key",
        "description": "必须使用登录会话或登录访问令牌；现有 API Key 调用返回403 api_key_not_allowed。完整秘密仅返回一次。最多20把未吊销Key。",
        "security": [
          {
            "sessionAccessToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "标准 JSON；HTTP body 不超过 64 KiB。后端不执行 JS。",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "label"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "expires_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "不提供为长期有效。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "data 包含 id、label、key、expires_at、notice",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/me/keys/{id}": {
      "servers": [
        {
          "url": "https://disk.zone"
        }
      ],
      "delete": {
        "operationId": "revokeAccountKey",
        "summary": "主站：吊销自己的账户 API Key",
        "security": [
          {
            "accountKey": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "data.revoked 为 Key ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "default": {
            "description": "失败，参见 error.code / error.message",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "accountKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "dzk.<user>.<keyid>.<secret>",
        "description": "disk.zone 账户 API Key，也可使用登录访问令牌。"
      },
      "sessionAccessToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "登录获得的访问令牌，不是 dzk API Key。"
      },
      "spaceKey": {
        "type": "apiKey",
        "in": "query",
        "name": "apikey",
        "description": "空间 Key，持有人可读写整个空间；读取不查 DO，写入排队后发布；不授予账户管理权限。"
      }
    },
    "schemas": {
      "JSONValue": {
        "oneOf": [
          {
            "type": "null"
          },
          {
            "type": "boolean"
          },
          {
            "type": "number"
          },
          {
            "type": "string"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JSONValue"
            }
          },
          {
            "$ref": "#/components/schemas/JSONObject"
          }
        ]
      },
      "JSONObject": {
        "type": "object",
        "propertyNames": {
          "pattern": "^[^/]*$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/JSONValue"
        }
      },
      "Envelope": {
        "type": "object",
        "required": [
          "ok",
          "data"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "data": {}
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "const": false
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "SetOperation": {
        "type": "object",
        "required": [
          "op",
          "path",
          "value"
        ],
        "properties": {
          "op": {
            "const": "set"
          },
          "path": {
            "$ref": "#/components/schemas/PropertyPath"
          },
          "value": {
            "$ref": "#/components/schemas/JSONValue"
          }
        }
      },
      "DeleteOperation": {
        "type": "object",
        "required": [
          "op",
          "path"
        ],
        "properties": {
          "op": {
            "const": "delete"
          },
          "path": {
            "$ref": "#/components/schemas/PropertyPath"
          }
        }
      },
      "PropertyPath": {
        "type": "array",
        "minItems": 1,
        "maxItems": 64,
        "items": {
          "type": "string",
          "pattern": "^[^/]*$",
          "description": "每段最多512 UTF-8字节；数组索引为字符串。"
        }
      },
      "Idempotency": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[!-~]+$"
      },
      "PatchBody": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "operations"
            ],
            "properties": {
              "operations": {
                "type": "array",
                "minItems": 1,
                "maxItems": 1000,
                "items": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SetOperation"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteOperation"
                    }
                  ]
                }
              },
              "idempotency_key": {
                "$ref": "#/components/schemas/Idempotency"
              }
            }
          },
          {
            "type": "object",
            "anyOf": [
              {
                "required": [
                  "set"
                ]
              },
              {
                "required": [
                  "delete"
                ]
              }
            ],
            "properties": {
              "set": {
                "$ref": "#/components/schemas/JSONObject"
              },
              "delete": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[^/]*$"
                }
              },
              "idempotency_key": {
                "$ref": "#/components/schemas/Idempotency"
              }
            }
          }
        ]
      },
      "ReplaceBody": {
        "type": "object",
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "$ref": "#/components/schemas/JSONObject"
          },
          "idempotency_key": {
            "$ref": "#/components/schemas/Idempotency"
          }
        }
      }
    }
  }
}
