> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hitheo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 创建 Webhook

> 注册一个新的 Webhook 端点以接收实时事件通知。

## 请求

<ParamField body="url" type="string" required>
  用于接收事件推送的 HTTPS URL。生产环境中必须使用 `https://`。该地址会经过 SSRF 校验——私有 IP、云元数据端点以及非 HTTP 协议均会被拦截。
</ParamField>

<ParamField body="event_types" type="string[]" required>
  要订阅的事件类型数组。使用 `"*"` 订阅所有事件，或指定具体类型，如 `"completion.created"`。

  有效类型：`completion.created`、`job.completed`、`job.failed`、`workflow.completed`、`workflow.failed`、`skill.installed`、`skill.uninstalled`、`skill.submitted`、`skill.approved`、`skill.rejected`、`skill.suspended`、`connector.created`、`connector.status_changed`、`credits.low`、`key.created`、`key.revoked`、`*`
</ParamField>

<ParamField body="secret" type="string" optional>
  可选的自定义签名密钥（16–256 个字符）。若省略，将生成一个密码学随机的 32 字节十六进制密钥。
</ParamField>

<ParamField body="description" type="string" optional>
  Webhook 的可选描述（最多 256 个字符）。
</ParamField>

## 响应

<ResponseField name="id" type="string">
  该 Webhook 的唯一 UUID。
</ResponseField>

<ResponseField name="url" type="string">
  已注册的端点 URL。
</ResponseField>

<ResponseField name="event_types" type="string[]">
  已订阅的事件类型。
</ResponseField>

<ResponseField name="enabled" type="boolean">
  创建时始终为 `true`。
</ResponseField>

<ResponseField name="signing_secret" type="string">
  HMAC-SHA256 签名密钥。**仅显示一次——请立即保存。** 用于在你的服务器上验证 Webhook 签名。
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 时间戳。
</ResponseField>

## 身份验证

需要具有 `completions` 权限范围的组织级 API 密钥。

```bash theme={null}
Authorization: Bearer theo_sk_...
```

## 示例

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://www.hitheo.ai/api/v1/webhooks \
    -H "Authorization: Bearer $THEO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://your-server.com/webhooks/theo",
      "event_types": ["completion.created", "job.completed"]
    }'
  ```

  ```typescript SDK theme={null}
  import Theo from "@hitheo/sdk";

  const theo = new Theo({ apiKey: process.env.THEO_API_KEY });

  const webhook = await theo.createWebhook({
    url: "https://your-server.com/webhooks/theo",
    event_types: ["completion.created", "job.completed"],
  });

  // Save webhook.signing_secret — shown once only
  console.log("Signing secret:", webhook.signing_secret);
  ```
</CodeGroup>

### 响应

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "url": "https://your-server.com/webhooks/theo",
  "event_types": ["completion.created", "job.completed"],
  "enabled": true,
  "signing_secret": "8f3a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1",
  "created_at": "2026-04-15T12:00:00.000Z",
  "_note": "Save the signing_secret — it will not be shown again."
}
```

## 限制

* 每个组织可创建的活跃 Webhook 数量有上限。如需更高配额，请联系支持团队。
* URL 必须通过 SSRF 校验（不允许私有 IP，不允许云元数据端点）。
* 生产环境中必须使用 HTTPS。

## 签名验证

每次推送都会包含三个用于验证的请求头：

```
Theo-Webhook-Signature: v1=<hex>
Theo-Webhook-Timestamp: <unix_seconds>
Theo-Webhook-Id: <event_id>
```

验证方式为计算 `HMAC-SHA256(signing_secret, timestamp + "." + raw_body)` 并与签名进行比对。若时间戳与你本地时钟相差超过 5 分钟，应拒绝该请求。

```javascript theme={null}
const crypto = require("crypto");

function verifyWebhook(rawBody, headers, secret) {
  const timestamp = headers["theo-webhook-timestamp"];
  const signature = headers["theo-webhook-signature"];

  // Replay protection
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (age > 300) throw new Error("Timestamp too old");

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const [, hash] = signature.split("=");
  if (hash !== expected) throw new Error("Invalid signature");

  return JSON.parse(rawBody);
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.