Webhook
HMAC 署名付き配信、自動再試行、コンソールからのリプレイ セーフティ ネットを使用して、HTTP 経由でリアルタイムの署名イベントを受信します。
SHA-256 署名要求
webhook シークレットごと、X-Endorsed-Signature として送信
配信タイムアウト
ウィンドウ内で 2xx を返すか、試行は失敗します
最初の試行後の再試行
60秒、5分、15分、1時間、その後6時間
開発者コンソールから
すべての試行を検査し、個々のイベントを再生します
webhookイベントでできること
すべての重要なライフサイクル遷移では、型付きイベントが生成されます。これらを使用して、ポーリングせずに自分のレコードを更新します。
ダウンストリームアクションをトリガーする
エンベロープが完全に署名されたら、CRM を更新したり、プロビジョニングされたリソースを解放したり、独自の製品内で確認を送信したりできます。これらはすべて、API をポーリングすることなく行われます。
同期ドキュメントステータス
データベースを署名ライフサイクル (送信、開封、署名、拒否、期限切れ、無効) と同期させます。遷移ごとに 1 つのイベントがあり、ポーリング ループは必要ありません。
監査とコンプライアンスのログ記録
webhook イベントを独自の監査ストアにフィードします。相関 ID は、すべてのイベントを元の API リクエストにリンクし、完全な追跡可能性を実現します。
失敗した配信を再生する
再試行ラダーを使い果たしたイベントは、開発者コンソールで検査して意図的に再生できる配信不能キューに入れられます。
Webhook イベント参照
webhook を登録し、必要なイベントを選択すると、EndorsedSign が `event`、`tenantId`、`timestamp`、および `data` を含む JSON ペイロードを配信します。イベント名は、webhook 作成呼び出しで送信する文字列と一致します。
| イベントタイプ | 発火時 | キーの「データ」フィールド |
|---|---|---|
| document.created | API 経由でドキュメントをアップロードします | documentId、customerId、externalDocumentId |
| document.sent | 署名リンクが最初の受信者に送信されました | ドキュメントID、顧客ID、チャネル |
| document.viewed | 署名者が署名リンクを開きます | documentId、signerEmail、viewAt |
| document.signed | 個人の署名者がステップを完了しました | documentId、signerEmail、signedAt |
| document.completed | 当事者全員が署名しました | documentId、completedAt、downloadUrl |
| document.declined | 署名者が明示的に拒否 | documentId、署名者のメールアドレス、理由 |
| document.expired | 文書は署名されていないまま有効期限を迎えます | documentId、期限切れ |
| signing.started | 署名セッショントークンが引き換えられます | documentId、sessionId、signerEmail |
| signing.completed | 署名セッションが終了しました (署名または拒否) | documentId、sessionId、outcome |
| 顧客.作成 / .更新 / .削除 | 顧客レコードを変更します | customerId、externalCustomerId |
| template.created /.updated | テンプレートを変更しました | テンプレートID、名前 |
完全なリストはバックエンド `WEBHOOK_EVENTS` にあります。 webhook ごとにサブスクリプションを追加または絞り込む — 配信パイプラインは、登録されたエンドポイントごとに 1 つの HTTP 呼び出しをファンアウトします。
webhook 署名の検証 (Node.js)
すべての配信には `X-Endorsed-Signature` ヘッダーが含まれます: `t={unix_seconds},v1={hex}`。 `v1` は ` の HMAC-SHA256 です ⟪P2⟫ の作成時に返されたシークレットを使用する {timestamp}.{rawBody}`。 ±5 分を超えるタイムスタンプを拒否します。 `X-Webhook-Signature` は、開発者ポータルのテスト配信に、非推奨の本体のみのエイリアスとして依然として表示される場合があります。`X-Endorsed-Signature` を確認してください。前提条件: 環境変数内の webhook シークレット、生の本体を保持する Express ルート。予期される出力: 認識されないペイロードまたは改ざんされたペイロードは、ハンドラーが実行される前に 401 で拒否されます。
import crypto from 'node:crypto';
import express from 'express';
const WEBHOOK_SECRET = process.env.ENDORSED_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 5 * 60;
export function verifyWebhookSignature(
rawBody: string,
header: string | undefined,
nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
let timestamp: number | null = null;
let v1 = '';
for (const part of header.split(',')) {
const eq = part.indexOf('=');
if (eq === -1) continue;
const key = part.slice(0, eq).trim();
const value = part.slice(eq + 1).trim();
if (key === 't' && /^\d+$/.test(value)) timestamp = Number.parseInt(value, 10);
if (key === 'v1' && /^[a-f0-9]{64}$/i.test(value)) v1 = value.toLowerCase();
}
if (timestamp === null || !v1) return false;
if (Math.abs(nowSeconds - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody)
.digest('hex');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(v1, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post(
'/webhooks/endorsed',
express.json({ verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); } }),
(req, res) => {
const sig = req.header('X-Endorsed-Signature');
if (!verifyWebhookSignature((req as any).rawBody, sig)) {
return res.status(401).send('Invalid signature');
}
res.sendStatus(200);
},
);30 秒以内に 2xx を返すか、配信は失敗としてマークされます。失敗した試行は上のラダーで再試行され、開発者コンソールから引き続き再生可能です。
webhook エンドポイントの設定方法
- 1
アプリ内にエンドポイントを作成します
POSTリクエストを受け入れ、10秒以内にHTTP 200を返すルートを追加します。 2xx 応答はすべて配信成功としてカウントされます。
- 2
テナント設定にエンドポイントを登録します
「管理者」→「設定」→「P0」に移動します。エンドポイント URL を入力し、必要なイベント タイプを選択します。署名シークレットはエンドポイントごとに生成されます。
- 3
すべてのリクエストの署名を検証します
「X-Endorsed-Signature」と読み取ってください。 ` を介して HMAC-SHA256 を再計算します{timestamp}.{rawBody}` および定数時間は `v1` と比較されます (上記のコードサンプルを参照)。ヘッダーの欠落、不正な 16 進値、±5 分を超えるタイムスタンプ、または HMAC の不一致を拒否します。 `X-Webhook-Signature` は、一部のテスト配信では非推奨のエイリアスです。これを実際のコントラクトとして扱わないでください。
- 4
2xxを素早く返し、非同期処理
10 秒以内に 200 で配信を確認し、非同期処理のためにイベント本文をキューに入れます。開発者コンソールにはすべての試行 (ヘッダー、本文、ステータス、タイミング) が表示され、配信を再実行できます。ハンドラーをテストするためだけにソース署名フローを再トリガーする必要はありません。
よくある質問
実際の webhook ペイロード — ドキュメントが完成しました
すべての当事者が署名すると、EndorsedSign このペイロードが登録済みのエンドポイントに POST されます。 HMAC 署名を検証し、キューに入れ、200 で確認応答します。

最初の webhook を接続します
サンドボックスを取得し、管理者→開発者→Webhooks でエンドポイントを登録し、開発者コンソールから各配信を検査または再生します。