> 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

> BeatAPI タスクの完了通知を必要に応じて受け取るための、Webhook エンドポイントを作成します。

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

BeatAPI タスクの完了通知を必要に応じて受け取るための、Webhook エンドポイントを作成します。

## 認証

`Authorization`   `string`   **必須**

BeatAPI の API キーを Bearer トークンとして送信します。API キーは[ダッシュボード](https://beatapi.io/dashboard)で作成できます。

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

通常の API キーは、信頼できるサーバーで管理してください。リクエストボディには `Content-Type: application/json` が必要です。対応するエンドポイントでは `Idempotency-Key` は任意ですが、同一のリクエストボディで安全に再試行するために指定を推奨します。

## リクエストボディ

`url`   `string`   **必須**

BeatAPI のタスクイベントを受信する、公開 HTTPS コールバック URL です。localhost やプライベートネットワークの URL は使用しないでください。

**形式:** `uri`

---

`description`   `string`   **任意**

アカウント内でエンドポイントを識別するための、任意の内部ラベルです。

---

`events`   `string[]`   **任意**

通知するタスクイベントです。省略すると、`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 を計算し、16 進数の署名値を求めてください。

`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`。理由はメッセージに記載されます）。`Authorization: Bearer <key>` で送信してください。`sk-` 接頭辞の有無にかかわらず使えます。そのまま再試行しないでください。      |
| `429`    | リクエスト数が上限を超えています（無料モデルの制限を含む `rate_limit_exceeded`）、または同時処理中のタスクが多すぎます（`user_concurrency_exceeded`）。`Retry-After` の秒数だけ待ってから再試行できます。同じ値は `error.retry_after_seconds` にも含まれます。 |
| `500`    | 予期しない内部エラーです（`internal_error`）。再試行できます。繰り返し発生する場合は、`request_id` を控えてサポートに連絡してください。                                                                                            |