Webhook とイベント
アカウントの Webhook は、アカウント全体で起きたこと(新しいリード、予約されたミーティング、ステージが変わった商談など)を、指定した URL にリアルタイムで送ります。Zapier と n8n の連携も内部でこれを使っており、独自のエンドポイントに送ることもできます。
各メールの回答ページにあるプロジェクトの Webhook はこれまでどおり使えます。プロジェクトの Webhook は1通のメールのインタラクションを扱い、アカウントの Webhook はすべてのメールと下記のイベントを扱います。署名の方式は同じです。
Webhook を追加する
- ダッシュボードの 開発者向け を開き、Webhook カードを探します。
- エンドポイント URL(公開された
https://の URL)を入力し、必要な イベント にチェックを入れます。 - 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 仕様にあります。