管理接口速查¶
SPA 页面和资源(v1.31.88 起)¶
部署必须同时包含 SPA 入口和对应资源。匿名及首次改密会话均可读取已有
/ui/assets/* JS/CSS:GET/HEAD 返回 200、正确资源 MIME,缓存为
public, max-age=31536000, immutable。/ui/dashboard、/ui/admin/password
等页面入口返回 HTML 并禁止缓存。匿名请求缺失资源返回禁止缓存的 404,不能用 HTML
兜底冒充资源成功。首次改密会话的缺失资源 HEAD 仍遵循原安全限制。
业务接口继续要求认证及完成首次改密。验收、失败排查及回滚见
后台认证安全。
后台认证加固(v1.31.87 起)¶
GET /api/panel/auth/csrf 返回 { "token": "..." } 并设置防伪 Cookie,响应禁止缓存。
客户端必须保留 Cookie,在 POST /api/panel/auth/login、POST /api/panel/settings/password、
POST /api/panel/settings/username 携带 X-TelegramPanel-CSRF 请求头。
登录成功或用户名变化后必须重新获取当前身份令牌,不要自动重放失败的写请求。
服务端 /login 表单内置隐藏防伪字段,不接受缺失或错误令牌的提交。
400 INVALID_CSRF_TOKEN:刷新页面或重新读取令牌后,由用户重新提交。429 LOGIN_RATE_LIMITED:按Retry-After秒数等待,表单与 JSON 两入口共享额度。403 PASSWORD_CHANGE_REQUIRED:先访问/ui/admin/password修改初始密码。
首次设置期间后台业务 API、后台模块和旧 Blazor 通道被拦截;健康检查和独立鉴权的外部 API/Webhook 保留各自合同。 仅改用户名仍保持必须改密,改密码会撤销其他会话。新密码至少 12 位且与旧密码不同。 此合同面向后台 Cookie 登录,外部 API Key 不通过上述后台登录入口。
Vue 后台使用 /api/panel 下的管理接口。开启后台登录时,除登录等少数端点外都需要
管理员 Cookie;这些接口不是面向公网的稳定开放 API。完整行为以
PanelAdminApiEndpoints.cs 和各功能 Endpoint 文件为准。
模块仓库与批量版本清理¶
从包含外置改动的宿主 1.31.77 起,POST /api/kick 由公开的 demo.kick-api 模块提供,
未安装并启用时没有该端点。仍使用 X-API-Key 和原 ExternalApi:Apis 中 Type=kick 配置;
ExternalApi:Enabled=false 时返回 404。成功提交返回 202,执行由后台任务完成。
管理页面为 /ext/demo.kick-api/kick,模块管理 API 保持 /api/panel/extensions/kick-api。
迁移、权限、测试与回滚见在线模块仓库维护。
适用:包含在线仓库功能的版本;所有接口沿用管理员鉴权。前置条件、目录合同、故障排查和回滚见 在线模块仓库维护。
GET /api/panel/module-repositories:仓库列表,只返回hasToken,不返回令牌。- 页面上的官方仓库、Fork 和维护说明入口为外部链接,不调用仓库写入接口;Fork 完成后仍须手动添加仓库配置。
POST /api/panel/module-repositories:新增;请求name/kind/location/ref/token/clearToken。kind为github(location=owner/repo)或https(完整 index.json 地址);ref默认main。PUT /api/panel/module-repositories/{id}:更新;令牌留空保留,clearToken=true清除,改变目标清除旧令牌。DELETE /api/panel/module-repositories/{id}:删除来源和令牌,不卸载已安装模块。GET /api/panel/module-repositories/{id}/index:连接并校验目录,返回schemaVersion/modules。POST /api/panel/module-repositories/{id}/install:请求moduleId/version/sha256/activateAndEnable/autoRestart; 服务器重新取目录并下载校验,返回success/message/moduleId/version。安装成功但启用失败会明确写入message。GET /api/panel/modules/prune-preview:返回[{id,versions,keptVersions}]。POST /api/panel/modules/prune-all:请求{autoRestart};返回success/removedVersions/results,results每项含id/version/success/message。部分失败用success=false表示,HTTP 200 不代表全部成功。
清理永久删除旧包及旧安装目录,保护当前/最后可用/运行版本。成功判据是逐项结果和刷新后的版本清单; 空清理不重启,部分成功最多一次重启。仓库验证失败返回不含凭据的错误信息。
登录与账号¶
POST /api/panel/auth/login:后台登录GET /api/panel/auth/me:当前后台登录状态POST /api/panel/settings/username:修改后台用户名GET /api/panel/accounts:账号列表GET /api/panel/accounts/{id}:账号详情POST /api/panel/accounts/import/zip:导入 Telethon 或 TData 压缩包POST /api/panel/accounts/import/session-files:导入 Session 文件POST /api/panel/accounts/import/string-session:导入 StringSessionPOST /api/panel/accounts/login/start:开始手机号登录POST /api/panel/accounts/login/qr/start:开始二维码登录POST /api/panel/accounts/login/code:提交手机号验证码POST /api/panel/accounts/login/password:提交 2FA 密码DELETE /api/panel/accounts/{id}:删除账号POST /api/panel/accounts/{id}/telegram-status:刷新单个账号 Telegram 状态POST /api/panel/accounts/telegram-status:批量刷新账号 Telegram 状态POST /api/panel/accounts/cleanup-waste:复查并清理明确失效的账号POST /api/panel/accounts/batch/category:由账号列表页发起的批量修改账号分类操作;categoryId=null表示改为未分类,只影响请求里的accountIds,不会覆盖分类的全部成员。自 v1.31.78 起,账号分类页只维护分类并显示账号数量,不再提供此操作入口;接口、鉴权和数据合同保持不变。POST /api/panel/accounts/batch/recovery-email:批量换绑 2FA 找回邮箱,可选同时换绑登录邮箱。单个账号可能等待 Telegram 发信和 Cloud Mail 收码;前端会按账号逐个调用该接口并聚合结果,外部自动化调用大量账号时也应拆成单账号或小批次请求,避免长连接被浏览器、Nginx 或网关超时中断。GET /api/panel/accounts/{id}/login-email:查询 Telegram 当前登录邮箱状态,结合本地已确认记录返回邮箱展示与核验结果,字段和失败语义见下文。POST /api/panel/accounts/{id}/login-email:请求{email},向目标地址发送验证码;发送成功仅保存待确认地址,不改写已确认的当前邮箱。POST /api/panel/accounts/{id}/login-email/confirm:请求{code};Telegram 确认成功后保存完整邮箱与官方掩码,结束待确认状态。GET /api/panel/accounts/{id}/devices:读取账号在线设备;返回的hash始终是十进制字符串,避免 JavaScript 处理 Telegram 64 位授权哈希时丢失精度。POST /api/panel/accounts/{id}/devices/{hash}/kick:踢出指定非当前设备;hash使用上述字符串原样放入 URL。POST /api/panel/accounts/{id}/devices/kick-all:踢出所有其他设备并保留当前授权。
图片上传格式限制¶
自 v1.31.79 起,任务头像 POST /api/panel/tasks/assets/avatar 和图片字典上传使用
宿主图片处理器时按文件内容拒绝 TIFF/BigTIFF,改名为 .jpg 或声明 image/jpeg 也不会放行。
接口返回 HTTP 400、success=false 与中文转换提示,不持久化该图片文件。
管理员鉴权和原 multipart 字段不变;JPEG、PNG、WebP 继续转换为 JPEG 保存,并保留原方向纠正。
其他头像和 Telegram 图片预览调用同一处理器,其已有错误响应结构不变。
成功判据为 TIFF 返回明确错误、PNG 等正常图片仍可保存;失败时核对真实编码和部署版本, 不要通过修改文件扩展名重试。无需迁移;回滚应用会恢复 TIFF 解码,同时重新暴露对应风险。 这是格式级缓解,不表示依赖的全部安全风险已解决。
手机号登录的人机验证失败¶
适用于 v1.31.79 及后续版本,前置条件是管理员鉴权、有效 Telegram API 配置及显式登录代理选择。
POST /api/panel/accounts/login/start 收到 Telegram 的 RECAPTCHA_CHECK_* 时,沿用登录失败合同:
HTTP 400,success=false、nextStep=null、account=null,message 返回中文人机验证说明。
客户端不得把此响应当作验证码已发送或可继续输入验证码,也不得自动循环重发。
响应与登录相关宿主日志不包含原始挑战串;临时客户端和登录代理资源继续走既有失败清理流程。 接口没有新增挑战提交字段或自动解题能力。用户需在官方 Telegram 客户端中按提示正常完成验证; 最终登录是否放行由 Telegram 决定。验收和问题排查见常见问题。 此改动不改变 DTO、数据库或配置;回滚应用仅恢复旧错误提示与日志行为。
登录邮箱持久化与核验¶
适用版本:v1.31.78 及后续版本,需要管理员鉴权与数据库迁移
20261009000000_AddAccountLoginEmails(新增 AccountLoginEmails 表)。
GET /api/panel/accounts/{id}/login-email 保留 success/error/hasLoginEmail/loginEmailPattern,
新增可为空的 loginEmail 和 verificationStatus:
verified:本地有经验证码确认的完整地址,本次官方掩码核验一致,可以展示loginEmail。unverified:存在完整地址,但本次官方查询失败、官方掩码为空或缺少确认时的核验基线;必须同时展示未核验状态,查询失败时接口通过error返回原因。unavailable:没有可供展示的本地完整地址,使用当前官方掩码或无邮箱状态;若success=false,只能显示查询失败,不能推断无邮箱。
loginEmailPattern 始终表示 Telegram 返回的官方邮箱掩码;星号不能用于还原完整邮箱。
完整地址来自本面板曾经完成验证码确认并持久化的记录,不能把待确认目标地址当作当前邮箱。
详情查询以官方状态核验本地记录:掩码一致时显示本地完整地址;只有掩码明显不匹配或官方明确
无邮箱时,旧记录才失效,分别回退官方掩码或无邮箱状态。查询失败与无邮箱不同:历史完整地址保留但标记为
未核验,客户端不得根据历史值宣称当前云端状态已确认。旧账号没有完整地址记录时,只能显示官方掩码。
确认成功但首次 GetPassword 失败或没有有效掩码时,完整地址仍会保存,状态为 unverified;
后续查询不得凭新掩码自动补建确认时的基线。官方表示有邮箱但掩码为空时同样保留地址并返回未核验。
掩码一致性检查不能区分恰好使用相同掩码的不同邮箱,不等于重新获取了完整云端地址。
手动、批量和 auto_change_login_email 计划任务通过 Core 共享更换与确认流程写入同一份记录。
验收时检查发送、确认、再次查询及重启后的展示,并覆盖掩码不一致、无邮箱、查询失败和旧账号无缓存。 失败先检查数据库迁移、Session、出口与验证码确认结果;回滚前备份数据库,旧程序会忽略新增记录, 不得手动删除新增表或迁移历史。完整约束见账号详情密码与登录邮箱合同。
账号加群、订阅和 Bot 后台任务¶
自 v1.31.79 起,管理员通过
POST /api/panel/accounts/chat-membership/tasks 提交账号列表中的后台操作。
请求包含 accountIds(数据库主键数组)、operation(join 或 leave)、
links(目标数组)、可选 treatNoBotSuffixAsBot 和 delayMs。
服务端过滤非正账号编号并去重,目标按换行、空格和英文逗号拆分后忽略大小写去重;
操作间隔默认 2000 毫秒,限制为 0~60000 毫秒。无账号、无目标或操作类型无效返回 400,
不会写入任务。成功返回普通 BatchTaskDto,其 taskType=user_join_subscribe、
ownerModuleId=builtin.tasks、executionKind=batch、status=pending,
total 为规范化后的账号数乘目标数;执行结果在任务中心查看。
该接口沿用面板管理员鉴权,不接受调用方指定所有者、任务类型或运行态。
账号页面仍先执行风控检查和用户确认;POST /api/panel/tasks 保持标准创建目录限制,
不会因该专用入口而开放 user_join_subscribe。若仍提示“未开放标准创建入口”,
检查浏览器是否加载旧版前端以及请求是否仍指向 /tasks。无需数据库迁移;
回滚时前后端一起恢复旧版,已创建任务配置仍可读取,但旧版入口会恢复原错误。
账号编号¶
自 v1.31.57 起,账号列表、账号详情、任务账号候选和风控确认中的账号 DTO 都返回
displayNumber。这是面向用户展示和手工填写任务账号范围的账号编号;id 仍是内部数据库
主键,只用于接口路径、权限校验和持久化关联。删除账号后,新账号可以复用空出的
displayNumber,因此外部系统不得把它当作长期不可变主键。成功判据是
GET /api/panel/accounts 与 GET /api/panel/accounts/{id} 同时返回正整数
displayNumber,前端任务表单在“账号来源”切到“账号编号填写”后可用 #编号 选择账号;该前端入口与“账号分类选择”二选一,不再把编号和分类合并执行。手工输入支持每行一个,也支持英文逗号 ,、中文逗号 ,、顿号 、 或分号分隔。回滚到旧版前无需清理数据,但旧前端不会展示该字段。
前端会为登录和导入请求明确携带 proxyStrategy;自定义调用也必须显式传入。省略策略、
策略无效或所选代理不可用时,服务端会在连接 Telegram 前拒绝请求,不会回退直连。不要
绕过这些入口自行先直连创建 Session。
Telegram API 配置池设置¶
GET /api/panel/settings 的 telegram 字段包含兼容旧版的已写入 apiId、apiHash,以及 officialApiEnabled 和可选 profiles 数组;还会返回运行态字段 effectiveApiId、effectiveApiSource、effectiveApiName、officialApiId、officialApiName 和 hasUsableApi。POST /api/panel/settings/telegram-api 由系统设置页调用,并写入 appsettings.local.json:
{
"apiId": "",
"apiHash": "",
"officialApiEnabled": true,
"profiles": [
{ "name": "api-a", "apiId": "123456", "apiHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "enabled": true, "weight": 1, "notes": "备用配置" },
{ "name": "api-b", "apiId": "234567", "apiHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "enabled": true, "weight": 1 }
]
}
profiles 省略时保留当前 API 配置池;传空数组表示清空配置池。系统设置不再提供单独“默认 API”选择,启用中的内置官方 API 固定排在池子最顶上,保存时旧版 apiId/apiHash 会被前端带入配置池并清空旧字段。服务端会校验每个 ApiHash 为 32 位十六进制字符串,名称不可重复,weight 规范到 1-1000。新账号登录和不自带 API 的导入入口按启用池子顺序轮询;权重大于 1 时该配置会在轮询序列中出现对应次数。已有账号继续使用数据库中保存的 ApiId/ApiHash。
Telegram API 与设备画像¶
系统设置页管理 Telegram API 池;侧栏 /device-profiles 只管理内置/自定义设备画像和默认画像,不展示 Telegram API 状态。两者最终都通过 POST /api/panel/settings/telegram-api 保存,设备画像请求沿用现有 deviceProfiles 与 defaultDeviceProfileKey 字段。
GET /api/panel/settings 返回有效 Telegram API、API 池、启用画像和默认画像 key;GET /api/panel/settings/device-profiles 返回同一画像目录的 { items, defaultKey }。defaultDeviceProfileKey/defaultKey 可以是保留值 random,表示按账号或会话稳定随机选取适合当前 API 的内置画像;random 不属于 items 画像目录,前端必须作为下拉首项单独展示。
PUT /api/panel/accounts/{id} 的请求可携带 deviceProfileKey:传画像 key 表示绑定该账号,传 random 表示该账号后续按稳定随机画像连接,传空字符串表示清除绑定并跟随系统默认。GET /api/panel/accounts/{id} 返回 deviceProfileKey。POST /api/panel/accounts/import/zip、POST /api/panel/accounts/import/session-files 的 multipart 字段名为 deviceProfileKey;StringSession JSON 请求同名字段。POST /api/panel/accounts/login/start 与 POST /api/panel/accounts/login/qr/start 也接受 deviceProfileKey,在发送验证码或生成二维码前应用该画像,并在登录成功后保存到账号。未知或停用 key 返回 400 或业务失败响应,不会修改账号。
成功判据是保存后重新读取账号详情仍返回该 key,清空后返回 null;画像只影响客户端设备字段,不改变 API 凭据、代理策略或 Session 文件格式。数据库列由 20260818090000_AddAccountDeviceProfileKey 迁移创建。
POST /api/panel/settings/username 的以下合同适用于 v1.31.42 及以上版本。调用方必须
已经通过管理员 Cookie 认证,请求 JSON 必须提供 currentPassword 和 newUsername。
新用户名要求 4-32 位,只包含字母、数字、下划线、短横线或点,且不能使用 admin、
administrator 或 root。成功时返回 200、success=true,当前登录 Cookie 会切换到
新用户名;输入不合法时返回 400 和可直接展示的 message,不会修改凭据文件。
若修改失败,先按 message 检查当前密码、长度、字符范围和保留名称,再修正后重试。
需要回滚时用相同接口提交原用户名,并以当前密码完成确认;成功判据是重新读取
GET /api/panel/auth/me 时返回原用户名。凭据文件损坏或无法写入时应先停止修改并检查
持久化目录权限,不要直接删除 /data/admin_auth.json。
在线设备动态代理恢复(v1.31.43 及以上)¶
GET /api/panel/accounts/{id}/devices 要求管理员已登录,且账号 Session 有效、账号当前选择的
直连/全局/已有代理路由可用。读取在线设备遇到超时、连接关闭或动态代理出口失效等瞬时故障时,
服务端会清理该账号的缓存客户端,重新解析当前代理并重试一次;不会为账号创建独立 WARP 容器。
Telegram 的限流、权限和 Session 等业务错误不会重试,避免扩大限流。
成功时返回 200 和设备数组;数组中的 hash 是十进制字符串,lastActiveAtUtc 是 Telegram 返回的服务端时间,刷新页面会重新请求 Telegram,但该字段的更新粒度由 Telegram 决定。设备踢出接口返回 success=false 时,前端必须展示失败原因,不得把 HTTP 200 当作业务成功。
设备踢出成功后,页面先移除已确认的设备,再延迟刷新一次设备列表,以覆盖 Telegram 授权列表的短暂传播延迟。
自动恢复后仍失败时返回 502,响应包含可直接展示的中文 message 和 code=TELEGRAM_DEVICE_QUERY_FAILED。此时先在代理管理中检测账号当前出口,再检查 Session 是否仍有效;不需要通过“切换代理再应用”手工清理客户端。
成功判据是代理出口短暂变化后再次打开“在线设备”仍返回 200,日志至多记录一次客户端重建。
在线设备响应会同时返回 apiFamily、apiDisplayName、apiDescription 和 deviceDisplayName,前端不得只根据 ApiId 自行猜测未知状态。ApiId=2040 是官方 Telegram Desktop API,属于正常官方桌面端会话;异常排查应结合 appName/platform/deviceModel/ip 和最近活跃时间判断。
如需回滚,恢复到 v1.31.65;本改动不包含数据库迁移,设备哈希响应从数字改为字符串,调用方需按字符串传回踢出接口。
账号状态恢复与安全清理(v1.31.46 及以上)¶
状态刷新端点遇到动态代理连接关闭、IO 错误、请求超时或非调用方触发的取消时,会清理账号缓存
客户端、重新解析当前代理并重试一次。调用方主动取消以及 Telegram RPC、权限、限流和 Session
错误不会重试。单账号端点仍返回 TelegramStatusDto,批量端点仍逐项返回结果,响应结构不变。
POST /api/panel/accounts/cleanup-waste 会在删除前重新检测账号,但只删除明确封禁、注销、受限、
冻结、需要两步验证密码或 Session 永久失效的账号。连接失败、请求超时、刷新失败、
创建频道探测失败和无法获取账号资料不会删除,
也不会被 GET /api/panel/accounts?onlyWaste=true 返回。成功判据是临时故障账号得到“跳过”结果且
数据库记录与 Session 文件均保留。持续连接失败时先检查代理出口;回滚到 v1.31.45 无需迁移数据。
Zip 逐账号批量代理¶
POST /api/panel/accounts/import/zip 使用 multipart/form-data。普通导入支持
proxyStrategy=direct|global|existing|warp_pool|warp_per_account;existing 还必须提供
proxyId。
v1.31.82 起,warp_pool 只自动分配带 managedWgcfProfile 的空闲轻量出口:必须已启用、
ready、监听正常、检测成功,且没有账号或全局引用。每个出口仅分配给一个账号,并在首次
连接期间持有独占租约;旧 kind=warp 记录不是候选。该策略无需 proxyId,不会创建新出口,
没有候选或候选被占用时在连接 Telegram 前失败,不回退直连。
warp_per_account 从 v1.31.81 起在每个账号首次 Telegram 验证前创建一个轻量 WARP,并在账号成功入库后把
新 ProxyId 绑定到账号。Zip 和 Session 文件导入单次最多 10 个账号,StringSession 固定 1 个;
请求必须明确提交 acceptWarpTerms=true,可提供本次操作 UUID warpRequestId。超过上限、
运行器不可用或出口检测失败时,请求会在首次 Telegram 连接前失败。导入未成功绑定账号的
新出口会停止,代理记录和注册材料保留用于核对;不会删除上游注册或降级直连。
Zip 专属的一对一代理模式使用以下字段:
file: accounts.zip
proxyStrategy: proxy_per_account
proxyText: http://user-a:password-a@proxy-a.example.com:8080
socks5://user-b:password-b@proxy-b.example.com:1080
proxy_per_account只允许用于/accounts/import/zip,Session 文件、StringSession、 手机号登录和二维码登录不接受该策略。proxyText每个有效行仅支持一个 HTTP 或 SOCKS5 地址;空行和以#开头的注释行 不计数,重复行不去重并继续占用独立槽位。- 单次最多匹配 100 个账号,
proxyText最长 100000 个字符。 - Telethon 候选按规范化的 Zip 相对
.json路径稳定排序;纯 TData 候选按规范化的tdata相对目录路径稳定排序。路径分隔符统一为/,第 N 个候选固定使用第 N 个 有效代理行。 - 账号候选数必须与有效代理行数完全一致。服务端会先解析全部代理并检测全部出口,全部 成功后才在一个持久化阶段新增或复用代理记录,再冻结连接参数并开始第一个 Telegram 请求。
- 任一格式、数量、凭据冲突或出口检测预检失败会返回
400;该请求新增代理数为 0、 Telegram 连接数为 0,并且不会尝试面板直连。 - 全部代理持久化后,每个账号仍独立导入。某个账号的 Session 或 TData 后续失败时,其 已持久化代理不会回滚;没有其他账号使用时会留在代理列表中并显示为未使用。
逐账号代理结果在通用导入响应的 results 项中增加以下审计字段:
{
"success": true,
"phone": "8613111111111",
"sourceKey": "8613111111111/8613111111111.json",
"proxyLine": 1,
"proxyId": 17,
"proxyName": "http://proxy-a.example.com:8080",
"proxyEgressIp": "203.0.113.10"
}
sourceKey 是 Zip 内的规范化相对路径,proxyLine 是 proxyText 中从 1 开始计算的
原始物理行号。proxyName 不含认证信息;响应和错误不会返回 proxyText 原文、代理
用户名、密码或 Secret。
代理与出口¶
GET /api/panel/network/egress:检测面板服务自身出口GET /api/panel/settings/global-proxy:读取账号全局代理配置;密码与 Secret 仅返回是否已设置POST /api/panel/settings/global-proxy:启用、修改或关闭账号全局代理并清理客户端缓存GET /api/panel/proxies:代理列表GET /api/panel/proxies?usage=used|unused&categoryId={id}:按使用状态或分类筛选代理GET /api/panel/proxies/{id}/accounts?page=1&pageSize=50:分页查看该代理的专属绑定账号GET/POST/PUT/DELETE /api/panel/proxy-categories[/{id}]:查询和管理代理分类POST /api/panel/proxies/batch/category:批量设置代理分类POST /api/panel/proxies/batch/delete:逐项删除所选代理并返回成功、失败数及每项原因POST /api/panel/proxies:新增普通代理或 ResinPUT /api/panel/proxies/{id}:修改代理POST /api/panel/proxies/{id}/test:检测代理出口POST /api/panel/proxies/warp:v1.31.81 起创建轻量 WARP,固定 SOCKS5;返回 202 档案状态POST /api/panel/accounts/{id}/proxy:切换单个账号路由POST /api/panel/accounts/batch/proxy:批量切换账号路由GET /api/panel/accounts/{id}/proxy/egress:检测账号实际出口
POST /api/panel/accounts/batch/proxy 支持 strategy=direct|global|existing|warp_per_account|proxy_per_account。proxy_per_account 仅用于批量切换已存在账号代理,必须提供 proxyText,每个有效行一个 HTTP 或 SOCKS5 代理,空行和 # 注释不计数,数量必须与 accountIds 去重后的数量完全一致。服务端会先解析并检测全部代理出口,全部成功后新增或复用代理记录,再按 accountIds 顺序逐账号绑定;任一格式、数量、凭据冲突或出口检测失败会返回 400,不会修改账号路由。失败排查先看响应 items[].error 或全局错误;回滚方式是重新用原代理、全局代理或直连策略批量切换账号。
POST /api/panel/settings/global-proxy 使用 sourceMode=manual|existing。existing 模式
必须提供 proxyId,服务端只保存引用并在运行时解析代理;不会把 WARP 或 Resin 的连接
凭据复制到全局配置。
v1.31.82 起,GET /api/panel/proxies/{id}/accounts 在面板认证后可用,仅查询
ProxyId == id 的专属绑定账号,不包含仅继承全局代理的账号。返回
{ items, total, page, pageSize },按账号内部 id 升序分页;page 默认 1、最小 1,
pageSize 默认 50、限制在 1~200,超出范围会被钳制。超出最后一页返回空 items,
但 total 保留当前总数。代理不存在返回 404 和中文 message。
每项仅包含 id、displayNumber、remark、nickname、phoneLastFour、proxyId、
useGlobalProxy;手机号不足四位时 phoneLastFour 为空,不返回完整手机号、Session、
API Hash 或二级密码。此端点只读,不触发账号连接或改变路由。
代理页的解绑、全局代理切换和换绑复用 POST /api/panel/accounts/{id}/proxy,分别使用
strategy=direct|global|existing,并提交列表快照中的 expectedProxyId 和
expectedUseGlobalProxy;换绑指定代理时同时传入目标 proxyId,必须一次提交完成,
不能先解绑再绑定。返回 409 时说明绑定已变化,应刷新列表后重新选择,不能覆盖新绑定。
验收以专属账号正确分页、敏感字段未返回、解绑后刷新列表移除该账号为准;若列表与页面
使用数不同,先区分全局继承人数与专属绑定人数。回滚旧版本会移除该查看端点和快捷操作,
已完成的路由切换需重新绑定原代理恢复。
v1.31.82 已撤除旧 GET /proxies/warp/status、POST /proxies/{id}/warp/refresh 与
POST /proxies/warp/refresh-all,旧客户端必须改用下文轻量档案 API。历史 kind=warp
记录不再允许用于新绑定或实际账号/全局路由;残留引用在连接前失败,不降级直连。
v1.31.83 起,内置轻量出口允许显式已有代理绑定、批量绑定和全局代理共享;登录及导入的
existing、global 同样支持。出口需已就绪且无未完成首连占用,提交时服务端重新核验;
warp_pool 的空闲独占规则保持不变。
频道、群组和 Bot¶
GET /api/panel/channels/GET /api/panel/groups:列表和筛选GET /api/panel/channels/{id}/GET /api/panel/groups/{id}:详情POST /api/panel/channels/POST /api/panel/groups:创建POST /api/panel/groups/{id}/admins/{userId}/kick:从群组详情移除非创建者管理员并踢出成员GET /api/panel/bots:Bot 列表GET /api/panel/bot-channels:Bot 频道列表
批量邀请、管理员变更、退出和解散等端点可在对应 Vue API 调用或 Endpoint 文件中查看。
自当前开发版起,群组详情的管理员表可对非创建者执行
POST /api/panel/groups/{id}/admins/{userId}/kick。端点不接受用户名、访问哈希或永久封禁
参数;服务端会重新读取 Telegram 的实时管理员列表并自动选择群组创建者或本系统管理员执行,
因此不会把管理员的 access_hash 返回给浏览器。目标是创建者、执行账号本人、已不再是管理员,
或执行账号缺少“添加管理员”和“封禁用户”权限时,接口返回 400 和可展示的中文 message。
成功时返回 200、success=true,操作固定为先撤销管理员权限、再施加短时限制以完成非永久
踢出。若 Telegram 在撤销后拒绝踢出,接口返回 409、success=false,message 会明确说明
“已撤销管理员权限,但尚未踢出成员”;调用方必须刷新管理员列表,不能把该结果重试为完整操作。
前置条件是群组和执行账号已同步且 Session 有效。排障依次检查管理员权限、目标是否已变化、
Telegram 限流和 Session/代理状态。该功能不引入数据库迁移,但会同步匹配到的本系统账号群组关联:
目标已离群时删除关联,仅完成降权时保留成员关联并清除创建者、管理员标记;不会为外部管理员新建
账号记录。回滚到旧版本只会移除行内入口和专用端点,不会恢复已撤销的管理员权限、已踢出的成员或
已同步的关联状态。
POST /api/panel/accounts/batch/profile 的 mode=bio 支持与昵称/用户名相同的文本模板:{time} 和已启用文本字典变量会在每个账号执行前解析。模板和字典文本中的字面 \\n 或 /n 会转为真实换行;留空仍表示清空 Bio。成功判据是 Bio 在 Telegram 资料中按换行展示,模板变量解析失败时单项返回失败原因;回滚到旧版前应把 Bio 改回固定文本或提前写入真实换行。
任务和模块¶
GET /api/panel/tasks:任务列表GET /api/panel/tasks/{id}:任务详情,包含完整configPOST /api/panel/tasks:创建任务POST /api/panel/tasks/{id}/pause:暂停POST /api/panel/tasks/{id}/resume:恢复POST /api/panel/tasks/{id}/cancel:取消POST /api/panel/tasks/{id}/rerun:由服务端重跑构建器创建新任务,原任务不变DELETE /api/panel/tasks/{id}:删除GET /api/panel/modules:模块列表POST /api/panel/modules/install:安装模块包/api/panel/extensions/{module-slug}:模块自定义后台管理接口约定GET /api/panel/extensions/fragment-username-checker:Fragment 用户名监控静态页面初始化数据;可带taskId读取可编辑任务配置。POST /api/panel/extensions/fragment-username-checker/tasks:创建或保存 Fragment 用户名监控任务;请求包含usernames、targetGroupIds、checkIntervalSeconds、queryDelayMs、durationHours,编辑时额外传taskId。
私信任务原生表单(宿主 v1.31.76)¶
任务中心的 direct_message.live 和 direct_message.batch 使用宿主原生表单,
主流程不加载模块 iframe;字段、默认值、边界和普通复制/编辑行为见
模块任务配置合同。
调用方必须先完成后台登录,并确保提供任务定义的私信模块已安装、启用且返回
canCreate=true。选项接口或账号群组接口失败时表单标记 canSubmit=false,保存请求不会发出。
当前宿主不支持私信类型的 Cron 创建、计划编辑、计划复制或立即执行;任务中心会禁用这些 入口。需要调整已有计划时先停用计划,再使用普通任务编辑。
GET /api/panel/extensions/direct-messaging/options:返回私信表单的账号分类、可用发送账号和 文本/图片字典选项。账号保留id、telegramUserId、label、categoryId,并提供displayNumber、nickname、username、displayPhone、categoryName、isActive;只返回isActive=true,不按TelegramStatusOk过滤。批量界面将文本词典显示为“用户名词典”。GET /api/panel/extensions/direct-messaging/accounts/{id}/groups:按监听账号读取可选群组;切换账号后应重新请求,失败时不得提交旧列表。POST /api/panel/extensions/direct-messaging/assets:上传图片,使用multipart/form-data的file字段;成功响应至少包含assetId和fileName,表单将assetId写入content.messageRules对应规则。
提交配置时 senderCategory 必须是分类名称字符串,不能是分类 ID 或数字字符串;宿主会将
下拉框内部 ID 映射为名称,无法映射时禁止提交。批量配置使用 manualUsernames 和
dictionaryKey,内容字段使用 content.action、messageRules、forward、todo,图片规则写入
imageAssetId。模块生命周期解析或字段校验失败统一返回 4xx,并包含字段名和“配置校验失败”。
私信原生表单的“不去重”开关不增加接口字段:开启时仍按现有合同提交 dedupeDays=0,并原样保留
dedupeScope;读取到 dedupeDays=0 时开关自动开启。关闭后恢复最后一次正数去重天数,未记录时为
3;cooldownSeconds 和 rolling24h 继续生效。
去重判断和历史账本均由 pro.direct-messaging 模块执行,宿主前端只负责承载配置并提交任务。
新建任务默认 dedupeScope=Task(仅当前任务去重);需要跨任务共享去重窗口时显式选择
dedupeScope=Global。已有任务的配置保持原值。
模块 1.0.2 执行时会按目标隔离失败:账号与目标/来源组合失败会自动换发送账号,全部组合失败或
目标永久无效时只终结当前目标并继续;uncertain 不会自动换号重发当前目标,但不会阻断同轮其他
目标。批量任务仅在普通目标处理完后进入人工裁决,整个发送池永久不可用时才暂停整项任务。
未安装或停用模块时,任务定义不会显示创建入口;先安装兼容版本并确认
canCreate=true。接口持续失败时检查管理员 Cookie、模块日志和响应错误,必要时停用
私信任务定义并回滚到上一稳定宿主版本(LastGoodVersion);已有任务应先暂停,避免
在不完整配置下运行。
fragment_username_monitor可直接通过POST /api/panel/tasks或PATCH /api/panel/tasks/{id}保存配置,前端表单写入的配置键为Usernames、TargetGroupIds、CheckIntervalSeconds、QueryDelayMs、DurationHours;保存时会清空StartedAtUtc、AssignedUsernames、LastCheckTime、Error、Canceled等运行态字段。适用条件是宿主前端包含 Fragment 任务中心表单,且已安装提供该任务定义的 Fragment 模块 1.2.9+。
GET /api/panel/tasks 和 GET /api/panel/tasks/{id} 的 BatchTaskDto 包含可空 name。普通一次性任务可为空,前端使用“任务类型 #ID”兜底;计划任务触发或手动“立即执行”创建的批量任务会复制计划任务名称,历史任务应优先展示 name,并保留任务类型作为辅助说明。自 v1.31.57 起,POST /api/panel/tasks 和 PATCH /api/panel/tasks/{id} 支持可选 name,服务端会去除首尾空白并限制最多 100 个字符;即时任务传空或省略时继续使用兜底显示,编辑任务时省略 name 会保留原名称,传空字符串会清空名称。该字段通过 BatchTasks.Name 持久化;回滚到旧版需先忽略或删除该列。
自 1.31.76 起,任务 DTO 还包含 ownerModuleId、executionKind、runtimePhase、runtimeMessage、heartbeatAtUtc、requiresAttention 和可空的 nextEligibleAtUtc。后者仅表示持久任务被延后后的下次可领取 UTC 时间,到期领取、暂停、恢复或取消后恢复为空。POST /api/panel/tasks 只接受任务目录中 canCreate=true 的类型,并由宿主写入所有者和执行通道;外部类型的模块页面不能伪造这些字段。创建/重跑只在内部 initializing 提交成功后返回 pending,编辑只允许从 paused 进入内部 updating,因此调度器不会读取未提交的模块配置;提交失败会返回错误并保留不可执行的失败记录或恢复编辑前快照。pausing 表示旧实例尚未退出。常驻任务会被拒绝创建或更新为 Cron 计划。成功判据是外部创建返回真实模块 ID 和 pending 状态,延后任务返回未来的 nextEligibleAtUtc,提醒状态出现在任务列表,服务端重跑获得新的任务 ID。失败时检查定义的安全 CreateRoute、执行器/生命周期处理器唯一性与模块校验错误;回滚前先删除常驻任务。
任务定义 DTO 的 canSchedule 只对宿主内置 batch 类型为 true。当前开发版不允许外部模块任务和 persistent 任务创建、更新或立即执行 Cron 计划,避免计划记录缺少模块所有权后被错误处理器领取;已有不合法计划会被后台自动暂停。
任务中心“复制”入口对已知 taskType 通用:复制执行中/历史 BatchTask 会读取 GET /api/panel/tasks/{id},复制 ScheduledTask 会读取 GET /api/panel/scheduled-tasks/{id},再用原 taskType 和清理运行态后的配置打开“新建任务”弹窗。内置专用表单会按配置回填;模块任务即使有独立 CreateRoute,复制时也走通用 JSON 配置区,确认后仍通过 POST /api/panel/tasks 或 POST /api/panel/scheduled-tasks 创建新记录。复制不会修改原任务,也不会绕过后端 JSON 校验。
自 v1.31.59 起,任务中心的“编辑计划任务”弹窗在窄屏设备上使用 min(760px, calc(100vw - 24px)) 宽度,并将表单标签切换为顶部布局;Cron、状态、专用任务配置和保存按钮不会依赖横向滚动。成功判据是在手机宽度打开计划任务编辑时,弹窗不超出视口、字段按单列排列且“保存计划任务”可见;回滚到旧版只会恢复固定 760px 弹窗,不涉及接口或数据库迁移。
自 v1.31.70 起,计划任务保存、恢复、后台补算和每次自动触发后会对 NextRunAtUtc 加入 ScheduledTasks:RandomDelaySeconds 范围内的随机延迟,默认 300 秒,且不会越过下一次 Cron 窗口。GET /api/panel/scheduled-tasks 和 GET /api/panel/scheduled-tasks/{id} 返回的是已经持久化的错峰后时间;POST /api/panel/scheduled-tasks/{id}/run-now 只立即创建本次执行记录,后续计划仍按 Cron 加随机延迟重算。
自当前开发版起,后台 account_auto_sync 任务在 config.failures 返回最多 50 条同步失败项,字段为 accountId、phone 和 error。任务详情前端也兼容早期 AccountId、Phone、Error 命名,调用方读取历史任务时应同样兼容两种形式。前置条件是某个账号实际同步失败;成功判据是 GET /api/panel/tasks/{id} 的原始 config 和任务中心都能显示同一账号编号、手机号及原因。若内容回退为占位值,检查持久化 JSON 的命名策略及前端字段读取;本变更无需迁移,回滚仅会让旧前端失去 PascalCase 历史项的显示兼容。
自 v1.31.44 起,channel_group_private_create 任务会在 config.recent_failures
返回最近 20 条失败明细。字段包括 time_utc、account_id、target_type、
target 和 reason。自 v1.31.48 起,user_chat_active 会在
config.recent_failures 返回最多 100 条账号活跃失败明细,字段包括 time_utc、
account_id、account、target 和 reason;自 v1.31.54 起,user_chat_active
目标支持群组、频道和 Bot 私聊(@xxxbot、t.me/xxxbot?start=...、
tg://resolve?domain=xxxbot)。目标列表的某一项可以是单个文本字典变量(例如 {groups}),执行器会把该字典的全部启用文本项展开成实际目标;字典项内部可用换行、空格或逗号分隔多个目标。目标字典不能使用 {time} 或图片字典,未知、停用或空文本字典会导致创建/启动失败。
自 v1.31.55 起,user_chat_active.config.message_rules 是消息选择的主合同。它是对象数组,
每项包含可选的 text 和 image_dictionary_token:text 保留内部换行,可用于多段消息;
image_dictionary_token 必须是单个已启用图片字典变量,例如 {active_images}。一条规则可以
只含文字、只含图片,或同时包含图片和说明文字;message_mode=random|queue 针对整条规则选择,
不会再把段落中的每一行拆成独立消息。前置条件是引用的文本/图片字典已启用且至少有一个可用项。
兼容字段 dictionary 和 image_dictionary_token 仍会读写:旧配置会在加载时转换为等价规则;
dictionary 保存所有非空规则文字,只有全部规则共享同一个非空图片字典时才回写全局
image_dictionary_token。成功判据是保存后任务详情包含 message_rules,重新编辑仍保留段落换行和
每条图片字典,实际执行按规则随机或循环。图片字典无效时创建页或任务启动会返回模板校验错误。
自当前开发版起,user_chat_active 创建/编辑表单的账号来源在“账号分类选择”和“账号编号填写”之间
二选一。前端提交分类来源时只写入 category_ids,提交编号来源时只写入 account_numbers;后端仍按现有
校验返回“请选择账号分类”或“请填写账号编号”。成功判据是创建页切换来源后只显示对应输入框,历史配置重新编辑时
按已保存的编号或分类恢复来源。回滚到旧版前无需迁移数据,但同时写入两类来源的旧配置在新版编辑时会优先按
账号编号来源展示。
回滚到 v1.31.54 或更早版本时,旧字段仍可继续发送文字;每条规则使用不同图片字典的配置无法被旧版
完整表达,回滚前应改为全部规则共用一个图片字典或纯文字规则。
自 v1.31.56 起,user_chat_active.config 增加 message_action_mode、reply_to_message_url、reply_to_message_id、forward_source_urls、forward_mode 和 skip_if_last_message_from_self。message_action_mode 默认为 send_generated_text,继续使用 message_rules 发送;前端只展示 reply_to_message_url,通过 Telegram 消息链接解析回复消息 ID。reply_to_message_id 保留为原始 API 兼容字段,自动化调用可继续大于 0 传入,但与 reply_to_message_url 同时存在时必须指向同一条消息。message_action_mode=forward_url 时,forward_source_urls 必须至少包含一个 Telegram 消息链接,forward_mode=with_attribution|hide_attribution 控制原生转发是否保留来源引用;此时前端不展示内容模式,默认按随机来源选择保存,原始 API 仍可用 message_mode=queue 改为队列选择。此模式不执行模板渲染、图片字典或 AI 验证。skip_if_last_message_from_self=true 时,发送或转发前会读取目标最新普通消息;若它仍由当前执行账号发出,本轮记为已处理但不发送,以避免同账号连续刷屏。成功判据是任务详情配置摘要显示“发送动作”和“去重发送”,且转发模式不再显示内容模式;recent_failures 为空或只记录真实 Telegram 访问/权限错误。开启去重但无法读取目标最新消息时,本轮会失败并记录原因。回滚到 v1.31.55 或更早版本前,应把任务重新保存为 send_generated_text 并关闭去重,否则旧版不会理解转发来源和去重字段。
自当前开发版起,user_chat_active.config.forward_source_urls 的单项也可以是单个文本字典变量(例如 {forward_sources})。执行器启动时会把该字典全部启用内容展开为 Telegram 消息链接,字典内容可用换行、空格或逗号分隔多个来源链接;未知、停用、空文本字典或展开后不是有效 Telegram 消息链接都会启动失败,不会静默跳过。account_mode=queue 会维护 account_queue_cursor,有限任务多次运行时会从上次使用后的下一个账号继续轮询;回滚到旧版前无需迁移,但旧版会忽略该游标并从第一个账号重新开始。
user_join_subscribe 会在 config.failures 返回最多 200 条失败明细,字段包括 accountId、
target 和 reason,并会对 Telegram 瞬时连接错误执行一次客户端重建重试。
user_join_subscribe.config.DelayMs 和即时 /accounts/chat-membership 的 delayMs 允许 0-60000 毫秒,服务端会按该范围夹取;系统设置里的默认批量操作间隔为 1000-60000 毫秒。Plain Bot 链接(例如 https://t.me/SpamBot、@examplebot)没有 start 参数时会向 Bot 私聊发送普通 /start,不会再调用必须携带 start_param 的 deep-link 接口;带 ?start=abc 时仍走 Telegram deep-link 启动接口。
成功判据是任务的 failed 大于零时,详情接口和任务中心均能看到对应失败账号、目标和原因;
该字段为空表示没有失败或运行的是尚未支持失败明细的旧版本。
失败原因来自当次执行,最长 500 字符。接口调用方不得把其中内容当作稳定错误码;需要自动化 判断时应优先匹配 Telegram/RPC 的明确错误标识。回滚到 v1.31.53 或更早版本不会解析 Bot 私聊活跃目标, 也不会继续写入新增重试后的失败描述。
auto_change_login_email 任务使用 config.items 返回最近账号级结果,字段包括 time_utc、
account_id、phone、email、target_domain、previous_login_email_pattern、
previous_login_email_domain、result、message、matched_message_id 和
matched_message_date_utc。任务配置可使用 domains 保存邮箱域名池;运行时会读取账号当前登录邮箱掩码,
如果域名池里存在多个域名并能识别原域名,会优先随机选择一个不同于原域名的域名生成 手机号数字@目标域名。
result 只表示该账号在本轮任务中的处理结果:success 表示已发送并在开启自动确认时完成登录邮箱验证码确认,skipped 表示因 Cloud Mail 配置、目标邮箱或通知匹配条件不足而未操作,failed 表示 Telegram/Cloud Mail 调用失败或收码确认失败。默认不会删除、停用或禁用账号;除非配置 force=true,否则没有匹配 777000 登录邮箱重置通知的账号不会被换绑。
需要给外部系统调用时,优先使用模块的 MapEndpoints 明确设计鉴权、限流和响应模型,
不要直接把管理 Cookie 接口暴露到公网。
轻量 WARP 管理 API(v1.31.83)¶
档案响应的 poolEligible 表示当前可被空闲池领取:排除内部临时归属、停止意图、
已有占用或账号绑定,且要求运行及联网检测就绪。这只是瞬时快照,领取时仍原子校验,
不能作为客户端自行复用出口的授权。shareEligible 则用于显式共享绑定或全局选择:已有正式
账号或全局引用不影响共享资格,未完成首连或失败清理的 claim 不可共享,运行状态仍需就绪。
首次正式绑定后解除绑定,不会因为原临时归属标记而永久禁止复用。
isGlobal 表示启用的全局引用,usageCount 包含全局继承使用情况;accountCount 和绑定账号
查询端点仅表示显式 ProxyId 绑定,不能用它们判定是否没有全局使用。
v1.31.82 的旧 Razor 登录/导入兼容页也使用相同的资格快照;运行器不可用、档案读取失败、 代理 ID 不匹配或存在启用的全局引用时,不计入页面空闲池。本次修复不改变公开 API 合同。
以下接口均位于已登录的 /api/panel 下,不接受或返回 WARP 私钥、注册
Token、SOCKS 密码或上游原始输出。
GET /proxies/wgcf:返回环境是否可用及档案数组。档案包含profile、phase、registered、generated、desired、runtime、proxyId、accountCount、检测状态和 脱敏错误。runtime=listening只代表本地监听,不能替代testStatus=ok。POST /proxies/wgcf:请求体为{ requestId, name, acceptTerms }。requestId为 UUID,acceptTerms必须为true;name可为空,服务会按 requestId 生成稳定的“轻量 WARP-XXXXXXXX” 名称。返回已持久化的档案状态,后续以 GET 读取创建进度。同一 requestId 幂等。登录、导入和 账号绑定的创建流程仍须由调用方显式确认条款。POST /proxies/wgcf/{profile}/resume、start、stop、test:恢复失败档案、切换期望 启停或执行出口检测。停止被账号、启用的全局配置或临时 claim 引用的出口返回冲突,调用方需先解除占用。DELETE /proxies/wgcf/{profile}:返回OperationResultDto。检查账号、全局配置和 claim 后, 请求停止并等待停止回执确认,再删除本地代理和档案材料。不保证注销 Cloudflare 远端注册; 停止或清理失败保留可重试状态,调用方必须检查操作结果,不能仅根据 HTTP 成功判定已删除。
常规代理 DTO 包含可空 managedWgcfProfile。带该字段的代理仍不能用常规代理编辑接口改变
运行参数,启停和删除需经过上述受管生命周期检查。已有代理编号的受管出口支持批量分类;
页面批量删除将轻量项交给受管删除路径逐项处理,失败项保留并返回原因,其它可删除项继续执行。历史 kind=warp 记录也可进入普通删除路径;仍被账号或全局代理引用的记录返回失败原因并保留,前端不会再将其永久设为不可选。
尚未生成代理编号的档案使用相同专用删除端点,可逐项批量调用,不参与分类。
统一代理列表由 GET /proxies 和 GET /proxies/wgcf 合并,以
managedWgcfProfile / profile 关联。未落库的创建中或失败档案仍需显示;同一档案
不能因已有 proxyId 而重复成两行。页面合表不改变 API 的运行态来源;显式共享资格与自动空闲池资格必须分别处理。
账号登录(手机和二维码)、导入(表单或 StringSession)及单/批账号代理绑定的
warp_per_account 新增 acceptWarpTerms 与可选 warpRequestId,前者必须显式为 true。
warpRequestId 省略时由服务端生成;提供时必须为非零 UUID,空字符串、空白和非法值返回 400。
登录清理失败会保留会话占用供后台重试;取消或重置返回明确失败,不能视为出口已停止。
旧 POST /proxies/warp 请求改为 {name, requestId, acceptWarpTerms, protocol:"socks5"},
返回档案而非代理 DTO,通过 GET /proxies/wgcf 等待完成。旧容器状态与维护接口已撤除。
首次连接期间的出口不可由其它流程绑定、恢复或启停;内部归属 token 不接受公开提交。
代理重命名(v1.31.86)¶
PUT /api/panel/proxies/{id}/name,沿用管理员鉴权,请求体为 {"name":"新名称"}。
名称去除首尾空白后必须是 1–80 个字符。成功返回 {"success":true,"message":"代理名称已更新"};
名称无效返回 400,代理不存在返回 404。适用于已落库代理,包括普通、Resin、外部 WireGuard、
受管轻量 WARP 以及旧代理记录;未落库档案没有可用编号,不能调用。
接口只修改显示名称与更新时间,不改变运行器、连接参数、凭据、分类或账号/全局引用。 操作可重复提交同一名称;请求超时先重新查询代理列表核对结果。轻量运行态同时以数据库名称显示, 重启或恢复后保持新名称。升级无需迁移数据,回滚保留数据卷;旧版未提供该接口。