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

搜索与分页已捕获流量。所有参数均可选。

GET /api/v1/flows?method=GET&host=api.example.com&limit=10&offset=0

查询参数:

  • 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。

GET /api/v1/rules

PUT /api/v1/rules

按 id 创建或覆盖规则。

PUT /api/v1/rules
{
  "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

删除规则。

DELETE /api/v1/rules/rul_01HX5K9P3Q8Y2Z7

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 流。

GET /api/v1/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

查询控制平面变更审计日志。

GET /api/v1/audit?since_ms=1705276800000&actor=http&kind=policy_updated

查询参数:

  • since_ms、until_ms — 毫秒时间戳;任一可省略
  • actor — runtime、http、tauri、probe、cli
  • kind — rule_changed、intercept_resolved、script_reloaded、policy_updated
  • outcome — success 或 failure

响应为 AuditEvent 数组,每条记录谁在何时做了何种变更,以及变更前/后的差异。