API 参考
BlankTrail Proxy 提供了一个本地 HTTP API,让你能够开放端口、配置身份,并自动化控制面板所能完成的一切操作。本页介绍基础 URL、身份验证和约定规范。
基础 URL
所有端点都位于与控制面板相同的主机和端口下的 /api/v1 前缀之下:
http://127.0.0.1:8891/api/v1
API 与控制面板共用同一个源,因此来自您自己的脚本和工具的调用可以开箱即用。
身份验证
该 API 采用默认拒绝策略:几乎每个端点都需要身份验证。有两种身份验证方式:
- API 密钥 —— 通过 X-API-Key 请求头发送。最适合脚本和自动化。
- 会话 Cookie —— 通过登录获取;供浏览器控制面板使用。
您可以在控制面板的“设置”对话框中查找和轮换您的 API 密钥。在每个请求上都要发送它:
curl -H "X-API-Key: YOUR_API_KEY" http://127.0.0.1:8891/api/v1/status
约定规范
- 请求和响应均为 JSON。对于带有请求体的请求,请发送 Content-Type: application/json。
- 配置始终在 JSON 请求体中发送,绝不通过查询字符串发送。
- 该 API 在 /api/v1 下进行版本管理。破坏性变更将迁移到新的版本前缀。
状态码
错误响应体始终一致:一个带 error 字段和英文文本的对象;部分拒绝还会附带 code 字段,即机器可读的原因。各接口的说明中给出了这些文本:据此区分同为 400 的不同原因。405 是例外:它由路由器以纯文本返回,而非 JSON。
| 状态码 | 含义 |
|---|---|
200 OK | 成功。 |
202 Accepted | 已接受并在后台执行——启动更新时即以此作答。 |
400 Bad Request | 输入有误:请求体无法解析、字段缺失或取值不被允许。 |
401 Unauthorized | 未发送 API 密钥或密钥错误。请检查请求头名称:X-API-Key。 |
403 Forbidden | 被拒绝的原因不是密钥而是状态:许可未激活(订阅已结束,或 24 小时内未连接授权服务器),或该功能需要 Pro 套餐。 |
404 Not Found | 对象不存在:路径未注册、端口未开放,或条目未找到。 |
405 Method Not Allowed | 路径存在但方法不对——例如对只读接口发送 PUT。该状态码由路由器本身返回,而不是由处理程序返回。 |
409 Conflict | 状态存在冲突:端口已被占用、名称已存在,或网关正在使用中。 |
429 Too Many Requests | 过于频繁——例如重复提交问题报告。请降低频率后重试。 |
500 Internal Server Error | 应用内部发生了意外错误。 |
501 Not Implemented | 该组件在此构建中未编译或未接入——例如未配置身份验证时,控制面板登录即以此作答。 |
502 Bad Gateway | 对外请求失败:Cabinet 不可达,或对该地址的访问未能完成。 |
503 Service Unavailable | 此刻无法作答:没有空闲端口、服务未启动,或调试钩子未接入。 |
按主题查阅参考
- 端口与流量 —— 开放、关闭、列出和配置端口;测试上游代理。
- 配置文件与路由 —— 身份、预设、域名规则和网关。
- 端口池 —— 从代理列表开放和管理端口池。
- 许可证与访问 —— 许可证状态、身份验证以及 CA 证书。
服务类接口
这些接口不属于业务流程本身,而是伴随其左右:确认应用存活、在排查期间提高日志详细度、查询更新,以及设置全局路由规则。
/api/v1/log_level需要鉴权当前的日志级别。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/log_level{
"level": "info"
}/api/v1/log_level需要鉴权在排查期间提高详细度:debug 会写入明显更多内容,并持续到下次重启。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
level | string | 是 | debug、info、warn 或 error。 |
{ "level": "debug" }curl -X PUT -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"level":"debug"}' \
http://127.0.0.1:8891/api/v1/log_level{
"level": "debug"
}- 其他取值一律返回 400 “level must be one of: debug, info, warn, error”。
/api/v1/update/status需要鉴权已安装的版本以及是否有新版本:没有更新时 available 为空;state 显示更新器当前的状态。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/update/status{
"current": "1.3.2",
"available": "",
"state": "idle",
"last_error": "",
"download_url": ""
}- 在未包含自更新的构建中返回 404 “self-update not available”。
/api/v1/update需要鉴权安装 /update/status 所报告的更新。应用会自行重启。
curl -X POST -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/update{
"status": "started"
}- 🔴 响应为 202 Accepted 而不是 200:更新已被接受并在后台执行,并非在响应返回时已经完成。请通过轮询 /update/status 等待其结束。
- 若没有可安装的更新,返回 409 “no update available”;在未包含自更新的构建中返回 404 “self-update not available”。
/api/v1/domain_routing需要鉴权简单路由规则:一组域名以及它们共用的出口代理。列表为空表示该规则关闭。带名称的详细规则位于 /domain_rules。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/domain_routing{
"domains": ["example.com", "*.example.net"],
"proxy": "socks5://203.0.113.10:1080"
}/api/v1/domain_routing需要鉴权整体设置简单规则:域名与代理。域名列表为空即关闭该规则。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
domains | array | 是 | 域名及形如 *.example.net 的掩码。 |
proxy | string | 是 | 这些域名所使用的出口代理。 |
{ "domains": ["example.com"], "proxy": "socks5://203.0.113.10:1080" }curl -X PUT -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"domains":["example.com"],"proxy":"socks5://203.0.113.10:1080"}' \
http://127.0.0.1:8891/api/v1/domain_routing{
"domains": ["example.com"],
"proxy": "socks5://203.0.113.10:1080"
}- 若域名或代理地址格式有误,返回 400 并附说明。
/api/v1/idle_timeout需要鉴权适用于没有自身设置的端口的全局空闲超时。0 表示不关闭。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
seconds | int | 是 | 端口自动关闭前的空闲秒数;0 表示不关闭。 |
{ "seconds": 1800 }curl -X PUT -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"seconds":1800}' \
http://127.0.0.1:8891/api/v1/idle_timeout{
"idle_timeout_seconds": 1800
}- 取负值时返回 400 “seconds must be >= 0”。设置了自身覆盖值的端口(PUT /api/v1/port/{port}/idle)不会采用该值。
问题报告
该报告会收集日志与端口状态并发送给支持团队。发送前可完整查看——那正是将要发送的同一份文件。
/api/v1/bug-report/status需要鉴权报告发送是否已启用,以及上次运行是否非正常退出——若是,控制面板会主动提示发送报告。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/bug-report/status{
"enabled": true,
"unclean_previous_exit": false
}- enabled=false 表示在没有有效许可的情况下无法发送。
/api/v1/bug-report/preview需要鉴权生成报告并展示,但不发送任何内容。
curl -X POST -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/bug-report/preview{
"report": { "version": 1, "ports": [ … ], "log": [ … ] },
"notes_included": false
}- 若报告收集功能未接入,返回 404 “bug report not available”;500 “failed to build report”。
/api/v1/bug-report/send需要鉴权把报告连同您的描述一起发送给支持团队。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
description | string | 是 | 发生了什么。该字段必填:去除空白后为空将被拒绝。 |
{ "description": "更换出口后端口不再返回 200" }curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"description":"port stopped returning 200 after an egress change"}' \
http://127.0.0.1:8891/api/v1/bug-report/send{
"status": "sent",
"bug_report_id": "br-7f3a1c9d"
}- 未填写描述时返回 400 “description required”;403 “activate your license to send a bug report”;404 “bug report not available”;发送过于频繁时返回 429;若支持服务器不可达,返回 502。
- 请求体上限为 64 KiB。
/api/v1/bug-report/dismiss需要鉴权拒绝所提示的报告:在本次运行剩余时间内不再显示非正常退出提示。
curl -X POST -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/bug-report/dismiss{
"status": "dismissed"
}- 该标记仅存于内存:若下次运行确实再次非正常退出,它会被重新置位。
诊断
当应用行为异常、需要在支持请求中附上数据而非描述时,可使用这些路径。它们并非产品接口:其格式由运行时决定,可能在版本之间发生变化。
/api/v1/debug需要鉴权进程自身的快照:goroutine、系统线程、句柄、内存与运行时间。若应用变得沉重,这是首先应附上的内容。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/debug{
"goroutines": 142,
"threads": 21,
"handles": 380,
"open_ports": 2,
"uptime": "3h14m22s",
"memory": {
"alloc_mb": 96,
"total_alloc_mb": 8140,
"sys_mb": 310,
"heap_objects": 410000,
"heap_inuse_mb": 120,
"heap_released_mb": 64,
"gc_cycles": 1830,
"stack_inuse_mb": 6
}
}- handles 字段始终存在,但只在 Windows 上有意义:该数值由系统自身统计;在其他平台上它恒为 0。
性能剖析(pprof)
十一个标准的 Go 路径,使用普通 API 密钥即可访问。它们返回的是进程内部信息而非用户数据,但与其余 API 一样需要密钥。
| 路径 | 返回内容 |
|---|---|
/debug/pprof/ | 索引:可用性能剖析的列表。 |
/debug/pprof/heap | 堆快照——内存增长时应从这里入手。 |
/debug/pprof/goroutine | 所有 goroutine 及其栈——出现卡住时应从这里入手。 |
/debug/pprof/allocs | 自启动以来的全部内存分配。 |
/debug/pprof/profile | CPU 剖析。🔴 它会保持连接 30 秒——这不是卡死。 |
/debug/pprof/trace | 执行跟踪。 |
/debug/pprof/block | goroutine 在阻塞操作上的等待情况。 |
/debug/pprof/mutex | 互斥锁竞争。 |
/debug/pprof/threadcreate | 系统线程创建。 |
/debug/pprof/cmdline | 进程的命令行。 |
/debug/pprof/symbol | 把地址解析为函数名。 |
为报告采集堆与 goroutine:curl -H "X-API-Key: YOUR_API_KEY" -o heap.pprof http://127.0.0.1:8891/debug/pprof/heap,goroutine 同理。使用 go tool pprof heap.pprof 打开它们。
解题器的调试特征机制
该机制只为一件事而存在:在不重建、不发布资源包的情况下检查挑战特征是否匹配。在此之前,这样一个循环需要重建资源包、签名、发布,并等待客户端重新读取资源包,最长达半小时。
/api/v1/debug/signatures需要鉴权报告当前是否在资源包特征库之上叠加了调试特征层,以及其中有多少条目。
curl -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/debug/signatures{
"debug_active": true,
"debug_vendors": 3
}- 若已设置开关但该构建未接入解题器钩子,返回 503 “solver debug hooks not wired”。这不是 404:路由本身存在,区分这两种状态很重要。
/api/v1/debug/signatures需要鉴权把所提交的特征集合作为独立层叠加到资源包特征库之上——无需重建资源包、签名或发布。
{ "Version": 7, "Vendors": [ { "…": "…" } ], "NavHints": [ ] }curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
--data-binary @signatures.json \
http://127.0.0.1:8891/api/v1/debug/signatures{
"installed": 3,
"dropped": 1
}- 请求体是与资源包相同格式的特征库。installed 表示被接受的厂商数量,dropped 表示所提交条件中被丢弃的数量。
- 该层可经受任意次数的资源包更新,只有显式 DELETE 才会移除。安装动作会以警告写入日志——被遗忘的层不应无声无息地留存。
- 503 “solver debug hooks not wired”;400 “invalid JSON body”。
/api/v1/debug/signatures需要鉴权移除调试特征层,让解题器回到资源包特征库。
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" \
http://127.0.0.1:8891/api/v1/debug/signatures{
"cleared": true
}- 若未接入钩子,返回 503 “solver debug hooks not wired”。
/api/v1/port/{port}/solve_probe需要鉴权让解题器经由指定端口访问给定地址,并返回它在那里看到的内容——无论特征是否匹配。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url | string | 是 | 要让解题器访问的地址。 |
solve | bool | 否 | false(默认)只识别厂商与页面性质,约需一秒。true 还会强制求解。 |
{ "url": "https://example.com/", "solve": true }curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-H "Accept-Language: ru-RU,ru;q=0.9" \
-d '{"url":"https://example.com/","solve":true}' \
http://127.0.0.1:8891/api/v1/port/20134/solve_probe- 🔴 当 solve=true 时,此处刻意不设人为超时:强制求解确实需要数十秒,某些验证甚至长达一分半。请求并没有卡死。
- 该请求的 Accept-Language 头会被原样传入任务:启动语言会影响结果,若不传入,求解就会带着出口节点的语言而非所请求的语言。
- 503 “solver debug hooks not wired”;400 “url is required”;若访问本身失败,返回 502 并附带错误文本。