---
title: "Webhooks"
description: "通过签名的 HTTP 交付订阅已实施的用户、组织、成员资格、邀请和 SAML 证书事件。"
locale: "zh-Hans"
---

> Documentation Index
> Fetch the relevant documentation index at: https://vonvon.id/zh-hans/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

## 事件命名

已实现的事件遵循 `<object>.<action>` 模式。vonvon-webhook-event header 和正文 type 携带准确的事件名称；每次投递还具有唯一的 `svix-id`。

| 对象 | 操作 |
| --- | --- |
| `user` | 已创建、已更新、已删除、已恢复、已封禁、已解封、已停用 |
| `organization` | 已创建、已更新、已删除、已恢复 |
| `organization.auth_policy` | 已更新 |
| `organization.delivery_channels` | 已更新 |
| `organization.social_providers` | 已更新 |
| `organization.outbound_saml_app` | 已创建、已删除 |
| `organization.scim_target` | 已创建、已删除 |
| `organizationMembership` | 已创建、已更新、已删除、已恢复 |
| `organizationInvitation` | created, accepted, revoked |
| `connection` | saml\_certificate\_renewed |
| `user.*` | 所有已实现的用户事件的订阅通配符。 |
| `organization.*` | 用于订阅所有已实现组织事件的通配符，包括点分子事件。 |
| `organizationMembership.*` | 用于订阅所有已实现组织成员关系事件的通配符。 |
| `*` | 每个已实施事件的订阅通配符。 |

## payload 结构

每次 Webhook 投递都是带有 `Content-Type: application/json` 的 HTTP POST。正文包含准确的事件 `type` 及其 `data`；svix 元数据通过请求 header 传递。

```json
{
  "type": "user.created",
  "data": {
"userId": "user_01abc"
  }
}
```

## 签名验证

Vonvon 对每次投递使用 HMAC-SHA256 签名。在处理 payload 前请先验证签名。拒绝 5 分钟前的投递以防重放攻击。

| 请求头 | 描述 |
| --- | --- |
| `svix-id` | 唯一消息 ID。用于对重试投递去重。 |
| `svix-timestamp` | 消息发送时的 Unix 时间戳（秒）。 |
| `svix-signature` | svix-signature header 以字面量前缀 v1, 开头，随后是使用端点签名 secret 对 `${svix-id}.${svix-timestamp}.${raw-body}` 计算得到的 Base64 编码 HMAC-SHA256。 |

```ts
import { verifyWebhook } from '@vonvon-kit/backend'

const result = await verifyWebhook(request, {
  secret: env.VONVON_WEBHOOK_SECRET,
})
if (!result.ok) {
  return new Response('Invalid webhook', { status: 400 })
}
const { type, data } = result.value.payload
```

## 重试与死信

- 投递使用指数退避重试，最终进入 dead 状态。队列重试耗尽后，原始消息会作为加密死信记录持久化，供 Instance Manager 检查和重放。
- 交付通过 Cloudflare Queues 与认证路径解耦。端点缓慢或不可用不会影响登录延迟。
- 使用 `svix-id` 请求头在接收端去重。重试的投递与原始尝试携带相同的 `svix-id`。

```mermaid
flowchart LR
  Vonvon --> Queue
  Queue -->|HTTPS| Endpoint
  Endpoint -->|2xx| ACK
  Endpoint -->|non-2xx| Retry
  Retry --> Queue
  Retry -->|max_retries| dlq["D1 DLQ"]
```

## 端点恢复

使用 `POST /v1/webhooks/:id/restore` 重新激活已删除的端点，使用 `POST /v1/webhooks/:id/rotate-secret` 替换其签名 secret。新的 `signing_secret` 仅返回一次。尚未实现按投递 ID 或`时间范围`进行产品级重放。

```shell
curl -X POST https://vonvon.id/v1/webhooks/webhook_xxx/rotate-secret \
  -H 'Authorization: Bearer sk_live_xxx'
```

## 投递历史边界

Vonvon 不提供拉取式 Events API。使用 `GET /v1/webhooks` 管理订阅；投递状态和队列死信重放是供 Instance Manager 使用的运维界面，不是租户事件流。

```shell
curl 'https://vonvon.id/v1/webhooks?limit=100' \
  -H 'Authorization: Bearer sk_live_xxx'
```

Source: https://vonvon.id/zh-hans/webhooks/index.mdx
