跳到主要内容

负载格式

每次 Webhook 投递都是一个带有 JSON 请求体的 POST 请求。请求头携带用于防重放保护、签名校验和重试跟踪的元数据。

请求体

每个事件使用相同的信封:

{
"id": "evt_8c1f2a3b4d",
"type": "strategy.deployed",
"created_at": "2026-04-29T12:00:00.000Z",
"data": { ... }
}
字段类型说明
idstring唯一事件标识,格式为 evt_<10-12 hex>。用于幂等去重。
typestring事件类型;取下文枚举的某个值。
created_atstringISO 8601 UTC 时间戳,精度到毫秒,表示事件在服务端生成的时间。
dataobject与事件类型相关的负载。各类型的 schema 详见下文。

请求头

请求头说明
X-PipAI-Event-Id唯一事件 ID。与 body.id 相同。用于幂等。
X-PipAI-Event-Type事件类型。与 body.type 相同。便于在不解析请求体的情况下进行路由。
X-PipAI-Webhook-Id本次投递所属的 Webhook 订阅(例如 wh_2a4f10)。当一个端点服务多个订阅时很有用。
X-PipAI-Delivery-Id每次投递的唯一标识。同一 event_id 作为重试再次投递时,多次尝试间会复用同一个 Delivery ID。
X-PipAI-Delivery-Attempt整型尝试计数,从 1 开始。在重试计划中递增到 10 后会放弃投递。
X-PipAI-Timestamp投递时的 Unix 毫秒(ms)。用于在签名校验时计算重放窗口。
X-PipAI-Signature十六进制编码的 HMAC-SHA256(webhook_secret, "{timestamp}.{raw_body}")。详见 签名校验

事件类型

通配符订阅(strategy.*backtest.*account.**)在注册时也被接受——参见 创建 Webhook

事件类型说明数据 schema
strategy.created策略以 draft 状态被创建。strategy.created
strategy.deployed策略已部署到生产环境(如果 dry_run 则为模拟交易)。strategy.deployed
strategy.paused策略被暂停;不会再开新仓。strategy.paused
strategy.stopped策略已停止(终态,不可恢复)。strategy.stopped
strategy.position_opened策略开了一个新仓位。strategy.position_opened
strategy.position_closed一个开仓被平仓;PnL 已最终确定。strategy.position_closed
strategy.order_filled策略下的订单成交(全部或部分)。strategy.order_filled
strategy.error策略遇到不可恢复的错误并已停止。strategy.error
backtest.job_done一个回测任务成功完成。backtest.job_done
backtest.job_failed一个回测任务因错误中止。backtest.job_failed
account.balance_low受监控的资产余额降到配置阈值以下。account.balance_low
account.api_key_rotated账户上的某个 API 密钥已轮换。account.api_key_rotated

各事件数据 schema

strategy.created

{
"strategy_id": "strat_8f2a1b",
"name": "BTC grid 1h",
"status": "draft"
}

strategy.deployed

{
"strategy_id": "strat_8f2a1b",
"name": "BTC grid 1h",
"capital": "10000.00",
"leverage": 3,
"deployed_at": "2026-04-29T12:00:00.000Z"
}

strategy.paused

{
"strategy_id": "strat_8f2a1b",
"status": "paused"
}

strategy.stopped

{
"strategy_id": "strat_8f2a1b",
"status": "stopped"
}

strategy.position_opened

{
"strategy_id": "strat_8f2a1b",
"position_id": "pos_19acb2",
"symbol": "BTCUSDT",
"side": "long",
"entry_price": "67234.50",
"qty": "0.05",
"leverage": 3,
"opened_at": "2026-04-29T12:00:01.245Z"
}

strategy.position_closed

{
"strategy_id": "strat_8f2a1b",
"position_id": "pos_19acb2",
"symbol": "BTCUSDT",
"side": "long",
"entry_price": "67234.50",
"exit_price": "68110.00",
"qty": "0.05",
"exit_qty": "0.05",
"pnl": "43.78",
"leverage": 3,
"opened_at": "2026-04-29T12:00:01.245Z",
"closed_at": "2026-04-29T13:42:18.880Z"
}

strategy.order_filled

{
"strategy_id": "strat_8f2a1b",
"order_id": "ord_3c9df4",
"symbol": "BTCUSDT",
"side": "buy",
"type": "limit",
"price": "67234.50",
"qty": "0.05",
"filled_at": "2026-04-29T12:00:01.180Z"
}

strategy.error

{
"strategy_id": "strat_8f2a1b",
"error_code": "ORDER_REJECTED",
"message": "Exchange rejected order: insufficient margin"
}

backtest.job_done

{
"job_id": "bt_4d2e7c1f",
"metrics": {
"total_return": "0.184",
"sharpe": "1.62",
"max_drawdown": "-0.073",
"win_rate": "0.541",
"total_trades": 312,
"profit_factor": "1.78"
}
}

完整的指标定义参见 回测指标 参考文档。

backtest.job_failed

{
"job_id": "bt_4d2e7c1f",
"error_code": "TIMEOUT",
"message": "Job exceeded maximum runtime of 30 minutes"
}

account.balance_low

{
"asset": "USDT",
"balance": "12.50",
"threshold": "100.00"
}

阈值通过创建 Webhook 时的 balance_low_threshold 按 Webhook 配置——参见 创建 Webhook

account.api_key_rotated

{
"key_id": "key_7a91c2",
"rotated_at": "2026-04-29T12:00:00.000Z"
}

确认

你的端点必须在收到请求后的 10 秒 内返回 2xx HTTP 状态。任何其他结果——非 2xx 响应、响应过慢、TLS 错误或连接失败——都会被视为投递失败,并按 概览 中的计划进入重试队列。

响应体会被忽略。空的 200 OK 即可。

如果你需要在响应事件时执行较重的工作,请同步确认并将工作分发到后台队列。在处理事件期间一直占用连接,会让投递工作线程饥饿,并触发不必要的重试。