開発者

Webhook

HMAC 署名付き配信、自動再試行、コンソールからのリプレイ セーフティ ネットを使用して、HTTP 経由でリアルタイムの署名イベントを受信します。

HMAC

SHA-256 署名要求

webhook シークレットごと、X-Endorsed-Signature として送信

10s

配信タイムアウト

ウィンドウ内で 2xx を返すか、試行は失敗します

5×

最初の試行後の再試行

60秒、5分、15分、1時間、その後6時間

Replay

開発者コンソールから

すべての試行を検査し、個々のイベントを再生します

webhookイベントでできること

すべての重要なライフサイクル遷移では、型付きイベントが生成されます。これらを使用して、ポーリングせずに自分のレコードを更新します。

✅

ダウンストリームアクションをトリガーする

エンベロープが完全に署名されたら、CRM を更新したり、プロビジョニングされたリソースを解放したり、独自の製品内で確認を送信したりできます。これらはすべて、API をポーリングすることなく行われます。

🔄

同期ドキュメントステータス

データベースを署名ライフサイクル (送信、開封、署名、拒否、期限切れ、無効) と同期させます。遷移ごとに 1 つのイベントがあり、ポーリング ループは必要ありません。

📋

監査とコンプライアンスのログ記録

webhook イベントを独自の監査ストアにフィードします。相関 ID は、すべてのイベントを元の API リクエストにリンクし、完全な追跡可能性を実現します。

🔁

失敗した配信を再生する

再試行ラダーを使い果たしたイベントは、開発者コンソールで検査して意図的に再生できる配信不能キューに入れられます。

Webhook イベント参照

webhook を登録し、必要なイベントを選択すると、EndorsedSign が `event`、`tenantId`、`timestamp`、および `data` を含む JSON ペイロードを配信します。イベント名は、webhook 作成呼び出しで送信する文字列と一致します。

イベントタイプ発火時キーの「データ」フィールド
document.createdAPI 経由でドキュメントをアップロードします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 で拒否されます。

typescript
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. 1

    アプリ内にエンドポイントを作成します

    POSTリクエストを受け入れ、10秒以内にHTTP 200を返すルートを追加します。 2xx 応答はすべて配信成功としてカウントされます。

  2. 2

    テナント設定にエンドポイントを登録します

    「管理者」→「設定」→「P0」に移動します。エンドポイント URL を入力し、必要なイベント タイプを選択します。署名シークレットはエンドポイントごとに生成されます。

  3. 3

    すべてのリクエストの署名を検証します

    「X-Endorsed-Signature」と読み取ってください。 ` を介して HMAC-SHA256 を再計算します{timestamp}.{rawBody}` および定数時間は `v1` と比較されます (上記のコードサンプルを参照)。ヘッダーの欠落、不正な 16 進値、±5 分を超えるタイムスタンプ、または HMAC の不一致を拒否します。 `X-Webhook-Signature` は、一部のテスト配信では非推奨のエイリアスです。これを実際のコントラクトとして扱わないでください。

  4. 4

    2xxを素早く返し、非同期処理

    10 秒以内に 200 で配信を確認し、非同期処理のためにイベント本文をキューに入れます。開発者コンソールにはすべての試行 (ヘッダー、本文、ステータス、タイミング) が表示され、配信を再実行できます。ハンドラーをテストするためだけにソース署名フローを再トリガーする必要はありません。

よくある質問

実際の webhook ペイロード — ドキュメントが完成しました

すべての当事者が署名すると、EndorsedSign このペイロードが登録済みのエンドポイントに POST されます。 HMAC 署名を検証し、キューに入れ、200 で確認応答します。

ドキュメントライフサイクルエントリを含む配信イベント履歴
配信イベント履歴 — 運用検証のためのタイムスタンプとステータス結果を含む署名付きライフサイクル イベント。

最初の webhook を接続します

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