> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Webhook 回调

> 创建 Webhook 端点，按需接收 BeatAPI 任务完成回调。

`POST https://api.beatapi.io/v1/webhooks`

创建 Webhook 端点，按需接收 BeatAPI 任务完成回调。

## 鉴权

`Authorization`   `string`   **必填**

在 `Authorization` 请求头中以 Bearer 令牌发送服务端 API 密钥，可在[控制台](https://beatapi.io/dashboard)创建。

```
Authorization: Bearer <BEATAPI_API_KEY>
```

永久 API 密钥只能保存在可信服务端，不能写入浏览器、移动端、公开脚本、日志或截图。请求体必须使用 `Content-Type: application/json`。请按当前接口文档处理重试，不要对结果不明的创建请求盲目重发。

## 请求体

字段名、类型和枚举值保留英文原样，用途和限制用中文说明。

`url`   `string`   **必填**

接收 BeatAPI 任务事件的公网 HTTPS 回调 URL。

**取值与默认值:** 格式 `uri`

---

`description`   `string`   **选填**

用于说明对象、主体或端点用途的文字。

---

`events`   `string[]`   **选填**

该 Webhook 端点要订阅的事件列表。

**取值与默认值:** 可选值 `task.succeeded`、`task.failed`

## 响应

成功请求返回 HTTP `201`，响应体如下。

```json
{
  "data": {
    "id": "wh_9aBcD",
    "object": "webhook_endpoint",
    "url": "https://example.com/beatapi-webhook",
    "description": "Production webhook",
    "events": [
      "task.succeeded",
      "task.failed"
    ],
    "status": "active",
    "secret": "whsec_example_store_this_once",
    "created_at": 1782210000,
    "updated_at": 1782210000
  }
}
```

## 验证回调签名

BeatAPI 每次投递都会发送 `x-beatapi-event`、`x-beatapi-timestamp` 和 `x-beatapi-signature`。请对下面的内容计算十六进制 HMAC-SHA256。

`timestamp + "." + raw_request_body`

使用创建端点时返回的 `secret`。必须在 JSON 解析前按原始字节计算签名，使用常量时间比较，并拒绝超过 5 分钟的时间戳。

## 管理端点

* `GET /v1/webhooks`：列出 Webhook 端点。
* `GET /v1/webhooks/{id}`：查询 Webhook 端点。
* `PATCH /v1/webhooks/{id}`：更新 Webhook 端点。
* `DELETE /v1/webhooks/{id}`：删除 Webhook 端点。

## 下一步

解析回调数据前验证签名。投递延迟或失败时，`GET /v1/tasks/{task_id}` 的查询结果仍然是任务状态真源。

## 错误

| 状态码   | 含义与处理方式                                                                                                    |
| ----- | ---------------------------------------------------------------------------------------------------------- |
| `400` | JSON 格式错误，或字段、取值、参数组合不被接受（`bad_request`，错误信息会点名字段）；输入未通过内容审核时为 `content_policy_violation`。修正后再请求，原样重试仍会失败。 |
| `401` | 未提供 API 密钥（`missing_api_key`），或密钥错误、已过期、已停用或额度已用尽（`invalid_api_key`，错误信息会说明是哪一种）。不要原样重试。                   |
| `429` | 请求过于频繁（`rate_limit_exceeded`，含免费模型限额）。按 `Retry-After`（也在 `error.retry_after_seconds`）等待后重试。                |
| `500` | 内部异常（`internal_error`），可以重试；持续出现时请保留 `request_id` 联系支持。                                                    |