---
title: "webhook"
description: "XID イベントをサブスクライブし、ユーザー、セッション、組織が変更されると署名付き HTTP ペイロードを受信します。"
locale: "ja"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/ja/llms.txt
> Use this file to discover all available pages before exploring further.

# webhook

## イベント命名規則

イベントは `<object>.<action>` パターンに従います。各イベントは安定した type 名、一意の `svix-id`、ISO 8601 タイムスタンプを持ちます。

| オブジェクト | 操作 |
| --- | --- |
| `user` | created, updated, deleted |
| `session` | created, ended, removed, revoked |
| `organization` | created, updated, deleted |
| `organizationMembership` | created, updated, deleted |
| `organizationInvitation` | created, accepted, revoked |
| `organizationDomain` | created, updated, deleted, verified, verification\_failed |
| `authentication` | password\_succeeded, password\_failed, passkey\_succeeded, passkey\_failed, mfa\_succeeded, mfa\_failed, oauth\_succeeded, oauth\_failed, sso\_succeeded, sso\_failed, magic\_auth\_succeeded, magic\_auth\_failed, email\_verification\_succeeded, email\_verification\_failed, radar\_risk\_detected |
| `connection` | activated, deactivated, deleted, saml\_certificate\_renewed, renewal\_required |
| `dsync` | activated, deleted, user.created, user.updated, user.deleted, group.created, group.updated, group.deleted, group.user\_added, group.user\_removed |
| `role` | created, updated, deleted |
| `permission` | created, updated, deleted |
| `email` | created（開発者が送信を引き継ぐ際に発火） |
| `sms` | created（開発者が送信を引き継ぐ際に発火） |
| `billing` | subscription.created, subscription.updated, paymentAttempt.succeeded, paymentAttempt.failed |

## ペイロード構造

すべての webhook 配信は `Content-Type: application/json` の HTTP POST です。ボディには `type`、`data`、トップレベルのメタデータヘッダーが含まれます。

```json
{
  "type": "user.created",
  "data": {
"id": "usr_01abc",
"email_addresses": [{ "email_address": "alice@example.com" }],
"created_at": 1700000000000
  }
}
```

## 署名検証

XID はすべての配信を HMAC-SHA256 で署名します。ペイロードを処理する前に署名を検証してください。リプレイ攻撃を防ぐため、5 分以上経過した配信は拒否してください。

| ヘッダー | 説明 |
| --- | --- |
| `svix-id` | 一意のメッセージ ID。再試行された配信の重複排除に使用してください。 |
| `svix-timestamp` | メッセージが送信された時刻（Unix 秒）。 |
| `svix-signature` | `${svix-id}.${svix-timestamp}.${raw-body}` をエンドポイント署名シークレットで Base64 エンコードした HMAC-SHA256。 |

```js
// Node.js / Cloudflare Workers example
async function verifyWebhook(request, secret) {
  const svixId = request.headers.get('svix-id')
  const svixTimestamp = request.headers.get('svix-timestamp')
  const svixSignature = request.headers.get('svix-signature')
  const body = await request.text()

  // Reject messages older than 5 minutes
  const ts = Number(svixTimestamp)
  if (Math.abs(Date.now() / 1000 - ts) > 300) {
throw new Error('webhook timestamp out of tolerance')
  }

  const signedContent = `${svixId}.${svixTimestamp}.${body}`
  const keyData = Uint8Array.from(atob(secret), c => c.charCodeAt(0))
  const key = await crypto.subtle.importKey(
'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
  )
  const msgData = new TextEncoder().encode(signedContent)

  // svix-signature may contain multiple comma-separated values
  for (const sig of svixSignature.split(' ')) {
const prefix = 'v1,'
if (!sig.startsWith(prefix)) continue
const sigBytes = Uint8Array.from(atob(sig.slice(prefix.length)), c => c.charCodeAt(0))
const valid = await crypto.subtle.verify('HMAC', key, sigBytes, msgData)
if (valid) return JSON.parse(body)
  }
  throw new Error('invalid webhook signature')
}
```

## 再試行とデッドレター

- 配信失敗は指数バックオフで再試行されます。最大再試行回数を超えると、メッセージは手動確認用に D1 のデッドレターストアに書き込まれます。
- 配信は Cloudflare Queues を通じて認証パスから切り離されています。エンドポイントが遅かったり使用不能でも、ログインのレイテンシーには影響しません。
- `svix-id` ヘッダーを使って受信側で配信を重複排除してください。再試行は元の試行と同じ `svix-id` を持ちます。

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

## 手動リプレイ

`POST /v1/webhooks/:endpointId/replay` を使ってメッセージ ID または時間範囲でイベントをリプレイします。リプレイされたイベントは新しい `svix-id` 値を持ちますが、元の `type` と `data` は保持されます。

```shell
# Replay events from the last hour
curl -X POST https://xid.dev/v1/webhooks/whe_xxx/replay \
  -H 'Authorization: Bearer sk_live_xxx' \
  -H 'Content-Type: application/json' \
  -d '{ "since": "2024-01-01T00:00:00Z", "until": "2024-01-01T01:00:00Z" }'
```

## Events API

push webhook に加え、XID は `GET /v1/events` でカーソルページネーション付きの順序付き不変イベントストリームを公開します。ストリームを取得することで、webhook 再試行の間にイベントを取りこぼすことなく確実な同期を構築できます。

```shell
curl 'https://xid.dev/v1/events?limit=100&after=evt_xxx' \
  -H 'Authorization: Bearer sk_live_xxx'
```

Source: https://xid.dev/ja/webhooks/index.mdx
