Webhooks
Docsbookは、ワークスペース内で発生するイベントについてシステムに通知できます — 新しいコンテンツのインデックス作成、必要な翻訳、チャットでの質問、トラフィックの異常 などです。各Webhookはタイプ付きです。18種類の特定のイベントのいずれかを購読すると、 Docsbookはそのイベントが正確に発生したときにのみ、URLへPOSTします。
Webhookの登録とその配信の受信によって、プロジェクトの残高が消費されることはありません。 手動で再送またはテストする配信は、Docsbookがお客様に代わって行う送信呼び出しであるため、 エグレスとして計上されます。
仕組み#
event_type、url、および任意のsecretを使用してWebhookを登録します。- イベントが発生すると、Docsbookは配信をキューに追加します(アウトボックスパターン)。
- ワーカー(Vercel cron、毎分)がJSON本文をURLにPOSTします。
- 指数バックオフ(1秒、10秒、60秒)で最大3回試行します。
リクエスト形式#
POST https://your-url.example.com
Content-Type: application/json
User-Agent: Docsbook-Webhooks/1.0
X-Docsbook-Event: content.indexed
X-Docsbook-Signature-256: sha256=<hex hmac of body>
X-Docsbook-Delivery: 12345
X-Docsbook-Attempt: 1{
"event": "content.indexed",
"workspace_id": 42,
"occurred_at": "2026-05-23T12:34:56.000Z",
"data": { /* event-specific payload */ }
}署名の検証#
import crypto from "node:crypto"
const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex")
if (expected !== req.headers["x-docsbook-signature-256"]) reject()2xxレスポンス = 配信済み。それ以外の場合は、試行回数の上限に達するまで再試行されます。
ワークスペースが発行する内容を確認する#
管理画面のフィードパネルには、ワークスペースが生成したすべてのイベントが新しい順に表示されます — アラートが監視していなかったイベントも含まれます。また、ワークスペースに対して行われたすべての MCP ツール呼び出しも表示されます。フィードが埋まっていく様子を確認するために、Webhook を登録しておく必要はありません 。これが重要な点です。通知対象を決める前に、ドキュメントが実際にどのイベントを発行しているかを確認できるからです。フィードはライブで更新されます。表示している間は数秒ごとに自動更新されるため、選択する期間も、再読み込みを覚えておく必要もありません。
フィードを選ぶ#
フィードセクションを開くとカードのページが表示されます。各フィードにつき1枚のカードがあり、そのフィードに何が含まれているかを説明する行と、最後には自分でフィードを作成カードがあります。カードを開くと、そのフィード自体に切り替わります。上部にタイトルや戻るリンクはありません。カードを選んでここに移動したため、戻るにはサイドバーのフィード行を使います。
同じフィードはサイドバーのそのセクションの下にも行として表示されるため、読んでいるページを離れずにフィードを切り替えられます。ただし、このリストは最初は閉じた状態です。フィード行にカーソルを合わせると、アイコンがシェブロンに変わります。それをクリックすると、最近開いた順に最大5件のフィードが表示され、残りについてはさらにN件を表示が表示されます。Docsbookは、次に戻ってきたときにリストを開いたままにしていたかどうかを記憶しています。空のフィルターから新しいリストを作成する+は、その行とギャラリー内のカードの両方にあります。
組み込みのフィードは7つあるため、自分で何も保存していなくても、初回訪問時から開けるものがあります。閲覧者イベント(ドキュメントを読んだ人が行ったすべての操作 — 読まれたページ、実行された検索、AIへの質問、送信されたフィードバック)、翻訳(生成されたすべての言語、古くなった言語、まだ必要な言語)、言語イベント(閲覧者がドキュメントをどの言語に切り替えたか)、チャットイベント(AIアシスタントに寄せられた質問、回答できなかった質問、低評価を受けた回答)、閲覧者フィードバック(ページまたは回答に対する低評価やコメント)、MCP呼び出し(エージェントが行った、計測対象となるすべての呼び出し)、そしてすべてのイベントです。これはフィルターなしのすべてのイベントで、名前付きのフィードのどれにも当てはまらない場合に使うものなので、リストの最後にあります。閲覧者イベント、言語イベント、MCP呼び出しは、購読するのではなく読むためのフィードです。これらのイベントにはアラートを関連付けられないためです。残りの4つは、通知先として指定できるものです。7つすべてが保存済みリストではなく開始時のフィルターであるため、削除することはできず、直接何かを関連付けることもできません。いずれかを絞り込み、リストとして保存すると、自分で作成したフィードになり、独自の行として表示されます。これが、アラートを関連付けられる形式です。
フィードを読む#
フィードは日ごとのセクションに分かれて表示され、各項目は1行です。イベントの原因となった読者のアバター(プラン、使用状況、MCPイベントには帰属先がないため表示されません)、種類を示す色付きタイル、イベント名、1行の概要、送信先が並びます。ステータス、イベント種別、送信先は小さなグリフで表示され、単語の説明はポップオーバーでクリックして確認できるため、全体が1行に収まります。時刻は、この上のセクションですでに日付が示されているため、時刻のみ表示されます。行をクリックすると、その場で展開され、イベントの詳細(各配信試行とそのレスポンス、リプレイ、未加工のペイロード)がすべて表示されます。イベントには単一のステータスが付与されます。これは各配信の結果を集約したもので、最も悪い結果が優先されます。
| ステータス | 意味 |
|---|---|
delivered |
すべての送信先が受け付けました。 |
pending |
キューに入りました。ワーカーはまだ試行していません。 |
retrying |
送信先が拒否しましたが、試行回数の上限には達していません。 |
failed |
送信先が拒否し、試行回数の上限に達しました。 |
not sent |
発生しましたが、これを購読しているアラートはありませんでした。 |
フィード内のMCPツール呼び出し#
フィードには、ドキュメントがディスパッチしたイベントとともに、このワークスペースに対してエージェントが行ったすべてのMCPツール呼び出しも表示されます。呼び出しごとに1行で、呼び出したツール、成功したかどうか、所要時間、MCP料金表の定価でのコストが表示されます。失敗した呼び出しにはその旨が示されます。サーバーの説明、プロジェクトの一覧表示、プロジェクトの作成など、特定のプロジェクトに関するものではない呼び出しは、プロジェクトではなくアカウントに属するため、どのプロジェクトのフィードにも表示されません。
これらはデフォルトで表示され、オンに切り替える必要はありません。イベントを追加ピッカーでは、専用のMCP呼び出しセクションに、ツール名ではなく呼び出しの請求クラス(mcp.read、mcp.write、mcp.query、mcp.egress、mcp.generate、mcp.agent)でフィルタリングされて表示されます。請求クラスはコストに影響する軸であり、新しいツールが提供されても機能し続けます。ツール自体の名前はすべての行とすべてのペイロードに含まれているため、1つのツールに絞り込むにはペイロードを検索するだけです。無料の呼び出し(get_info、find_skill、find_widget、その他の検出処理)は課金対象として計測されないため、行は表示されません。
ツール呼び出しがどこかに転送されたことはないため、未送信と表示され、閲覧者のアクティビティと同様に、宛先または配信ステータスでフィルタリングすると直ちに表示対象から外れます。訪問者を固定した場合も同様に表示対象から外れます。トークンを保持するエージェントは読者の1人ではなく、その呼び出しを誰かの閲覧として数えるのは誤りだからです。
フィードを絞り込む#
イベントの種類、ステータス、送信先、訪問者、達成済みの目標、またはペイロード内のどこにでも一致する自由テキストによってフィードを絞り込めます。フィードの上にはタイトルなしでツールバーの行が1つ表示されます。最初の5つのファセットはアイコンボタンです。ホバーまたはフォーカスすると名前が表示され、設定するとその値自体で埋められ、その値をクリックすると再度編集できます。自由テキストは、先に開くファセットではなく、その行の末尾に常に表示される独立した検索ボックスです。訪問者フィルターはアナリティクスから1クリックで利用できます。そこで読者を開けば、その人が行ったすべての操作に直接移動できます。また、フィード内の行にあるアバターをクリックするか、IDを手動で貼り付けることでも利用できます。読者をピン留めすると、フィードが検索する範囲が広がります。ドキュメントが送信したイベントに加えて、その読者自身のサイト上でのアクティビティ、つまり読んだページ、検索した内容、尋ねたことも取得します。そのため、ピン留めされたフィードには、その読者が行ったすべてのことが表示され、アラートを発生させられた部分だけに限られません。また、フィードの上には、その読者が誰なのかを示すカードも表示されます。読んだ場所、使用したデバイス、システムとブラウザー、読んだ言語、何度も訪れているページ、ドキュメントの閲覧に費やした合計時間、達成した目標、現在の価値と今後見込まれる価値が表示されます。このカードは1人の読者だけをピン留めした場合にのみ表示されます。目標フィルターは集団を対象とするものであり、集団の平均として示された1つの国や1つのブラウザーは誰のことも表さないためです。フィルターを保存するとイベントリストになり、フィードを絞り込むことと、通知対象を定義することが同じ操作になります。テスト用の ping は他のイベントと同様にフィードに表示され、再送信はそれが属するイベントの下に別の試行として表示されます。エクスポートでは、表示中の内容をそのまま、フィルターを適用した状態で、時間による制限なしにCSV、JSON、またはNDJSONとしてダウンロードできます。時間による制限がないのは、フィード自体に時間範囲がないためです。フィードはライブであり、コピー元のビューより狭い範囲のファイルは、ファイルがないよりも悪いからです。これは同じツールバーの行の末尾に、プロンプトを設定およびアラートを設定と並んで配置されています。これら3つのコントロールは、1つのイベントではなくビュー全体に作用します。
フィードでプロンプトを実行する#
アラートはフィードのイベントをユーザーに転送します。同じ行の隣にあるプロンプトを設定を使うと、代わりにそれらをアシスタントに渡せます。プロンプトを選ぶと、このフィードに何かが届くたびに、誰も監視していなくても自動的に実行されます。ボタンには件数が表示されるため、何かがあるフィードが何もないフィードのように見えることはありません。また、有効にした各プロンプトには送信先チップの横にチップが表示されます。実行中は塗りつぶし、一時停止中は中抜きになり、ツールチップには最後の実行時刻が表示されます。
チップをクリックしても設定は開きません。開くのは、プロンプトがこれまで行ってきた会話です。つまり、このフィードに変化があった前回、実際に何を行ったかを記録したトランスクリプトで、アシスタントの「トリガー」グループにあります。プロンプトが単にオンになっているだけでなく、実際に機能していることを確認できるのは、これだけです。
フィードを監視する対象は保存済みのフィードです。そのため、絞り込んだもののまだ保存していないビューにはその旨が表示され、リストとして保存するよう案内されます。同じ有効化操作は反対側からも利用できます。MCPツール専用ページのスケジュールまたはイベントでパネルには、個々のイベントの上にフィードが一覧表示されます。また、フィードを削除すると、それを監視していたものは無効になりますが、有効化された呼び出し自体は削除されません。
すべてにかかった費用#
フィードの各行には料金が付いていますが、1行ずつ見ても、誰も合計できる列にはなりません。 使用状況を見るをサイドバーの残高カードで選ぶと、ストリームが合計に切り替わります。このプロジェクトの 資金が期間中に何に使われたかを、金額の高い順に3つのセクションで表示します。これはフィード自体のツールバーにはありません。 表示される数値は、見ているフィードではなくプロジェクト全体に関するものだからです。
| セクション | 1行あたり | 数値の内容 |
|---|---|---|
| AI & トークン | サーフェスとモデル | 各AI回答、翻訳、インデックス作成の実行に設定された料金 |
| MCPツール呼び出し | ツール | そのツールが実際に行った呼び出しの定価 |
| 記録されたイベント | イベントタイプ | 料金表に基づく、そのトラフィックの記録費用 |
最初の2つは課金対象です。その金額はプロジェクトの残高から差し引かれます。3つ目は課金対象ではありません。
イベントには、トラフィックが見えなくならないよう料金が設定されていますが、イベント分が差し引かれることはありません。したがって、2つの合計は
異なる2つの語の下に、2つの数値として表示されます。また、3つすべてを1つの数字でまとめると、誰も受け取っていない金額まで請求することになるため、各セクションには charged
または not charged バッジが付いています。
24時間、7日間、30日間のいずれかの期間を選択します。それより長い期間がないのは、 それ以上遡って確認できないためです。閲覧者分析は30日間保持され、AI台帳もそれに合わせて整理されるため、 90日間のボタンを用意すると、30日間分の結果を誤ったラベルで表示することになります。
ここでエクスポートを選ぶと、内訳自体をCSVで取得できます。モデル、ツール、イベントタイプごとに1行で、件数と合計可能な単純な数値としての費用、 その行が課金対象かどうかを示す列が含まれます。また、表示中の期間を範囲とした、その内訳の元となる生イベントも取得できます。
サイドバーの残高通知から使用状況を見るを開いた場合も、同じ画面が表示されます。これは、このプロジェクトの残高が少なくなったときに警告するカードです。 チャージはアカウントメニューの残高ブロックから行えます。一方は残高がどれだけ残っているかを答え、こちらは何に使われたかを答えます。
通知先:イベントの送信先#
通知先とは、イベントの送信先、つまりチャンネル、そのURL、認証情報をまとめたもので、そこから送信されるイベントとは別に存在します。通知先は一度作成します — タイトル行のアラートを設定、または通知先を追加の下部にある新しい通知先から作成できます — その後、送信先として使用するイベントリストをいくつでも選択して追加します。3つのリストから1つのSlackチャンネルに送信する場合も、通知先は1つであり、署名シークレットも1つです。停止や削除も1か所で行えます。
表示中のリストですでに機能している通知先は、フィルターチップの横に、それぞれ独自のラベル付きチップとして表示されます — 各チップにはチャンネル本来のアイコン、名前、そして無効になっている場合はpausedが表示されます。チップをクリックするとその通知先が開くため、フィードを離れずにリストの送信先を確認したり、変更したりできます。別のリストで機能している通知先 — またはまだどのリストでも使われていない通知先(新しく作成された通知先はすべてここから始まります) — には、通知先を追加メニューからアクセスできます。各行にはチェックボックスの横に編集コントロールがあります。
リストの選択を解除すると、その通知先はそのリストでは機能しなくなります。最後のリストの選択を解除すると、送信先は残りますが、どのリストにも関連付けられず、再びリストを指定するまで何も配信しません。イベントリストを削除した場合も、そのリストで機能していた通知先は同じ状態になります — リストを失っても、サブスクリプションの範囲が広がることはありません。
通知先を設定できるのは保存済みリストのみです。組み込みフィード(その中にはすべてのイベントも含まれます)はリストではなくフィルターなので、まず目的のものを自分のフィードとして保存してください。
イベントカタログ#
Docsbook ワークスペースは、型付きイベントを18種類発行します。以下の各行では、X-Docsbook-Event ヘッダーおよび本文の event フィールドに表示されるイベント名をそのまま示し、その data オブジェクトが持つフィールドを記載しています。
| イベント | ペイロードフィールド |
|---|---|
content.indexed |
pages_count, relations_count, indexed_at |
content.outdated (非推奨 — 自動的には発行されません) |
last_indexed_at, repo_head_sha |
translation.needed |
source_path, language |
translation.completed |
source_path, language, origin |
translation.outdated |
source_path, language, source_hash_changed |
chat.question_asked |
question, answered, chat_id |
chat.no_answer |
question, chat_id |
chat.negative_feedback |
chat_id, question, answer |
search.no_results |
query |
search.popular |
query, count_24h |
traffic.spike (高度なイベント) |
path, views, baseline |
traffic.drop (高度なイベント) |
path, views, baseline |
feedback.received |
path, rating, comment |
plan.upgraded |
from, to |
plan.downgraded |
from, to |
usage.limit_approaching |
metric(ai|translation)、used、limit |
usage.overage_limit_reached |
workspace_id, overage_spent_cents, overage_limit_cents |
mcp.tool_called (高度なイベント) |
tool_name, args |
18種類のうち3種類には高度なイベントという印が付いています — traffic.spike、traffic.drop、mcp.tool_called。これらは、1つのアクションによって直接発行されるのではなく、ベースラインまたは計測されたアクティビティから派生します。
Webhook の登録#
REST経由#
curl -X POST https://docsbook.io/api/webhooks \
-H "Content-Type: application/json" \
-d '{"workspace_id": 42, "event_type": "content.indexed", "url": "https://you.example.com/hook"}'レスポンスにはsecretが1回だけ含まれます — 保存してください。
event_typeでは、イベント名にドット形式(このページ全体で使用されているcontent.indexed)とアンダースコア形式(content_indexed)のどちらも使用できます。どちらも同じサブスクリプションを登録します。
任意のAuthorizationヘッダー#
一部の受信側(たとえばClaude CodeのルーチントリガーURL)では、HMAC署名検証とは別に、すべてのリクエストで独自のベアラートークンが必要です。Webhookの作成時に
auth_header を渡すと、Docsbookはすべての配信でそれを
Authorization ヘッダーとしてそのまま送信します。
curl -X POST https://docsbook.io/api/webhooks \
-H "Content-Type: application/json" \
-d '{"workspace_id": 42, "event_type": "content.indexed", "url": "https://you.example.com/hook", "auth_header": "Bearer sk-..."}'値にスペースがない場合は Bearer <value> として送信され、すでにスキーム(例: Bearer sk-...)が含まれている場合は変更せずに送信されます。
MCP経由#
各イベントには専用のMCPツールがあるため、AIエージェントは文字列を選択せずに特定の通知ストリームを購読できます:
register_webhook_content_indexed(workspace_id: 42, url: "https://YOUR_ENDPOINT")
register_webhook_translation_needed(repo: "owner/repo", url: "https://YOUR_ENDPOINT")
register_webhook_traffic_spike(workspace_id: 42, url: "https://YOUR_ENDPOINT")その他のMCPツールと、各呼び出しが計上される請求クラス:
| ツール | 請求 | 動作 |
|---|---|---|
list_webhooks(workspace_id) |
読み取り | ワークスペースに登録されているWebhookを一覧表示 |
unregister_webhook(webhook_id) |
書き込み | 1つのサブスクリプションを削除 |
test_webhook(webhook_id) |
送信 | 登録されたURLへの合成pingをキューに追加 |
list_webhook_deliveries(webhook_id) |
分析 | ステータス、再試行回数、ペイロードを含む配信履歴 |
replay_webhook_delivery(delivery_id) |
送信 | 過去の配信を1件再配信 |
RESTエンドポイント#
GET /api/webhooks?workspace_id=X— 一覧表示POST /api/webhooks— 作成PATCH /api/webhooks/:id— 名前変更、停止/再開、または別のイベントリストへの再ポイントPOST /api/webhooks/:id/attach—{ "list_id": N }、同じ宛先(同じURL、同じシークレット)からもう1つのリストを提供DELETE /api/webhooks/:id— 削除POST /api/webhooks/:id/test— pingをテストGET /api/webhooks/:id/deliveries— 最近の配信POST /api/webhook-deliveries/:id/replay— 既存の配信を再キューイング
リトライと失敗のセマンティクス#
- ワーカーは Vercel cron を介して毎分実行されます。
- 配信は最大 3 回試行されます。
- バックオフは行の
created_atから適用されます: 1s、10s、60s。 - 3 回目の失敗後 →
status = "failed"。再試行するにはreplay_webhook_deliveryを使用します。 - レスポンスコードと(切り詰められた)本文は、すべての配信行に保存されます。
関連情報#
- MCP ツールリファレンス —
register_webhook_<event>ツールと、サーバー上のその他すべてのツール - MCP サーバー概要 — クライアントの接続方法と、呼び出しの料金を算出する料金表
- トラッキング対象イベントリファレンス — これらのイベントのいくつかを生み出す読者の操作
- 分析概要 — 同じアクティビティをストリームではなくレポートとして確認する方法