Beatra

回调

任务终态通知:签名验证、Header、重试策略与 payload 结构。

创建任务时传 callback_url(必须 HTTPS),任务到达终态后 Beatra 主动 POST 通知你。回调与轮询互不排斥;任务状态始终以 GET /v1/tasks/{task_id} 为准。

你会收到什么

POST {callback_url}10 秒内返回 2xx 视为送达。

Header说明
X-Event-Id事件唯一 ID,重试间保持不变 —— 用它做幂等去重
X-Delivery-Id每次投递尝试唯一
X-Delivery-Attempt第几次尝试(从 1 开始)
X-Task-Id任务 ID
X-Event-Typetask.succeeded / task.failed / task.canceled
X-TimestampUnix 秒级时间戳
X-Signature-Key-Id所选签名密钥 ID;仅签名投递携带
X-Signature签名;仅签名投递携带,见下文
{
  "event_id": "evt_01JX...",
  "event_type": "task.succeeded",
  "event_time": "2026-06-11T10:30:00.123456Z",
  "task": { "task_id": "task_01JX...", "status": "succeeded", "output": { "...": "..." } }
}

task 即完整 Task envelope

选择签名或无签名投递

回调签名密钥与 API Key 完全独立。在 Console → 开发者 → Webhook 中管理,也可调用 /account/callback-signing-keys 接口创建、轮换和停用。 明文密钥只在创建或轮换签名密钥时展示一次。

  • 只传 callback_url:无签名投递,不携带两个签名 Header;
  • 同时传 callback_url 和有效的 callback_signing_key_id:签名投递;
  • 所选密钥不可用时投递失败,Beatra 绝不会静默降级为无签名投递。

验证签名投递

X-Signature: t=<unix_ts>,v1=<hex>
v1 = HMAC-SHA256( secret, "<unix_ts>." + raw_body )
import hmac, hashlib, time
 
def verify(signature_header: str, raw_body: bytes, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in signature_header.split(","))
    ts, sig = int(parts["t"]), parts["v1"]
    if abs(time.time() - ts) > 300:          # 拒绝 5 分钟以外的时间戳
        return False
    expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

注意:必须对原始请求体字节计算,先解析再序列化会导致验签失败。

重试策略

投递失败(非 2xx 或超时)后,按以下间隔重试;总计 6 次投递(1 次首投 + 5 次重试):

1 分钟 → 5 分钟 → 30 分钟 → 2 小时 → 12 小时
  • 重试期间 X-Event-Id 不变,请按它去重;
  • 投递失败不影响任务本身——任务已是终态,随时可轮询兜底;
  • 每次投递的状态可在 envelope 的 callback 字段(pending / dispatching / delivered / retrying / failedattempt_countlast_error)和控制台回调日志中查看。

On this page