HTTP API
这套 API 由守护进程提供,因此 relay-core start 与前台运行的 relay-core run 都会服务它;默认基址 http://127.0.0.1:8082/api/v1/,端口被占时守护进程会回落到临时端口,实际端口写在 $RELAY_DATA_DIR/daemon.json 里(relay-core status 会直接告诉你)。
守护进程默认生成 Bearer 令牌并要求 Authorization: Bearer <T>(令牌同样在清单里,清单权限为 0600)。Web UI 例外:浏览器无法给 EventSource 加请求头,所以守护进程打印的 Web UI 地址把令牌放在 URL fragment 中,页面把它换成 SameSite=Strict 的同源 cookie 并立即从地址栏抹掉——fragment 不会被浏览器发给服务器,令牌因此不进请求日志。鉴权中间件接受 Bearer 头或该 cookie。使用 --api-cors <origins> 才下发 CORS 头,否则严格同源。
代理生命周期
这三个端点是"开启/关闭代理"的线上形态:CLI 的 start / stop 与 MCP 的 proxy_start / proxy_stop 走的都是它们。
GET /api/v1/proxy/status
{"phase": "running", "port": 8080, "started_at_ms": 1789817862851, "last_error": null} POST /api/v1/proxy/start
启动代理。幂等:已在运行返回 200 与 already_running,本次真正启动返回 201;端口被占等失败返回 409 与稳定错误码(如 start_failed),而不是一个从未 listen 的成功。
{"port": 8080, "transparent": false} POST /api/v1/proxy/stop
停代理,守护进程与历史保留。幂等:未运行时返回 already_stopped。
POST /api/v1/daemon/shutdown
停代理并退出守护进程。请求被接受后守护进程会先写清单清理、再停代理、最后释放数据目录锁。
另外,X-Relay-Client 头可以带一个客户端自述标签(例如 cli:relay-core start),会记入审计事件;它不用于鉴权,只为回答"这次变更是谁做的"。GET /api/v1/audit?kind=proxy_lifecycle_changed 可读出这些记录。
版本与状态
GET /api/v1/version
引擎版本、API 版本与已注册的能力名称列表。
{
"engine_version": "0.14.0",
"api_version": "1",
"capabilities": ["flows", "rules", "intercepts", "mock", "metrics", "status", "events", "scripts"]
} GET /api/v1/status
运行时生命周期快照——运行时长、当前规则数、未决拦截数等。
流量
GET /api/v1/flows
搜索与分页已捕获流量。所有参数均可选。
查询参数:
host、path、path_contains、method— 子串匹配status_min、status_max— 状态码区间has_error— 仅含错误的流量is_websocket— 仅 WebSocket 流量limit— 返回条数(默认 50,范围 1–200)offset— 分页偏移
{
"items": [{ "id": "fld_...", "method": "GET", "path": "/users", "status": 200 }],
"returned": 10,
"limit": 50,
"offset": 0
} 在响应离开服务器前会应用 redaction 策略:敏感 query 参数与 header 会被掩码,确保即使观察到敏感信息也不会外泄。
GET /api/v1/flows/:id
返回完整 Flow JSON(含 header 与 body)。同样应用 redaction。
POST /api/v1/flows/:id/replay
按已捕获的 HTTP 请求再发一次。这次调用不能改头或改体。重放从本代理的监听端口进去,会记成一条新流量,当前规则和脚本会生效;代理没在运行时返回 503。?accept_invalid_certs=true 让重放客户端跳过 TLS 校验(仅限调试)。引擎自己的 CA 会自动加入信任。WebSocket 流量会返回 400。
GET /api/v1/flows/:id/har
将单条流量导出为 HAR 1.2 entry。
GET /api/v1/flows/export/har
批量 HAR 导出,支持与 GET /api/v1/flows 相同的查询参数。
规则
GET /api/v1/rules
列出所有拦截规则。每条返回完整 Rule 对象(id、name、active、stage、priority、termination、filter、actions)。启用字段是 active,不是 enabled。
PUT /api/v1/rules
按 id 创建或覆盖规则。
{
"id": "rul_01HX5K9P3Q8Y2Z7",
"name": "Tag API requests",
"active": true,
"stage": "RequestHeaders",
"priority": 100,
"termination": "Continue",
"filter": {
"type": "And",
"config": [
{ "type": "Method", "config": { "mode": "Exact", "value": "GET" } },
{ "type": "Host", "config": { "mode": "Glob", "value": "*.example.com" } },
{ "type": "Path", "config": { "mode": "Glob", "value": "/api/*" } }
]
},
"actions": [{ "type": "Tag", "config": { "key": "kind", "value": "api" } }]
} DELETE /api/v1/rules/:id
删除规则。
POST /api/v1/mock
快速创建 MockResponse 规则。Body 字段:url_pattern、status、body、content_type。
拦截
POST /api/v1/intercepts
创建一次性拦截断点。
{
"url_pattern": "api.example.com",
"phase": "request"
} 响应中包含生成的 rule_id,后续以此引用该拦截。
GET /api/v1/intercepts
列出待处理拦截(HTTP 与 WebSocket 一起)。
POST /api/v1/intercepts/:key/resume
继续被拦截的流量。Body 支持 action(continue 或 drop)以及 FlowModification 字段:method、url、request_headers、request_header_upserts、request_body、status_code、response_headers、response_header_upserts、response_body、message_content。*_header_upserts 按名增改并保留其余头;request_headers / response_headers 会整表替换。
策略与脱敏
GET /api/v1/policy
返回当前 ProxyPolicy,包含 redaction 块以及(若已配置)upstream 块。Upstream auth.password 会被掩码为 ***。
PATCH /api/v1/policy
应用部分更新。顶层只接受 redaction、upstream、retention,未知字段会 400。三者都可省略:
{
"redaction": {
"enabled": true,
"redact_bodies": true,
"sensitive_header_names": ["authorization", "x-api-key", "cookie"],
"sensitive_query_keys": ["token", "api_key", "password"]
},
"upstream": {
"proxy_url": "http://corp-proxy.internal:8080",
"bypass_hosts": ["*.internal", "127.0.0.1"],
"fail_open": false
}
} 脱敏默认开启。默认策略会掩码下面的敏感 header 与 query 名,因此全新安装不会把凭据
原样持久化或返回——包括返回给任何读 API 的一方。body 是例外:redact_bodies 仍为关闭,
因为改写载荷内容会改变规则与脚本看到的东西。确实需要原始 header 时,请显式关闭脱敏。
默认敏感 header 名:authorization、proxy-authorization、cookie、set-cookie、x-api-key、x-auth-token。
默认敏感 query key:token、access_token、refresh_token、api_key、apikey、password、secret。
Redaction 作用于 HTTP 请求/响应、WebSocket 握手、每条 WebSocket 消息、流量摘要、搜索结果以及 SSE 事件流。运行时写入新的 proxy_url、认证、fail_open 或 bypass_hosts 会作用于之后的请求;匹配绕过列表的主机直接拨号。新地址解析失败且 fail_open 为 false 时,继续用上一份连接器。
脚本
POST /api/v1/script
热加载脚本到运行中的引擎。
{ "script": "globalThis.onRequestHeaders = (ctx, flow) => { console.log(flow.layer.data.request.url); return flow; }" } 事件
GET /api/v1/events
实时更新的 Server-Sent Events 流。
事件类型:
flow— 新流量或流量更新(data 字段为完整 Flow JSON)ws-message— 新 WebSocket 消息http-body— 预算内的 body,data 为{ flow_id, direction, body }body-budget-exceeded— 某方向 body 超出预算,data 为{ flow_id, direction }response-trailers— HTTP/2 trailers,data 为{ flow_id, trailers }flow-event— 类型化事件(拦截暂停/恢复、规则改写、终局),与flow快照并存audit— 控制平面变更(规则变更、拦截解决、脚本重载、策略更新)audit-lagged— 审计通道丢事件,服务器重新同步lagged— 流量/事件通道丢事件,TUI 重新同步lifecycle— 代理启动/停止/重载
指标
GET /api/v1/metrics
JSON 指标快照。字段同 relay-core metrics(见 CLI 参考)。
GET /api/v1/metrics/prometheus
Prometheus 文本格式指标。
# HELP relay_core_flows_total Total number of flows captured
# TYPE relay_core_flows_total counter
relay_core_flows_total 12847
# HELP relay_core_request_duration_ms Request duration in milliseconds
# TYPE relay_core_request_duration_ms histogram
relay_core_request_duration_ms_bucket{le="1"} 10023
relay_core_request_duration_ms_bucket{le="5"} 12500
relay_core_request_duration_ms_bucket{le="10"} 12800
relay_core_request_duration_ms_bucket{le="+Inf"} 12847 脚本引擎指标按 hook 维度发射:relay_core_script_hook_duration_us{hook}、relay_core_script_hook_invocations_total{hook}、relay_core_script_hook_errors_total{hook},另有 relay_core_script_env_access_total、relay_core_script_fetch_total 与 relay_core_script_fetch_rejected_total。
审计
GET /api/v1/audit
查询控制平面变更审计日志。
查询参数:
since_ms、until_ms— 毫秒时间戳;任一可省略actor—runtime、http、tauri、probe、clikind—rule_changed、intercept_resolved、script_reloaded、policy_updatedoutcome—success或failure
响应为 AuditEvent 数组,每条记录谁在何时做了何种变更,以及变更前/后的差异。