Documentation menu

Webhook とイベント

アカウントの Webhook は、アカウント全体で起きたこと(新しいリード、予約されたミーティング、ステージが変わった商談など)を、指定した URL にリアルタイムで送ります。Zapier と n8n の連携も内部でこれを使っており、独自のエンドポイントに送ることもできます。

各メールの回答ページにあるプロジェクトの Webhook はこれまでどおり使えます。プロジェクトの Webhook は1通のメールのインタラクションを扱い、アカウントの Webhook はすべてのメールと下記のイベントを扱います。署名の方式は同じです。

Webhook を追加する

  1. ダッシュボードの 開発者向け を開き、Webhook カードを探します。
  2. エンドポイント URL(公開された https:// の URL)を入力し、必要な イベント にチェックを入れます。
  3. Webhook を追加 をクリックし、署名シークレット をコピーします。表示されるのはこの一度だけです。

各 Webhook には、作成元(ダッシュボード、API、Zapier、n8n)、状態、最終配信日時が表示されます。テストを送信 は、選んだイベントのサンプルを data に "test": true を付けて送ります。削除 で Webhook を削除します。1つのアカウントで最大50件まで作成できます。

Webhook の追加と削除はアカウントのオーナーだけが行えます。操作の前に再ログインを求められる場合があります。

イベント

イベント発生するタイミング
interaction.received受信者がメールで操作したとき(投票、評価、クイズの回答、計測対象のクリック、購入など)。重複として除外された操作では発生しません。
form.submittedメール内のフォーム(source: "email-form")または登録フォーム(source: "signup-form")が送信されたとき。
contact.created連絡先がリストに追加されたとき。
contact.updated連絡先のフィールドが変わったとき。同じ内容を保存しただけでは発生しません。
lead.hot連絡先のエンゲージメントスコアがホットリードのしきい値を上向きに超えたとき。
lead.new登録フォームまたはメール内のフォームから新しいリードが来たとき。
booking.createdミーティングが予約されたとき。
booking.cancelled予約がキャンセルされたとき(cancelledBy 付き)。日時の変更ではどちらの予約イベントも発生しません。
deal.created商談が作成されたとき。作成元(ボード、自動ルール、ジャーニー、提案書、API)は問いません。
deal.stage_changed商談のステージが変わったとき(成約・失注を含む)。
purchase.completed受信者がメール内のチェックアウトで支払ったとき。
journey.completed連絡先がジャーニーの最後まで到達したとき。途中で抜けた場合は含みません。

連絡先のイベントは、インポート、登録フォーム、API、同期、AI コネクタで発生します。1回の書き込みで500件を超える連絡先(大きな CSV インポートなど)の場合は発生しないため、インポートで数千のワークフローが動くことはありません。連絡先グリッドでの編集、ジャーニーの フィールドを更新 ステップ、保存された回答でも発生しません。

lead.hot と lead.new は、リードアラートのスイッチや制限とは関係なく発生します。購読すること自体が同意になります。

ペイロード

配信はすべて、同じ形式の JSON の POST です。

{
  "id": "evt_8c1f…",
  "type": "deal.stage_changed",
  "createdAt": 1790000000000,
  "data": {
    "deal": {
      "id": "deal_abc123",
      "title": "Annual plan",
      "value": 1200,
      "currency": "USD",
      "pipelineId": "owner_default",
      "stageId": "proposal-sent",
      "stage": "Proposal sent",
      "status": "open",
      "source": "manual",
      "listId": "list_abc123",
      "rowId": "3f6c1b0e2d…",
      "email": "[email protected]"
    },
    "fromStageId": "meeting-booked"
  }
}

id は同じイベントの配信ではすべて同じで、X-MailInApp-Idempotency-Key ヘッダーでも送られます。処理済みの再配信は安全に破棄できます。createdAt はエポックからのミリ秒です。

各イベントの data の中身は、GET /api/v1/events/sample を呼ぶか、テストを送信 で確認できます。

署名を確認する

配信には X-MailInApp-Timestamp と X-MailInApp-Signature のヘッダーが付き、プロジェクトの Webhook とまったく同じ方法で計算されています。署名シークレットを使って生のボディに対して検証し、数分以上前のタイムスタンプは拒否してください。そのまま使える Node.js の関数がプロジェクトの Webhook のドキュメントにあります。

再試行

エンドポイントは5秒以内に 2xx を返す必要があります。それ以外(タイムアウト、エラーステータス、リダイレクト)は失敗として扱われ、同じボディと同じ冪等キーで、Webhook の現在の URL に向けて、間隔を広げながら数時間にわたり自動で再試行されます。すぐに応答を返し、時間のかかる処理はその後に行ってください。

  • エンドポイントが 410 Gone を返すと、Webhook は無効になります。REST Hooks のクライアントはこの方法で購読を解除します。
  • API キーを無効化 すると、そのキーで作成した Webhook も無効になります。
  • Webhook を削除すると、保留中の再試行も止まります。

API で購読する

Zapier、n8n、独自のコードは、API キー(Authorization: Bearer mia_live_…)で Webhook を管理できます。

curl https://mailinapp.com/api/v1/webhooks \
  -H "Authorization: Bearer mia_live_..." \
  -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.example.com/mailinapp", "events": ["lead.hot", "booking.created"]}'

201 のレスポンスには、購読の id と、すべての配信に署名する secret が含まれます。secret は二度と返されないので、保管してください。GET /api/v1/webhooks で購読の一覧を取得し、DELETE /api/v1/webhooks/{id} で削除します。不明なイベント名が1つでもあると、リクエスト全体が拒否されます。これらのルートは、キーごとに1分あたり30リクエストまでです。

完全な仕様は OpenAPI 仕様にあります。