{ "openapi": "3.1.0", "info": { "title": "FluxDown API", "description": "FluxDown 桌面应用的本机 HTTP API。仅监听 `127.0.0.1`(默认端口 17800,可在 设置 → API 服务 中修改)。\n\n- **takeover**(脚本接管):油猴脚本提交下载,进入快速下载确认流程;需 `X-FluxDown-Client` 头\n- **aria2**:aria2 JSON-RPC 兼容垫片,「发送到 aria2」类脚本与 AriaNg 可直接对接\n- **management**(管理 API):任务查询/创建/暂停/恢复/删除与队列查询,供 MCP/自动化客户端使用;强制要求 token(`Authorization: Bearer ` 或 `X-FluxDown-Token` 头)", "license": { "name": "MIT", "identifier": "MIT" }, "version": "0.1.0" }, "servers": [ { "url": "http://127.0.0.1:17800", "description": "本机 API 服务(默认端口)" } ], "paths": { "/api/v1/groups": { "get": { "tags": [ "groups" ], "summary": "列出全部任务组。", "operationId": "api_list_groups", "responses": { "200": { "description": "任务组列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GroupDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "post": { "tags": [ "groups" ], "summary": "创建多文件任务组(建组 + N 子任务),返回新组 ID。`items` 为空 → 400。", "operationId": "api_create_group", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGroupRequest" } } }, "required": true }, "responses": { "200": { "description": "创建成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGroupResponse" } } } }, "400": { "description": "载荷非法或 items 为空", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "503": { "description": "应用关闭中", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/groups/{id}": { "delete": { "tags": [ "groups" ], "summary": "删除任务组(批量删成员),可选同时删除磁盘文件。", "operationId": "api_delete_group", "parameters": [ { "name": "id", "in": "path", "description": "任务组 ID(UUID)", "required": true, "schema": { "type": "string" } }, { "name": "deleteFiles", "in": "path", "description": "true = 同时删除磁盘文件。默认 false(仅删记录)。", "required": true, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "已删除", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务组不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/groups/{id}/continue": { "put": { "tags": [ "groups" ], "summary": "恢复组内全部成员。", "operationId": "api_group_continue", "parameters": [ { "name": "id", "in": "path", "description": "任务组 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已恢复", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务组不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/groups/{id}/pause": { "put": { "tags": [ "groups" ], "summary": "暂停组内全部成员。", "operationId": "api_group_pause", "parameters": [ { "name": "id", "in": "path", "description": "任务组 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已暂停", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务组不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/info": { "get": { "tags": [ "management" ], "summary": "应用信息(名称与版本号)。", "operationId": "api_info", "responses": { "200": { "description": "应用信息", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiInfo" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "403": { "description": "服务端未配置 token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/code": { "post": { "tags": [ "link" ], "summary": "生成一次性配对码(**需 management token**)。供 web/CLI 让 headless 设备出示。", "description": "生成一次性配对码,供发起方在 pair/hello 出示。**需 management token**。", "operationId": "api_link_generate_code", "responses": { "200": { "description": "配对码 + 有效期", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkCodeResponse" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "delete": { "tags": [ "link" ], "summary": "停止 mDNS 广播(撤销「可被发现」状态);配对码本身若未过期仍可用\n(手动地址/已知连接仍能核对),只是不再出现在局域网 mDNS 扫描里。", "description": "停止 mDNS 广播(撤销「可被发现」状态);配对码本身未过期仍可用,只是不再出现在局域网扫描里。**需 management token**。", "operationId": "api_link_stop_advertising", "responses": { "200": { "description": "已停止", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkOkResponse" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/devices": { "get": { "tags": [ "link" ], "summary": "已配对设备列表(含并发在线探测)。", "description": "已配对设备列表(含并发在线探测)。**需 management token**。", "operationId": "api_link_devices", "responses": { "200": { "description": "设备列表", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkDevicesResponse" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/devices/{fingerprint}": { "delete": { "tags": [ "link" ], "summary": "解除配对(删除设备)。", "description": "解除配对(删除设备记录及双方链路密钥)。**需 management token**。", "operationId": "api_link_remove_device", "parameters": [ { "name": "fingerprint", "in": "path", "description": "设备指纹", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已解除", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkOkResponse" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "设备不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/devices/{fingerprint}/tasks": { "post": { "tags": [ "link" ], "summary": "下发下载任务给已配对设备(管理面,token 鉴权;区别于数据面链路 HMAC 鉴权的\n`POST /api/v1/link/tasks`)。", "description": "下发下载任务给已配对设备(管理面,token 鉴权;区别于数据面链路 HMAC 鉴权的 `POST /api/v1/link/tasks`)。**需 management token**。", "operationId": "api_link_device_tasks", "parameters": [ { "name": "fingerprint", "in": "path", "description": "目标设备指纹", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkDeviceTaskRequest" } } }, "required": true }, "responses": { "200": { "description": "创建成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedTask" } } } }, "400": { "description": "载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效,或目标设备不存在/未配对", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/discovered": { "get": { "tags": [ "link" ], "summary": "当前发现快照(发起方侧 UI 轮询)。", "description": "当前发现快照(发起方侧 UI 轮询)。**需 management token**。", "operationId": "api_link_discovered", "responses": { "200": { "description": "发现到的对端列表", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkDiscoveredResponse" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/discovery": { "post": { "tags": [ "link" ], "summary": "本地设备发现开关:`start` 幂等且清空发现快照;`stop` 停止 mDNS 浏览。", "description": "本地设备发现开关:`start` 幂等且清空发现快照,`stop` 停止 mDNS 浏览。**需 management token**。", "operationId": "api_link_discovery", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkDiscoveryRequest" } } }, "required": true }, "responses": { "200": { "description": "已切换", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkOkResponse" } } } }, "400": { "description": "action 非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/info": { "post": { "tags": [ "link" ], "summary": "已配对设备经已认证链路交换设备信息(默认下载目录 / 路径风格)。", "description": "数据面:已配对设备交换设备信息(默认下载目录 / 路径风格)。**无 management token**,鉴权靠 `X-FluxLink-*` 头(同 `/api/v1/link/tasks`)。请求体与响应体都是 AEAD 密文(`application/octet-stream`);旧版对端没有该端点(404)。", "operationId": "api_link_info", "responses": { "200": { "description": "用链路密钥加密的本机信息(二进制)" }, "401": { "description": "缺少/无效链路鉴权头", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } } } }, "/api/v1/link/pair/approve": { "post": { "tags": [ "link" ], "summary": "批准/拒绝一次入站配对核验(响应本机收到的 `IncomingPairing` 通知;区别于\n发起方视角、核对 SAS 后调用的 [`api_link_pair_finish`])。", "description": "批准/拒绝一次入站配对核验(响应本机收到的 `IncomingPairing` 通知;区别于发起方视角、核对 SAS 后调用的 pair/finish)。**需 management token**。", "operationId": "api_link_pair_approve", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairApproveRequest" } } }, "required": true }, "responses": { "200": { "description": "已处理", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkOkResponse" } } } }, "400": { "description": "会话不存在/已过期,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/pair/begin": { "post": { "tags": [ "link" ], "summary": "发起配对:向 `host:port` 发送 `hello`(带配对码),返回待确认令牌 + SAS +\n对端信息,供 UI 展示 SAS 核对后调 [`api_link_pair_finish`]。", "description": "发起配对:向 `host:port` 发送 hello(带配对码),返回待确认令牌 + SAS,供 UI 展示核对后调用 pair/finish。**需 management token**。", "operationId": "api_link_pair_begin", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairBeginRequest" } } }, "required": true }, "responses": { "200": { "description": "待确认令牌 + SAS + 对端信息", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairBeginResponse" } } } }, "400": { "description": "配对码错误,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "503": { "description": "对端不可达,或本机待确认配对已达上限", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/pair/confirm": { "post": { "tags": [ "link" ], "summary": "处理配对 `confirm`(SAS 核对后确认/拒绝)。", "description": "配对第三步:核对 SAS 后确认/拒绝(响应方内部会话,由 pair/hello 建立、pair/reveal 揭示后的 sessionId 守卫;未揭示的会话上 confirm=true 属协议违规)。**无 token 鉴权**。", "operationId": "api_link_pair_confirm", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairConfirmRequest" } } }, "required": true }, "responses": { "200": { "description": "`{success,paired,reason}`" }, "400": { "description": "会话不存在/已过期,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } } } }, "/api/v1/link/pair/finish": { "post": { "tags": [ "link" ], "summary": "SAS 核对后确认/拒绝配对(管理面版本,区别于响应方内部 `pair/confirm`)。", "description": "SAS 核对后确认/拒绝配对(管理面视角,区别于响应方内部 `pair/confirm`)。**需 management token**。", "operationId": "api_link_pair_finish", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairFinishRequest" } } }, "required": true }, "responses": { "200": { "description": "`paired=false` 表示对端拒绝,此时 device 省略", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairFinishResponse" } } } }, "400": { "description": "令牌不存在/已过期,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/pair/hello": { "post": { "tags": [ "link" ], "summary": "处理配对 `hello`(发起方 → 本机)。", "description": "配对握手第一步(发起方 → 响应方)。**无 token 鉴权**:由响应方 UI 展示的一次性配对码守卫,重复/过期码拒绝。请求只携带发起方临时公钥与随机数的承诺;响应方回出本次会话全新的临时公钥与随机数(不含 SAS)。`protocolVersion` 与响应方不一致(含旧版发起方)一律以版本不兼容拒绝。", "operationId": "api_link_pair_hello", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairHelloRequest" } } }, "required": true }, "responses": { "200": { "description": "响应方本次会话的临时公钥与随机数", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairHelloResponse" } } } }, "400": { "description": "配对码错误/过期/已用、协议版本不兼容,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } } } }, "/api/v1/link/pair/reveal": { "post": { "tags": [ "link" ], "summary": "处理配对 `reveal`(发起方揭示 hello 里承诺的临时公钥)。", "description": "配对握手第二步(发起方 → 响应方):揭示 `pair/hello` 里承诺过的临时公钥与随机数,响应方核对承诺后返回对完整握手转录的身份签名。**无 token 鉴权**:由 `pair/hello` 建立的 sessionId 与公钥承诺守卫,承诺不符即作废会话。", "operationId": "api_link_pair_reveal", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairRevealRequest" } } }, "required": true }, "responses": { "200": { "description": "响应方对完整转录的签名", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkPairRevealResponse" } } } }, "400": { "description": "会话不存在/已过期、承诺不符,或载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } } } }, "/api/v1/link/probe": { "post": { "tags": [ "link" ], "summary": "手动地址探测(mDNS 失效兜底);结果不入发现快照。", "description": "手动地址探测(mDNS 失效兜底);结果不入发现快照,直接返回给调用方。**需 management token**。", "operationId": "api_link_probe", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkProbeRequest" } } }, "required": true }, "responses": { "200": { "description": "探测到的对端信息", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkDiscoveredPeer" } } } }, "400": { "description": "载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "503": { "description": "对端不可达", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/link/tasks": { "post": { "tags": [ "link" ], "summary": "已配对设备下发下载任务:从 `X-FluxLink-*` 头取鉴权凭据 → 校验 → 建任务。", "description": "数据面:已配对设备下发下载任务。**无 management token**,鉴权靠 `X-FluxLink-Device`/`X-FluxLink-Ts`/`X-FluxLink-Nonce`/`X-FluxLink-Auth` 头做每对设备独立密钥的 HMAC 校验。\n\n请求体是对明文 JSON 任务描述做 AEAD 加密后的**二进制密文**(`Content-Type: application/octet-stream`),非普通 JSON;宿主校验鉴权头后解密再反序列化。", "operationId": "api_link_create_task", "responses": { "200": { "description": "创建成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedTask" } } } }, "400": { "description": "载荷非法(含解密失败)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "缺少/无效链路鉴权头", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } } } }, "/api/v1/market": { "get": { "tags": [ "plugins" ], "summary": "拉取去中心化插件市场索引。", "operationId": "api_market_list", "responses": { "200": { "description": "市场索引条目", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MarketEntryDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/market/install": { "post": { "tags": [ "plugins" ], "summary": "从市场安装某插件最新版。", "operationId": "api_market_install", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketInstallRequest" } } }, "required": true }, "responses": { "200": { "description": "安装成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstalledPlugin" } } } }, "400": { "description": "下载/校验/安装失败", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins": { "get": { "tags": [ "plugins" ], "summary": "列出全部已安装插件。", "operationId": "api_list_plugins", "responses": { "200": { "description": "插件列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PluginDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/install": { "post": { "tags": [ "plugins" ], "summary": "从 zip 安装插件(≤4MB,受全局请求体上限约束)。", "operationId": "api_install_plugin", "responses": { "200": { "description": "安装成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstalledPlugin" } } } }, "400": { "description": "zip 非法或超限", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/install-dev": { "post": { "tags": [ "plugins" ], "summary": "dev 安装插件(引用目录,不拷贝)。", "operationId": "api_install_plugin_dev", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstallPluginDevRequest" } } }, "required": true }, "responses": { "200": { "description": "安装成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InstalledPlugin" } } } }, "400": { "description": "路径非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/{identity}": { "delete": { "tags": [ "plugins" ], "summary": "卸载插件。", "operationId": "api_uninstall_plugin", "parameters": [ { "name": "identity", "in": "path", "description": "插件 identity", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已卸载", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/{identity}/auth": { "post": { "tags": [ "plugins" ], "summary": "驱动插件登录流程(二维码/账号登录)。认证结果只返回交互状态,凭据由引擎保存。", "operationId": "api_plugin_auth", "parameters": [ { "name": "identity", "in": "path", "description": "插件 identity", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PluginAuthRequest" } } }, "required": true }, "responses": { "200": { "description": "登录交互状态", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PluginAuthResponse" } } } }, "400": { "description": "插件登录失败", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/{identity}/enabled": { "put": { "tags": [ "plugins" ], "summary": "启用/禁用插件。", "operationId": "api_set_plugin_enabled", "parameters": [ { "name": "identity", "in": "path", "description": "插件 identity", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetPluginEnabledRequest" } } }, "required": true }, "responses": { "200": { "description": "已更新", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/plugins/{identity}/settings": { "put": { "tags": [ "plugins" ], "summary": "批量更新插件设置(all-or-nothing)。请求体为 `{key: value}` 字符串映射。", "operationId": "api_update_plugin_settings", "parameters": [ { "name": "identity", "in": "path", "description": "插件 identity", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已保存", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "设置校验失败", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/queues": { "get": { "tags": [ "management" ], "summary": "列出全部命名队列。", "operationId": "api_list_queues", "responses": { "200": { "description": "队列列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/QueueDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/resolve/preview": { "post": { "tags": [ "groups" ], "summary": "前置预解析清单(多文件清单,只读、不建任务、不写库)。强制鉴权——\n会触发插件网络调用(网盘 API),与管理 API 其余端点同一门禁。", "operationId": "api_resolve_preview", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResolvePreviewRequest" } } }, "required": true }, "responses": { "200": { "description": "预解析结果(items 为空且 error 为空 = 插件未返回清单)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResolvePreviewResponse" } } } }, "400": { "description": "载荷非法或缺少 url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss": { "get": { "tags": [ "rss" ], "summary": "列出全部 RSS 订阅。", "operationId": "api_list_rss_sources", "responses": { "200": { "description": "订阅列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RssSourceDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "post": { "tags": [ "rss" ], "summary": "新建 RSS 订阅,返回新订阅 ID。`url` 为空 → 400。", "operationId": "api_create_rss_source", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RssSourceDto" } } }, "required": true }, "responses": { "200": { "description": "创建成功,`{sourceId}`" }, "400": { "description": "载荷非法或缺少 url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss/validate": { "post": { "tags": [ "rss" ], "summary": "只读验证一个 feed 地址(新建订阅向导)。抓取失败**不是** HTTP 错误:\n这是一次诊断调用,失败原因本身就是有效载荷,仍回 200 + `error` 非空。", "operationId": "api_validate_rss_feed", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RssValidateRequest" } } }, "required": true }, "responses": { "200": { "description": "验证结果(`error` 非空 = 抓取失败)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RssValidateResponse" } } } }, "400": { "description": "载荷非法或缺少 url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss/{id}": { "put": { "tags": [ "rss" ], "summary": "更新订阅配置。运行态字段(`lastFetchAt`/`failCount` 等)写入被忽略。", "operationId": "api_update_rss_source", "parameters": [ { "name": "id", "in": "path", "description": "订阅 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RssSourceDto" } } }, "required": true }, "responses": { "200": { "description": "已更新", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "订阅不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "delete": { "tags": [ "rss" ], "summary": "删除订阅(级联删条目)。已建下载任务保留——用户要的是不再抓新条目,\n不是撤销已下载的东西。", "operationId": "api_delete_rss_source", "parameters": [ { "name": "id", "in": "path", "description": "订阅 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已删除", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "订阅不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss/{id}/items": { "get": { "tags": [ "rss" ], "summary": "一个订阅的条目流(新→旧)。", "operationId": "api_list_rss_items", "parameters": [ { "name": "id", "in": "path", "description": "订阅 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "条目列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RssItemDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "订阅不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss/{id}/items/action": { "post": { "tags": [ "rss" ], "summary": "对条目执行手动操作(下载 / 忽略 / 全部标记已读)。guid 在请求体里,\n不进路径段——真实 feed 的 guid 常常是一整条 URL。", "operationId": "api_rss_item_action", "parameters": [ { "name": "id", "in": "path", "description": "订阅 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RssItemActionRequest" } } }, "required": true }, "responses": { "200": { "description": "已执行", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "载荷非法或 action 未知", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "订阅或条目不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/rss/{id}/refresh": { "post": { "tags": [ "rss" ], "summary": "立即抓取一个订阅。抓取异步派发,本端点只表示「已受理」,结果走\n`rssSourcesChanged` / `rssItemsChanged` 事件;该订阅已在抓取时同样视为成功,\n仅订阅不存在返回 404。", "operationId": "api_refresh_rss_source", "parameters": [ { "name": "id", "in": "path", "description": "订阅 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已受理(已派发抓取;该订阅已在抓取时同样视为成功)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "订阅不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/site-auth": { "get": { "tags": [ "management" ], "summary": "列出已保存的站点凭据;只返回站点和用户名,不返回密码。", "operationId": "api_list_site_auth", "responses": { "200": { "description": "脱敏后的站点凭据列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SiteAuthEntryDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "put": { "tags": [ "management" ], "summary": "保存单个站点 HTTP Basic 凭据。", "operationId": "api_save_site_auth", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SiteAuthSaveRequest" } } }, "required": true }, "responses": { "200": { "description": "已保存", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SiteAuthEntryDto" } } } }, "400": { "description": "载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/site-auth/{site}": { "get": { "tags": [ "management" ], "summary": "读取单个站点凭据详情。只允许按站点定向读取,不进入通用配置快照。", "description": "**`pass` 字段是明文密码**(未脱敏):仅供编辑对话框回填原值,调用方不应\n在列表页/日志里回显;列表接口 [`api_list_site_auth`] 本就不含密码(L-1)。", "operationId": "api_get_site_auth", "parameters": [ { "name": "site", "in": "path", "description": "host 或 host:port", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "站点凭据详情;pass 为明文密码,仅用于编辑表单回填,不要在列表/日志中回显", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SiteAuthCredentialDto" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "站点凭据不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "delete": { "tags": [ "management" ], "summary": "删除单个站点凭据。", "operationId": "api_delete_site_auth", "parameters": [ { "name": "site", "in": "path", "description": "host 或 host:port", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已删除", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "站点凭据不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks": { "get": { "tags": [ "management" ], "summary": "列出全部任务,可按状态过滤。", "operationId": "api_list_tasks", "parameters": [ { "name": "status", "in": "path", "description": "按状态过滤:0=pending, 1=downloading, 2=paused, 3=completed, 4=error, 5=preparing", "required": true, "schema": { "type": [ "integer", "null" ], "format": "int32" } } ], "responses": { "200": { "description": "任务列表", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TaskDto" } } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "post": { "tags": [ "management" ], "summary": "直接创建下载任务(不弹确认框),返回新任务 ID。", "operationId": "api_create_task", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTaskRequest" } } }, "required": true }, "responses": { "200": { "description": "创建成功", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedTask" } } } }, "400": { "description": "载荷非法或缺少 url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "503": { "description": "应用关闭中", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/continue": { "put": { "tags": [ "management" ], "summary": "恢复全部已暂停任务。", "operationId": "api_continue_all", "responses": { "200": { "description": "已全部恢复", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/pause": { "put": { "tags": [ "management" ], "summary": "暂停全部活跃任务(pending / downloading / preparing)。", "operationId": "api_pause_all", "responses": { "200": { "description": "已全部暂停", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}": { "get": { "tags": [ "management" ], "summary": "按 ID 查询单个任务。", "operationId": "api_get_task", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "任务信息", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskDto" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] }, "delete": { "tags": [ "management" ], "summary": "删除任务,可选同时删除磁盘文件。", "operationId": "api_delete_task", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } }, { "name": "deleteFiles", "in": "path", "description": "true = 同时删除磁盘文件。默认 false(仅删记录)。", "required": true, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "已删除", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}/continue": { "put": { "tags": [ "management" ], "summary": "恢复单个任务。", "operationId": "api_continue_task", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已恢复", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}/ignore-plugin-retry": { "post": { "tags": [ "plugins" ], "summary": "任务级逃生舱:忽略插件重试,按原始链接重跑。", "operationId": "api_ignore_plugin_retry", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已按原始链接重跑", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}/pause": { "put": { "tags": [ "management" ], "summary": "暂停单个任务。", "operationId": "api_pause_task", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "已暂停", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}/rename": { "post": { "tags": [ "management" ], "summary": "重命名任务文件。", "operationId": "api_rename_task", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RenameTaskRequest" } } }, "required": true }, "responses": { "200": { "description": "已重命名", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "文件名非法(message 为错误码 `invalid-name`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "409": { "description": "业务拒绝(message 为错误码 `task-active` / `bt-unsupported` / `target-exists`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/api/v1/tasks/{id}/url": { "put": { "tags": [ "management" ], "summary": "更换任务下载源地址。", "operationId": "api_change_task_url", "parameters": [ { "name": "id", "in": "path", "description": "任务 ID(UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeTaskUrlRequest" } } }, "required": true }, "responses": { "200": { "description": "已更换", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "地址非法(message 为错误码 `invalid-url` 或 thunder 解码错误原文)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "404": { "description": "任务不存在", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "409": { "description": "业务拒绝(message 为错误码 `task-active` / `task-completed` / `bt-unsupported` / `protocol-unsupported` / `protocol-mismatch`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/download": { "post": { "tags": [ "takeover" ], "summary": "提交单个外部下载请求。用 `Bytes` 而非 `Json` 提取:油猴脚本可能不带\n`application/json` Content-Type(保留旧实现的宽容行为)。", "operationId": "takeover_download", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DownloadRequest" } } }, "required": true }, "responses": { "200": { "description": "已受理,进入快速下载确认流程", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "载荷非法或缺少 url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "403": { "description": "缺少 X-FluxDown-Client 头", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "tokenHeader": [] } ] } }, "/download/batch": { "post": { "tags": [ "takeover" ], "summary": "批量提交外部下载请求。支持 `{\"urls\":[...]}` 与 `{\"items\":[{...}]}` 两种形态,\n合并为单次确认。鉴权与 `/download` 相同。", "operationId": "takeover_download_batch", "responses": { "200": { "description": "已受理", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "400": { "description": "载荷非法", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "tokenHeader": [] } ] } }, "/jsonrpc": { "post": { "tags": [ "aria2" ], "summary": "aria2 客户端约定:HTTP 层始终 200,错误在 JSON-RPC envelope 内表达。", "operationId": "jsonrpc", "responses": { "200": { "description": "JSON-RPC 响应(错误在 envelope 内表达)。支持方法:aria2.addUri / aria2.getVersion / aria2.getGlobalStat / system.multicall / system.listMethods;token 可经 X-FluxDown-Token 头或 params[0]=\"token:xxx\" 传递" } }, "security": [ { "tokenHeader": [] } ] } }, "/mcp": { "post": { "tags": [ "mcp" ], "summary": "MCP(Model Context Protocol)端点。强制 token 鉴权(Bearer /\nX-FluxDown-Token,复用管理 API 门禁)。请求返回 `200 application/json`\nJSON-RPC 响应;通知(无 `id`)返回 `202 Accepted` 空体。", "operationId": "mcp", "responses": { "200": { "description": "JSON-RPC 响应(initialize / tools/list / tools/call / ping)" }, "202": { "description": "通知已接受(无响应体)" }, "401": { "description": "token 无效", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } }, "403": { "description": "服务端未配置 token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultMessage" } } } } }, "security": [ { "bearerAuth": [] }, { "tokenHeader": [] } ] } }, "/ping": { "get": { "tags": [ "system" ], "summary": "探活。返回应用名、版本号与 `pong`;宿主配置了 Web UI 语言时附带 `language`\n(无鉴权——登录前的前端靠它决定界面默认语言;经 [`ApiHost::web_language`]\n实时求值,配置变更无需重启)。", "operationId": "ping", "responses": { "200": { "description": "应用存活,返回 app/version/message;配置了 Web 语言时附带 language" } } } } }, "components": { "schemas": { "ApiInfo": { "type": "object", "description": "应用信息(`GET /api/v1/info` 响应)。", "required": [ "name", "version" ], "properties": { "name": { "type": "string" }, "version": { "type": "string" } } }, "ChangeTaskUrlRequest": { "type": "object", "description": "更换任务下载源地址请求体。", "required": [ "url" ], "properties": { "url": { "type": "string", "description": "新下载地址(http(s)/ftp,或待解封装的 `thunder://` 链接)。" } } }, "CreateGroupRequest": { "type": "object", "description": "创建多文件任务组请求(`POST /api/v1/groups`)。`items` 不可为空\n(空数组 → 400)。\n\n# Examples\n", "properties": { "cookies": { "type": "string" }, "extraHeaders": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "groupName": { "type": "string", "description": "组名(空 = 组根目录直接用 `save_dir`)。" }, "ignoreTlsErrors": { "type": "boolean", "description": "忽略 HTTPS 证书错误。缺省 false(严格验证)。" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/GroupItemRequest" }, "description": "组成员清单(不可为空,见本类型文档)。" }, "proxyUrl": { "type": "string", "description": "单任务代理 URL(空 = 使用全局代理)。" }, "queueId": { "type": "string", "description": "命名队列 ID(空 = 默认队列)。" }, "referrer": { "type": "string" }, "saveDir": { "type": "string", "description": "基础保存目录(组根目录 = `save_dir/sanitize(group_name)`);\n空 = 使用全局默认保存目录。" }, "segments": { "type": "integer", "format": "int32", "description": "0 = 由 segment_advisor 按文件大小动态决定。" }, "sourceUrl": { "type": "string", "description": "原始分享/清单链接(组行 `source_url`,展示/复制用)。" }, "startPaused": { "type": "boolean", "description": "稍后下载:true = 建组后不启动,待「启动队列」或用户手动恢复。" }, "userAgent": { "type": "string" } } }, "CreateGroupResponse": { "type": "object", "description": "创建任务组响应(`POST /api/v1/groups`)。", "required": [ "groupId" ], "properties": { "groupId": { "type": "string" } } }, "CreateTaskRequest": { "type": "object", "description": "创建任务请求(`POST /api/v1/tasks`)。\n\n与外部下载请求 [`DownloadRequest`] 不同:本请求**直接创建任务**,\n不经过快速下载确认弹框(管理 API 的调用方是受信任的自动化客户端)。\n\n# Examples\n", "required": [ "url" ], "properties": { "audioUrl": { "type": [ "string", "null" ], "description": "音频轨 URL(「视频轨+音频轨」离散下载对语义)。\n非空 = 引擎分别下载两路后 mux 合并;空/缺省 = 普通单 URL 下载。" }, "body": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/RequestBody", "description": "浏览器原始请求体(仅非 GET 时有意义)。" } ] }, "checksum": { "type": "string", "description": "Checksum spec,格式 `algo=hexhash`(空 = 跳过校验)。" }, "cookies": { "type": "string" }, "fileName": { "type": "string", "description": "空 = 从 URL / Content-Disposition 推断。" }, "headers": { "type": [ "object", "null" ], "description": "附加 HTTP 请求头。", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "httpPassword": { "type": "string", "description": "HTTP Basic 认证密码(仅 `httpUser` 非空时有意义,允许为空串)。" }, "httpUser": { "type": "string", "description": "HTTP Basic 认证用户名。非空时引擎生成 `Authorization: Basic` 头\n注入请求(覆盖 `headers` 中的同名头)。空 = 未提供,若该站点有\n已保存凭据则自动套用。" }, "ignoreTlsErrors": { "type": "boolean", "description": "忽略 HTTPS 证书错误。缺省 false(严格验证)。" }, "method": { "type": [ "string", "null" ], "description": "浏览器原始 HTTP method(`\"GET\"`/`\"POST\"`/…)。缺省 = GET。\nform-POST 触发的下载必须携带,否则引擎用 GET 重发会拿到错误内容。" }, "proxyUrl": { "type": "string", "description": "单任务代理 URL(空 = 使用全局代理)。" }, "queueId": { "type": "string", "description": "命名队列 ID(空 = 默认队列)。" }, "referrer": { "type": "string" }, "saveDir": { "type": "string", "description": "空 = 使用全局默认保存目录。" }, "saveSiteAuth": { "type": "boolean", "description": "为此网站保存凭据:true 且 `httpUser` 非空时按站点(host[:port])\n持久化,供后续同站点任务自动套用。" }, "segments": { "type": "integer", "format": "int32", "description": "0 = 由 segment_advisor 按文件大小动态决定。" }, "startPaused": { "type": "boolean", "description": "稍后下载:true = 建任务后不启动(paused 落库),待「启动队列」\n按序恢复或用户手动恢复。缺省 false = 立即开始。" }, "torrentB64": { "type": [ "string", "null" ], "description": "BT 种子文件字节(base64 编码,aria2 `addTorrent` 兼容入口)。\n非空时按种子任务创建,`url` 允许为空占位。" }, "url": { "type": "string" }, "userAgent": { "type": "string", "description": "空 = 使用全局 User-Agent。" } } }, "CreatedTask": { "type": "object", "description": "创建任务响应(`POST /api/v1/tasks`)。", "required": [ "taskId" ], "properties": { "taskId": { "type": "string" } } }, "DownloadRequest": { "type": "object", "description": "外部下载请求载荷(浏览器扩展 / 油猴脚本 / aria2 兼容层)。\n\n由宿主的「外部下载」通道消费:缓存请求事务 → 弹出快速下载确认框 →\n用户确认后创建任务。与管理 API 的 [`CreateTaskRequest`](直接建任务、\n无确认框)语义不同。\n\n# Examples\n", "required": [ "url" ], "properties": { "audioUrl": { "type": [ "string", "null" ], "description": "音频轨 URL(可选,通用「视频轨+音频轨」离散下载对语义,按 MIME\nvideo/* vs audio/* 分轨判定,非站点专用协议字段)。\n非空 = 这是一对轨道,引擎分别下载两路后用 ffmpeg mux 合并;\n空/缺省 = 普通单 URL 下载。" }, "body": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/RequestBody", "description": "浏览器原始请求体(仅在非 GET 时有意义)。" } ] }, "cookies": { "type": "string" }, "fileSize": { "type": [ "integer", "null" ], "format": "int64", "description": "文件大小提示(字节)。\n - `>0` = 已知大小,跳过 probe\n - `-1` = 大小未知但确认是下载资源(webRequest 嗅探),跳过 probe\n - `0` / `None` = 正常 probe" }, "filename": { "type": "string" }, "headers": { "type": [ "object", "null" ], "description": "浏览器请求中捕获的额外 HTTP 头(如 Authorization)。\n由下载引擎在发起请求时附加到请求头中。", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "method": { "type": [ "string", "null" ], "description": "浏览器原始请求方法(\"GET\" / \"POST\" / ...)。\n缺省 = \"GET\"。POST/PUT/PATCH 类请求由 `body` 携带请求体。" }, "mimeType": { "type": [ "string", "null" ] }, "referrer": { "type": "string" }, "saveDir": { "type": "string", "description": "保存目录(aria2 `dir` 选项 / 接管请求 `saveDir` 字段)。\n空 = 由宿主按分类匹配 / 默认目录决定。" }, "url": { "type": "string" } } }, "GroupDto": { "type": "object", "description": "任务组信息(`GET /api/v1/groups` 响应元素)。\n\n# Examples\n", "required": [ "groupId", "name", "sourceUrl", "saveDir", "createdAt" ], "properties": { "createdAt": { "type": "string", "description": "Unix 秒级时间戳(字符串)。" }, "groupId": { "type": "string" }, "name": { "type": "string" }, "saveDir": { "type": "string", "description": "组根目录(子任务落盘 = 本值 + 清单条目的相对路径)。" }, "sourceUrl": { "type": "string", "description": "原始分享/清单链接(展示/复制用)。" } } }, "GroupItemRequest": { "type": "object", "description": "[`CreateGroupRequest::items`] 的单个组成员条目(客户端在预览响应上\n勾选后的清单条目/规格投影)。", "required": [ "resolverItem", "fileName" ], "properties": { "fileName": { "type": "string" }, "relPath": { "type": "string", "description": "相对组根目录的子路径(空 = 组根)。" }, "resolverItem": { "type": "string", "description": "二段解析标识,按 `` 或 `@` 拼接(见\n[`PreviewItemDto::id`]/[`PreviewVariantDto::id`])。" }, "size": { "type": "integer", "format": "int64", "description": "已知大小(字节,0 = 未知)。" } } }, "InstallPluginDevRequest": { "type": "object", "description": "安装 dev 插件请求体。", "required": [ "dirPath" ], "properties": { "dirPath": { "type": "string" } } }, "InstalledPlugin": { "type": "object", "description": "安装成功返回体。\n\n`missing_components` 列出插件声明权限所需、但尚未安装的基础组件\n(如 `\"ffmpeg\"`/`\"ytdlp\"`,依赖表见引擎 `plugin::dependencies`)——\n提醒式而非阻断式:安装本身已成功,客户端应提示用户前往组件设置安装依赖。", "required": [ "identity" ], "properties": { "identity": { "type": "string" }, "missingComponents": { "type": "array", "items": { "type": "string" } } } }, "LinkCodeResponse": { "type": "object", "description": "生成配对码的响应(`POST /api/v1/link/code`)。", "required": [ "code", "ttlSeconds" ], "properties": { "code": { "type": "string", "description": "6 位一次性配对码。" }, "ttlSeconds": { "type": "integer", "format": "int64", "description": "有效秒数。" } } }, "LinkDeviceInfo": { "type": "object", "description": "一台**已配对**设备的对外视图(`GET /api/v1/link/devices` 元素)。严禁透出\n`link_secret`/`identity_pub` 等敏感字段(对应引擎 `link::PeerRecord`)。", "required": [ "fingerprint", "name", "online", "pairedAt", "lastSeenAt" ], "properties": { "defaultSaveDir": { "type": [ "string", "null" ], "description": "对端自报的默认下载目录(经已认证链路获取;旧版对端为 `None`)。" }, "fingerprint": { "type": "string" }, "lastSeenAt": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "online": { "type": "boolean", "description": "并发探测得到的在线状态(见 `ApiHost::link_devices` 实现)。" }, "pairedAt": { "type": "integer", "format": "int64" }, "pathStyle": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PathStyle", "description": "对端自报的路径风格(旧版对端为 `None`,可按 `platform` 推断)。" } ] }, "platform": { "type": [ "string", "null" ] } } }, "LinkDeviceTaskRequest": { "type": "object", "description": "已配对设备下发下载任务请求体(管理面,token 鉴权;区别于数据面链路 HMAC\n鉴权的 [`LinkTaskRequest`],字段语义一致)。", "required": [ "url" ], "properties": { "fileName": { "type": [ "string", "null" ] }, "saveDir": { "type": [ "string", "null" ] }, "url": { "type": "string" } } }, "LinkDevicesResponse": { "type": "object", "description": "已配对设备列表响应(`GET /api/v1/link/devices`)。", "required": [ "devices" ], "properties": { "devices": { "type": "array", "items": { "$ref": "#/components/schemas/LinkDeviceInfo" } } } }, "LinkDiscoveredPeer": { "type": "object", "description": "一台被发现、尚未配对的设备(`GET /api/v1/link/discovered` 元素 /\n`POST /api/v1/link/probe` 响应)。对应引擎 `link::DiscoveredPeer`(宿主层\n转换,`kind` → `source` 小写字符串 `\"mdns\"`/`\"manual\"`)。", "required": [ "name", "host", "port", "source" ], "properties": { "appVersion": { "type": [ "string", "null" ] }, "fingerprint": { "type": [ "string", "null" ], "description": "对端指纹(经 `/ping` TOFU 获得;mDNS 未探测到时为 `None`)。" }, "host": { "type": "string" }, "name": { "type": "string" }, "platform": { "type": [ "string", "null" ] }, "port": { "type": "integer", "format": "int32", "minimum": 0 }, "source": { "type": "string", "description": "发现途径:`\"mdns\"` | `\"manual\"`。" } } }, "LinkDiscoveredResponse": { "type": "object", "description": "发现快照响应(`GET /api/v1/link/discovered`)。", "required": [ "peers" ], "properties": { "peers": { "type": "array", "items": { "$ref": "#/components/schemas/LinkDiscoveredPeer" } } } }, "LinkDiscoveryRequest": { "type": "object", "description": "本地设备发现开关请求体(`POST /api/v1/link/discovery`)。", "required": [ "action" ], "properties": { "action": { "type": "string", "description": "`\"start\"` | `\"stop\"`。" } } }, "LinkOkResponse": { "type": "object", "description": "通用 `{\"ok\":true}` 应答(发现开关 / 解除配对)。与 [`ResultMessage`] 的\n`{\"success\",\"message\"}` 形态不同——契约就此路由指定的字面 wire 形状。", "required": [ "ok" ], "properties": { "ok": { "type": "boolean" } } }, "LinkPairApproveRequest": { "type": "object", "description": "批准/拒绝一次入站配对核验(管理面版本;`session_id` 对应\n`LinkEvent{kind:\"incomingPairing\"}` / WS `linkIncomingPairing` 携带的会话 id)。", "required": [ "sessionId", "accept" ], "properties": { "accept": { "type": "boolean" }, "sessionId": { "type": "string" } } }, "LinkPairBeginRequest": { "type": "object", "description": "发起配对请求体(`POST /api/v1/link/pair/begin`)。", "required": [ "host", "port", "code" ], "properties": { "code": { "type": "string" }, "host": { "type": "string" }, "port": { "type": "integer", "format": "int32", "minimum": 0 } } }, "LinkPairBeginResponse": { "type": "object", "description": "发起配对成功后的待确认结果(`POST /api/v1/link/pair/begin` 响应)。", "required": [ "token", "sas", "peerName", "peerFingerprint" ], "properties": { "peerFingerprint": { "type": "string" }, "peerName": { "type": "string" }, "sas": { "type": "string", "description": "供双方肉眼核对的短认证串。" }, "token": { "type": "string" } } }, "LinkPairConfirmRequest": { "type": "object", "description": "配对 `confirm` 请求:SAS 核对后确认/拒绝。", "required": [ "sessionId", "confirm" ], "properties": { "confirm": { "type": "boolean" }, "sessionId": { "type": "string" } } }, "LinkPairFinishRequest": { "type": "object", "description": "SAS 核对后确认/拒绝配对请求体(`POST /api/v1/link/pair/finish`)。", "required": [ "token", "accept" ], "properties": { "accept": { "type": "boolean" }, "token": { "type": "string" } } }, "LinkPairFinishResponse": { "type": "object", "description": "配对完成结果(`POST /api/v1/link/pair/finish` 响应)。`accept=false` 或\n对端拒绝时 `paired=false`,`device` 省略。", "required": [ "paired" ], "properties": { "device": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/LinkDeviceInfo" } ] }, "paired": { "type": "boolean" } } }, "LinkPairHelloRequest": { "type": "object", "description": "配对 `hello` 请求(发起方 → 响应方)。全部密钥/签名字段为 base64。\n\n配对协议版本 2:发起方在这一步只交出临时公钥与随机数的**承诺**,临时公钥本身\n要等响应方回出自己的临时值之后才在 `pair/reveal` 里揭示。", "required": [ "code", "initiatorIdPub", "initiatorSig", "name" ], "properties": { "appVersion": { "type": "string", "description": "发起方客户端版本。" }, "code": { "type": "string", "description": "一次性配对码(响应方 UI 展示、用户手输)。" }, "initiatorAddrs": { "type": "array", "items": { "type": "string" }, "description": "发起方自报可达候选地址(`ip:port`),供响应方存为回连候选。" }, "initiatorCommit": { "type": "string", "description": "发起方临时 X25519 公钥与随机数的承诺 `sha256(eph_pub || nonce)`(base64)。" }, "initiatorIdPub": { "type": "string", "description": "发起方 Ed25519 身份公钥(base64)。" }, "initiatorSig": { "type": "string", "description": "发起方对 hello(码、身份公钥、承诺、自报信息)的 Ed25519 签名(base64)。" }, "name": { "type": "string", "description": "发起方展示名。" }, "platform": { "type": "string", "description": "发起方平台。" }, "protocolVersion": { "type": "integer", "format": "int32", "description": "发起方的配对协议版本。旧版发起方没有这个字段(按 0 处理),与响应方版本不一致\n一律以版本不兼容拒绝。", "minimum": 0 } } }, "LinkPairHelloResponse": { "type": "object", "description": "配对 `hello` 回复(响应方 → 发起方):本次会话全新的临时公钥与随机数。不含 SAS\n与签名——响应方此刻还看不到发起方的临时公钥,两者都在 `pair/reveal` 之后才产生。", "required": [ "protocolVersion", "sessionId", "responderEphPub", "responderNonce", "responderIdPub", "name" ], "properties": { "appVersion": { "type": "string" }, "name": { "type": "string" }, "platform": { "type": "string" }, "protocolVersion": { "type": "integer", "format": "int32", "description": "响应方的配对协议版本。", "minimum": 0 }, "responderEphPub": { "type": "string", "description": "响应方本次会话的临时 X25519 公钥(base64)。" }, "responderIdPub": { "type": "string" }, "responderNonce": { "type": "string", "description": "响应方本次会话的随机数(base64)。" }, "sessionId": { "type": "string" } } }, "LinkPairRevealRequest": { "type": "object", "description": "配对 `reveal` 请求(发起方 → 响应方):揭示 `hello` 里承诺过的临时公钥与随机数。", "required": [ "sessionId", "initiatorEphPub", "initiatorNonce" ], "properties": { "initiatorEphPub": { "type": "string", "description": "发起方临时 X25519 公钥(base64)。" }, "initiatorNonce": { "type": "string", "description": "发起方随机数(base64)。" }, "sessionId": { "type": "string", "description": "`pair/hello` 回复里的会话 id。" } } }, "LinkPairRevealResponse": { "type": "object", "description": "配对 `reveal` 回复(响应方 → 发起方):响应方对完整握手转录的 Ed25519 签名。SAS\n不上线,两端各自在本机屏幕上展示。", "required": [ "responderSig" ], "properties": { "responderSig": { "type": "string", "description": "响应方对完整转录的 Ed25519 签名(base64)。" } } }, "LinkProbeRequest": { "type": "object", "description": "手动地址探测请求体(`POST /api/v1/link/probe`)。", "required": [ "host", "port" ], "properties": { "host": { "type": "string" }, "port": { "type": "integer", "format": "int32", "minimum": 0 } } }, "MarketEntryDto": { "type": "object", "description": "市场索引条目视图(去中心化插件市场浏览/安装)。", "required": [ "pluginId", "version", "sequence", "contentHash" ], "properties": { "author": { "type": "string" }, "contentHash": { "type": "string" }, "description": { "type": "string" }, "homepage": { "type": "string" }, "minAppVersion": { "type": "string" }, "mirrors": { "type": "array", "items": { "type": "string" } }, "name": { "type": "string" }, "permissions": { "type": "array", "items": { "type": "string" }, "description": "manifest 声明的能力权限(如 `[\"ffmpeg\"]`,供安装前展示授权)。" }, "pluginId": { "type": "string" }, "publishTime": { "type": "string" }, "sequence": { "type": "integer", "format": "int64", "minimum": 0 }, "tags": { "type": "array", "items": { "type": "string" } }, "version": { "type": "string" }, "yanked": { "type": "string" } } }, "MarketInstallRequest": { "type": "object", "description": "从市场安装请求体。", "required": [ "pluginId" ], "properties": { "pluginId": { "type": "string" }, "version": { "type": [ "string", "null" ], "description": "用户确认权限时看到的版本;最新可装版本与之不一致时拒绝安装(`Conflict`),\n由客户端刷新目录后重新确认。缺省 = 不钉版本。" } } }, "PathStyle": { "type": "string", "description": "设备本地文件路径的书写风格,决定远程下发时保存目录的合法形态。", "enum": [ "windows", "posix", "unknown" ] }, "PluginAuthRequest": { "type": "object", "description": "驱动插件平台登录(二维码/账号登录)的请求。", "required": [ "action" ], "properties": { "action": { "type": "string", "description": "`begin` / `poll` / `cancel` / `logout` / `status`。" }, "authRef": { "type": "string" }, "identity": { "type": "string" }, "input": { "type": "string", "description": "账号、验证码或平台登录流程需要的额外输入。" }, "sessionId": { "type": "string" }, "site": { "type": "string" } } }, "PluginAuthResponse": { "type": "object", "description": "插件平台登录交互状态。", "required": [ "status", "sessionId" ], "properties": { "authRef": { "type": [ "string", "null" ] }, "challenge": { "type": [ "string", "null" ], "description": "二维码文本、data URL 或其他挑战内容。" }, "challengeType": { "type": [ "string", "null" ] }, "message": { "type": "string" }, "sessionId": { "type": "string" }, "status": { "type": "string", "description": "`pending` / `success` / `error`。" } } }, "PluginDto": { "type": "object", "description": "已安装插件视图(列表/设置表单)。", "required": [ "identity", "name", "version", "enabled", "devMode", "disabledReason", "settings", "settingsValues" ], "properties": { "authSupported": { "type": "boolean", "description": "是否声明平台登录入口。" }, "description": { "type": "string" }, "devMode": { "type": "boolean" }, "disabledReason": { "type": "string", "description": "`None` / `Manual` / `CircuitBreaker`。" }, "enabled": { "type": "boolean" }, "homepage": { "type": "string" }, "identity": { "type": "string" }, "loadError": { "type": "string", "description": "加载失败的可读原因;成功时为空。" }, "loadStatus": { "type": "string", "description": "`Loaded` / `Failed`;与 `enabled` 独立,手动禁用的插件仍可能已加载。" }, "name": { "type": "string" }, "permissions": { "type": "array", "items": { "type": "string" }, "description": "manifest 声明的能力权限(如 `[\"ffmpeg\"]`,供 UI 展示授权徽章)。" }, "settings": { "type": "array", "items": { "$ref": "#/components/schemas/SettingFieldDto" } }, "settingsValues": { "type": "object", "description": "当前设置值(key → value 字符串)。", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "subscriptionProviderIds": { "type": "array", "items": { "type": "string" }, "description": "manifest 声明的订阅 provider ID,供订阅创建界面生成可选来源。" }, "version": { "type": "string" } } }, "PreviewItemDto": { "type": "object", "description": "[`ResolvePreviewResponse::items`] 的单个清单条目。", "required": [ "id", "name", "path", "size", "variants" ], "properties": { "id": { "type": "string", "description": "插件自定义标识,建组时按 `` 或 `@` 拼进\n[`GroupItemRequest::resolver_item`]。" }, "name": { "type": "string" }, "path": { "type": "string", "description": "相对组根目录的子路径(空 = 根)。" }, "size": { "type": "integer", "format": "int64", "description": "已知大小(字节),未知为 0。" }, "variants": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewVariantDto" } } } }, "PreviewVariantDto": { "type": "object", "description": "[`PreviewItemDto::variants`] 的单个规格(画质/格式)。", "required": [ "id", "label", "size" ], "properties": { "id": { "type": "string" }, "label": { "type": "string" }, "size": { "type": "integer", "format": "int64", "description": "已知大小(字节),未知为 0。" } } }, "QueueDto": { "type": "object", "description": "命名队列信息(`GET /api/v1/queues` 响应)。\n\n# Examples\n", "required": [ "queueId", "name", "speedLimitKbps", "maxConcurrent", "defaultSaveDir", "position", "defaultSegments", "defaultUserAgent" ], "properties": { "defaultSaveDir": { "type": "string" }, "defaultSegments": { "type": "integer", "format": "int32" }, "defaultUserAgent": { "type": "string" }, "isRunning": { "type": "boolean", "description": "队列运行状态:停止的队列不自动启动其中任务。" }, "maxConcurrent": { "type": "integer", "format": "int32", "description": "队列并发上限,0 = 跟随全局。" }, "name": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "queueId": { "type": "string" }, "scheduleDays": { "type": "integer", "format": "int32", "description": "定时生效星期位掩码:bit0=周一 … bit6=周日;127 = 每天。" }, "scheduleEnabled": { "type": "boolean", "description": "每日定时计划是否启用。" }, "scheduleStart": { "type": "string", "description": "每日定时启动时间 `HH:MM`(空 = 不定时启动)。" }, "scheduleStop": { "type": "string", "description": "每日定时停止时间 `HH:MM`(空 = 不定时停止)。" }, "speedLimitKbps": { "type": "integer", "format": "int64", "description": "队列限速(KB/s),0 = 不限速。" }, "uploadLimitKbps": { "type": "integer", "format": "int64", "description": "队列上传限速(KB/s),0 = 不限速。" } } }, "RenameTaskRequest": { "type": "object", "description": "重命名任务文件请求体。", "required": [ "fileName" ], "properties": { "fileName": { "type": "string", "description": "新文件名(不含路径分隔符;引擎侧校验非法字符与状态)。" } } }, "RequestBody": { "oneOf": [ { "type": "object", "required": [ "fields", "kind" ], "properties": { "fields": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } }, "propertyNames": { "type": "string" } }, "kind": { "type": "string", "enum": [ "formData" ] } } }, { "type": "object", "required": [ "raw", "kind" ], "properties": { "kind": { "type": "string", "enum": [ "urlencoded" ] }, "raw": { "type": "string" } } }, { "type": "object", "required": [ "bytesB64", "kind" ], "properties": { "bytesB64": { "type": "string" }, "contentType": { "type": [ "string", "null" ] }, "kind": { "type": "string", "enum": [ "raw" ] } } } ], "description": "浏览器原始请求体(form POST / XHR raw body 等)。\n\n当用户在 form-submit 触发的下载中点击下载按钮时,浏览器实际发起的是\nPOST 请求并携带表单数据;扩展通过 `webRequest.onBeforeRequest` 抓到 method\n与 body 后透传到此字段。宿主端按 `kind` 重建请求体。\n\n协议字段:\n- `formData`:来自 `requestBody.formData`,宿主用 `reqwest::form()` 编码为\n `application/x-www-form-urlencoded`\n- `urlencoded`:扩展端已序列化好的 url-encoded 字符串(直接作为 body 发送)\n- `raw`:base64 编码的二进制 body(XHR / fetch 直接发送 ArrayBuffer 的场景)" }, "ResolvePreviewRequest": { "type": "object", "description": "前置预解析请求(`POST /api/v1/resolve/preview`)。只读、不建任务、\n不写库;结果见 [`ResolvePreviewResponse`]。\n\n# Examples\n", "required": [ "url" ], "properties": { "cookies": { "type": "string" }, "extraHeaders": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "referrer": { "type": "string" }, "url": { "type": "string" }, "userAgent": { "type": "string" } } }, "ResolvePreviewResponse": { "type": "object", "description": "[`ResolvePreviewRequest`] 的结果。`items` 为空且 `error` 为空 = 插件未\n返回清单(客户端应回退普通单任务创建对话框);`error` 非空 = 预解析\n失败(同样回退,`error` 供 UI 提示)。", "required": [ "name", "sourceUrl" ], "properties": { "error": { "type": "string", "description": "无错误时为空。" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewItemDto" } }, "name": { "type": "string" }, "sourceUrl": { "type": "string" } } }, "ResultMessage": { "type": "object", "description": "通用结果响应(接管端点应答 / 各端点错误响应统一格式)。", "required": [ "success", "message" ], "properties": { "message": { "type": "string" }, "success": { "type": "boolean" } } }, "RssItemActionRequest": { "type": "object", "description": "对条目执行手动操作(`POST /api/v1/rss/{id}/items/action`)。\n\nguid 走请求体而不是路径段:真实 feed 的 guid 常常就是一整条 URL,\n塞进路径要双重编码,且被反向代理规范化后会静默改写。", "required": [ "action" ], "properties": { "action": { "type": "string", "description": "`download`(绕过规则强制下载)/ `ignore` / `readAll`(全部标记已读)。" }, "guid": { "type": "string", "description": "`action = \"readAll\"` 时忽略。" } } }, "RssItemDto": { "type": "object", "description": "订阅流中的一个条目(`GET /api/v1/rss/{id}/items`)。", "required": [ "sourceId", "guid", "title", "link", "enclosureUrl", "enclosureLength", "pubDate", "fetchedAt", "status", "taskId", "episodeKey", "reason" ], "properties": { "enclosureLength": { "type": "integer", "format": "int64", "description": "enclosure 声明大小(字节,0 = 未知)。" }, "enclosureUrl": { "type": "string", "description": "enclosure 直链(空 = 回退 `link`)。" }, "episodeKey": { "type": "string", "description": "智能剧集归一键(空 = 未识别)。" }, "fetchedAt": { "type": "integer", "format": "int64" }, "guid": { "type": "string", "description": "去重主键。" }, "link": { "type": "string" }, "pubDate": { "type": "integer", "format": "int64", "description": "发布时间(Unix 秒,0 = 未知)。" }, "reason": { "type": "string", "description": "稳定原因码(`excluded`/`too_large`/`dup_episode`/`seed_skipped`/…;\n空 = 无)。**客户端负责本地化**。" }, "sourceId": { "type": "string" }, "status": { "type": "integer", "format": "int32", "description": "0=新 1=已下载 2=已忽略 3=规则未命中 4=重复剧集 5=首轮历史条目。" }, "taskId": { "type": "string", "description": "`status == 1` 时回链的任务 ID。" }, "title": { "type": "string" } } }, "RssSourceDto": { "type": "object", "description": "一个 RSS 订阅(`GET/POST /api/v1/rss`、`PUT /api/v1/rss/{id}`)。\n\n写请求复用同一结构:全字段 `#[serde(default)]`,客户端只需给关心的字段;\n运行态字段(`lastFetchAt`/`lastError`/`failCount`/`seeded`/`unreadCount`)\n只读,写入时被引擎忽略。\n\n# Examples\n", "required": [ "url" ], "properties": { "autoDownload": { "type": "boolean", "description": "false = 收集模式(只收集条目供手动挑选)。" }, "cookies": { "type": "string" }, "enabled": { "type": "boolean" }, "excludePattern": { "type": "string" }, "failCount": { "type": "integer", "format": "int32", "description": "只读:连续失败次数(驱动指数退避)。" }, "includePattern": { "type": "string", "description": "包含关键词(`|` = 或,空格 = 且;空 = 不过滤)。" }, "intervalMinutes": { "type": "integer", "format": "int32", "description": "抓取间隔(分钟);0 = 引擎默认 30。" }, "lastError": { "type": "string", "description": "只读:上次失败原因(空 = 健康)。" }, "lastFetchAt": { "type": "integer", "format": "int64", "description": "只读:上次发起抓取的 Unix 秒(0 = 从未)。" }, "lastSuccessAt": { "type": "integer", "format": "int64", "description": "只读:上次成功抓取的 Unix 秒(0 = 从未)。" }, "maxPerFetch": { "type": "integer", "format": "int32", "description": "每轮最多新建任务数(1..=100);0 = 引擎默认 20。" }, "name": { "type": "string", "description": "空 = 用 feed 标题回填。" }, "notifyOnDownload": { "type": "boolean" }, "position": { "type": "integer", "format": "int32" }, "providerConfig": { "type": "string", "description": "provider 专属配置 JSON;缺省为空。" }, "providerId": { "type": "string", "description": "来源 provider 的稳定 ID;缺省为内置 RSS provider。" }, "proxyUrl": { "type": "string" }, "queueId": { "type": "string", "description": "空 = 内置主队列。" }, "saveDir": { "type": "string", "description": "空 = 队列目录 → 全局目录。" }, "seeded": { "type": "boolean", "description": "只读:首轮抓取是否已完成。" }, "sendReferer": { "type": "boolean" }, "sizeMaxBytes": { "type": "integer", "format": "int64", "description": "体积上限(字节,0 = 不限)。" }, "sizeMinBytes": { "type": "integer", "format": "int64", "description": "体积下限(字节,0 = 不限)。" }, "smartEpisode": { "type": "boolean" }, "sourceId": { "type": "string" }, "startPaused": { "type": "boolean", "description": "自动创建的任务以 paused 落库。" }, "unreadCount": { "type": "integer", "format": "int32", "description": "只读:未处理条目数(侧边栏 badge)。" }, "url": { "type": "string" }, "useRegex": { "type": "boolean" }, "userAgent": { "type": "string" } } }, "RssValidateRequest": { "type": "object", "description": "验证一个 feed 地址(`POST /api/v1/rss/validate`,只读、不落库)。", "required": [ "url" ], "properties": { "cookies": { "type": "string" }, "proxyUrl": { "type": "string" }, "url": { "type": "string" }, "userAgent": { "type": "string" } } }, "RssValidateResponse": { "type": "object", "description": "feed 验证结果。`error` 非空即验证失败(HTTP 状态仍是 200——这是一次\n**诊断**调用,失败原因本身就是有效载荷)。", "required": [ "url", "feedTitle", "items", "error" ], "properties": { "error": { "type": "string", "description": "无错误时为空。" }, "feedTitle": { "type": "string", "description": "feed 标题(供回填订阅名)。" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/RssItemDto" }, "description": "最近条目预览。" }, "url": { "type": "string" } } }, "SetPluginEnabledRequest": { "type": "object", "description": "设置插件启用状态请求体。", "required": [ "enabled" ], "properties": { "enabled": { "type": "boolean" } } }, "SettingFieldDto": { "type": "object", "description": "声明式设置项(镜像 `engine::plugin::SettingField`,api 本地定义)。", "required": [ "key", "title", "type", "widget" ], "properties": { "default": { "type": [ "string", "null" ] }, "description": { "type": "string" }, "helperLabel": { "type": [ "string", "null" ], "description": "辅助脚本按钮文案(空则用默认文案)。" }, "helperScript": { "type": [ "string", "null" ], "description": "辅助脚本(非空时 UI 在字段旁渲染复制按钮,仅复制文本、绝不执行)。" }, "key": { "type": "string" }, "max": { "type": [ "number", "null" ], "format": "double" }, "min": { "type": [ "number", "null" ], "format": "double" }, "options": { "type": "array", "items": { "$ref": "#/components/schemas/SettingOptionDto" } }, "pattern": { "type": [ "string", "null" ] }, "required": { "type": "boolean" }, "title": { "type": "string" }, "type": { "type": "string", "description": "`string` / `number` / `boolean`。" }, "widget": { "type": "string", "description": "`text`/`password`/`textarea`/`select`/`toggle`/`number`/`folder`。" } } }, "SettingOptionDto": { "type": "object", "description": "select 控件选项。", "required": [ "value", "label" ], "properties": { "label": { "type": "string" }, "value": { "type": "string" } } }, "SiteAuthCredentialDto": { "type": "object", "description": "单站点 HTTP Basic 凭据详情;仅由受保护的定向查询返回(`GET\n/api/v1/site-auth/{site}`,须管理 token;本机 RPC `daemon.siteAuth.match`)。\n`pass` 是明文密码,不脱敏——保留是为了表单可以回填原值;只应用于编辑对话框 /\n新建下载认证框这类需要原文的场景,不要在列表/日志里回显(L-1;列表接口\n[`SiteAuthEntryDto`] 本就不含 `pass`)。", "required": [ "site", "user", "pass" ], "properties": { "pass": { "type": "string" }, "site": { "type": "string" }, "user": { "type": "string" } } }, "SiteAuthEntryDto": { "type": "object", "description": "已保存的站点 HTTP Basic 凭据(`daemon.siteAuth.list`);不携带密码。", "required": [ "site", "user" ], "properties": { "site": { "type": "string", "description": "`host` 或 `host:port`。" }, "user": { "type": "string" } } }, "SiteAuthSaveRequest": { "type": "object", "description": "保存单站点 HTTP Basic 凭据的请求。", "required": [ "site", "user", "pass" ], "properties": { "pass": { "type": "string" }, "site": { "type": "string" }, "user": { "type": "string" } } }, "TaskDto": { "type": "object", "description": "任务信息(`GET /api/v1/tasks`、`GET /api/v1/tasks/{id}` 响应)。\n\n# Examples\n", "required": [ "taskId", "url", "fileName", "saveDir", "status", "downloadedBytes", "totalBytes", "errorMessage", "createdAt", "proxyUrl", "queueId", "checksum" ], "properties": { "autoRoute": { "type": "string", "description": "`ProxyMode::Auto` 的任务级最终链路(可追溯性):`direct` /\n`direct:sampled` / `direct:pinned` / `direct:failover` /\n`proxy:cached` / `proxy:sampled` / `proxy:failover`(代理类标签带\n候选来源后缀 `:system`/`:manual`);空 = 非 Auto 模式。" }, "checksum": { "type": "string", "description": "Checksum spec,格式 `algo=hexhash`(空 = 跳过校验)。" }, "completedAt": { "type": "string", "description": "任务结束时间,Unix 秒级时间戳(空 = 尚未完成)。\n记录下载真正完成(status→3)的时刻,不含插件 hook 后处理耗时。" }, "createdAt": { "type": "string", "description": "Unix 秒级时间戳(字符串)。" }, "downloadedBytes": { "type": "integer", "format": "int64" }, "errorMessage": { "type": "string" }, "fileMissing": { "type": "boolean", "description": "文件跟踪:completed 任务的目标文件是否已丢失(被删除/移动)。默认 false。" }, "fileName": { "type": "string" }, "groupId": { "type": "string", "description": "所属任务组 ID(空 = 不属于任何组)。" }, "ignoreTlsErrors": { "type": "boolean", "description": "是否显式忽略 HTTPS 证书错误。默认 false(严格验证)。" }, "originUrl": { "type": "string", "description": "展示用原始来源链接(空 = 用 `url`)。`.torrent` 任务的 `url` 是\n`torrent-file://local` 哨兵,客户端「复制链接」应优先取本字段。" }, "proxyUrl": { "type": "string", "description": "单任务代理 URL(空 = 使用全局代理)。" }, "queueId": { "type": "string", "description": "命名队列 ID(空 = 默认队列)。" }, "queueOrder": { "type": "integer", "format": "int32", "description": "队列内启动顺序(0 = 未显式排序,按创建时间;>0 = 显式顺序)。" }, "referrer": { "type": "string", "description": "Source page URL captured by the browser extension (empty = none)." }, "rssSourceId": { "type": "string", "description": "由哪条 RSS 订阅自动创建(空 = 非 RSS 来源)。P5 任务溯源。" }, "saveDir": { "type": "string" }, "seedInactiveTimeLimitMinutes": { "type": "integer", "format": "int64", "description": "任务级不活跃做种时长上限(分钟)。哨兵语义同上。" }, "seedPostRatioLimitMilli": { "type": "integer", "format": "int64", "description": "任务级做种后分享率上限(千分比)。哨兵语义同上。" }, "seedRatioLimitMilli": { "type": "integer", "format": "int64", "description": "任务级总分享率上限(千分比,1500 = 1.5)。哨兵:-2 = 跟随全局,\n-1 = 不限制,>=0 = 自定义(0 视同不限制)。" }, "seedTimeLimitMinutes": { "type": "integer", "format": "int64", "description": "任务级做种时长上限(分钟)。哨兵语义同上。" }, "seedUploadLimitBps": { "type": "integer", "format": "int64", "description": "任务级做种上传限速(字节/秒),0 = 未设置(跟随全局)。" }, "seedingMessage": { "type": "string", "description": "做种状态辅助说明(如停止原因,空 = 无)。" }, "seedingStatus": { "type": "integer", "format": "int32", "description": "BT 做种状态:0=无, 1=做种中, 2=达分享率, 3=达时长, 4=用户停止,\n5=任务删除, 6=会话释放, 7=不活跃停止, 8=排队等待做种槽。" }, "seedingTimeSecs": { "type": "integer", "format": "int64", "description": "累计做种秒数(活跃做种期间累加;排队/暂停不计,非 BT 任务恒 0)。" }, "sourceBytes": { "$ref": "#/components/schemas/TaskSourceBytesDto", "description": "加速来源累计字节(多 CDN / 智能代理 / 多网卡);源站 = 已下载 − 三者之和。" }, "status": { "type": "integer", "format": "int32", "description": "0=pending, 1=downloading, 2=paused, 3=completed, 4=error, 5=preparing" }, "taskId": { "type": "string" }, "totalBytes": { "type": "integer", "format": "int64" }, "uploadedAtCompletion": { "type": "integer", "format": "int64", "description": "下载完成时刻的已上传字节数(做种后分享率基准,非 BT 任务恒 0)。" }, "uploadedBytes": { "type": "integer", "format": "int64", "description": "BT 已上传字节数(做种累计,非 BT 任务恒 0)。" }, "url": { "type": "string" } } }, "TaskSourceBytesDto": { "type": "object", "description": "任务按加速来源累计的已写入字节:跨运行累加,重下 / 清盘时随进度一并复位。\n\n只记录源站主链路之外的路径;源站字节 = `downloaded_bytes` − 三者之和\n(BT / ED2K 等 P2P 协议由客户端按协议整体归入 P2P)。", "properties": { "cdnBytes": { "type": "integer", "format": "int64", "description": "多 CDN 钉定节点(DoH / ECS 解析出的额外源站 IP)。" }, "nicBytes": { "type": "integer", "format": "int64", "description": "多网卡聚合挂入的额外网卡链路。" }, "proxyBytes": { "type": "integer", "format": "int64", "description": "`ProxyMode::Auto` 下经候选代理路径(系统代理或手动代理)。" } } } }, "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" }, "tokenHeader": { "type": "apiKey", "in": "header", "name": "X-FluxDown-Token" } } }, "tags": [ { "name": "system", "description": "探活与基础信息" }, { "name": "takeover", "description": "浏览器脚本接管(Tampermonkey / Violentmonkey)" }, { "name": "aria2", "description": "aria2 JSON-RPC 兼容" }, { "name": "mcp", "description": "MCP(Model Context Protocol)—— AI 客户端工具调用" }, { "name": "management", "description": "管理 API(强制 token)" }, { "name": "groups", "description": "任务组与前置预解析(多文件任务组;强制 token)" }, { "name": "plugins", "description": "插件系统(安装/启停/设置/卸载;强制 token)" }, { "name": "rss", "description": "RSS 订阅自动下载(订阅 CRUD / 条目流 / 手动操作 / feed 验证;强制 token)" }, { "name": "link", "description": "设备互联(配对/发现/数据面下发;`pair/hello`·`pair/reveal`·`pair/confirm`·`link/tasks` 无 token,由一次性码/会话/链路 HMAC 守卫,其余强制 management token)" } ] }