n8nのWebhookは、受け取る方法・入力・認証・応答を決め、Test URLで確かめてからProduction URLへ移す順に設定します。URLをコピーするだけでなく、届いた値と返した内容、処理の回数までそろえることが大切です。
テストではListen for test eventで待受けを始め、外部への書込みがない構成へダミーを1件送ってください。本番では検証済みの版を公開し、送信元に設定したProduction URLとExecutionsの記録を照合しましょう。
特に分けたいのは、受け付けたことと、後続処理が完了したことです。再送や認証失敗も含めて答えを決めておくと、本番で「200は返ったのに保存されていない」と迷う場面を減らせます。
以下は、公開されているn8nの仕様に基づく設定手順と説明用の作例です。画面の表記や選択肢は本体版・ノード版・契約で異なるため、自分の環境の版と編集・実行・公開の権限、送信元の設定権限を確認して進めてください。
送信元との受信・応答の約束を先に決める
Webhookを置く前に、何が届き、どの条件で受け付け、何を返せば送信元が成功と判断するかを整理しましょう。ここが決まると、ノードの各欄へ入れる内容も明確です。
| 決める項目 | 説明用の設定例 | 確かめること |
|---|---|---|
| HTTP MethodとPath | POST、sample-receive | 送信元が使う方法と一致するか。完全URLはノード表示から取得 |
| Content-Typeと入力 | application/json。event_id、type、valueを受信 | 必須項目、文字列・数値の型、不正値をどう扱うか |
| イベントの識別 | event_idにdemo-001を使う仮例 | 再送でも同じIDか。別イベントと取り違えないか |
| 認証 | 隔離テストではHeader auth | 送信元が対応する方式か。秘密をどこへ保存するか |
| 応答 | 受け付けたら、合意したコードとJSONを返す | 受付なのか、処理完了なのか。拒否時は何を返すか |
| 待ち時間・再送 | 送信元の公式仕様を確認して記入 | タイムアウト、再送間隔、再送上限、重複通知の可能性 |
説明用のダミー入力
主例で送るJSONは次の形です。実在の利用者情報や秘密値を含まず、この内容で送受信を実測したという意味でもありません。
{ "event_id": "demo-001", "type": "sample", "value": 2}Pathは受信先を識別する部分であり、それ自体は認証とは別の設定です。GETでリンクを開いただけで投稿・課金・メール送信が動く設計も基本例にはせず、何を起点に副作用を起こすかを明示しましょう。
送信元が署名検証やchallenge応答を要求する場合は、そのサービスの公式条件が先です。専用のTriggerノードが必要条件を満たすなら、汎用Webhookで組む方法と比べて選んでください。
関連記事:n8nのHTTP RequestでAPIを呼ぶには
Webhookは外部からの要求を受ける入口、HTTP Requestはn8nから外へ要求するノードです。受信後に外部APIを呼びたいときは、送信先・入力・応答の設定を別々に整理できます。
認証と入力検証を入口へ置く
URLへ到達できることと、呼び出す権限があることは別です。送信元に合う認証を選び、その後で入力の必須項目や型を検証すると、不正な要求を外部処理へ渡さずに済みます。
| 役割 | 確認すること | 代わりにならないもの |
|---|---|---|
| 認証 | 許可した送信元が呼び出しているか | 長く分かりにくいPathだけでは不十分 |
| 入力検証 | 必須項目・型・許容値が合っているか | 正しい認証値があっても入力内容は別に確認 |
| 再送の重複制御 | 同じイベントで外部作成を繰り返さないか | 認証や一回の実行内の重複除去だけでは保証されない |
主例は、WebhookのAuthenticationにHeader authを選び、対応するCredentialを作成して使う構成です。CredentialのNameにはX-Demo-Webhook-Key、Valueにはテスト専用の秘密値を設定し、そのCredentialをWebhookへ割り当ててください。
送信元では、同じNameのHTTPヘッダーへ同じ秘密値を設定しましょう。ヘッダー名をBodyの項目名へ入れたり、秘密値をURLの一部へ書いたりする設定とは違います。
WebhookはBasic auth、Header auth、JWT authに加え、現行の公式文書ではn8n User Auth(OAuth2)にも対応しています。どの方式も使える送信元とは限らないため、相手が実際に送れる認証形式を確認して選びましょう。
IP allowlistは補助の制限として使えますが、送信元やプロキシの構成確認が必要です。CORSは認証の代わりになりません。ブラウザの許可元設定だけで、任意のクライアントからの呼出し権限を制御できたとは考えないでください。
認証なしのNoneを使うのは、意図した公開受付として入力・頻度・副作用を管理する場合に限りましょう。エラーを消すためだけに認証を外したり、許可範囲を広げたりする進め方は避けます。
User AuthとOnly Run Ifは、別の役割として読む
n8n User Auth(OAuth2)は、このn8nの利用者を呼出し主体にする方式です。外部APIへログインするためのOAuth2 Credential作成と、同じ手順ではありません。
この方式では呼出し元のユーザーや実行権限が関わり、BearerトークンがないGETをブラウザのログインへ誘導する設定もあります。外部通知の主例へ一律に追加せず、必要なときだけ利用版と公式の条件を確認してください。
Only Run Ifは、受信した要求を実行対象にするか選ぶ条件です。不一致では実行を作らず200を返す仕様があり、式の評価に失敗すると警告を残して要求を通すため、ここを認証の境界にしてはいけません。
たとえばtypeがsampleの要求だけを選ぶ場合も、Header authとは独立した条件として扱いましょう。「200が返った」だけでは、認証・入力検証・実行・処理完了のどこまで進んだかは分かりません。
関連記事:n8nの認証情報を設定・管理する方法とOAuth2
受信固有のヘッダー対応を確認した後、Credentialの更新、共有、移行まで整理したい場合に役立ちます。秘密を通常データへ混ぜず、利用先と権限を管理する考え方を確認しましょう。
Test URLでダミー入力を受け取る
Test URLは、テスト待受けを始めてから使います。公式の待受け時間は120秒で、120秒はテスト入口の待受け窓です。
ワークフローの処理制限時間、送信元の再送間隔、Production URLの有効期限とは別に考えてください。時間切れになった場合は待受けをやり直し、URLの種類とMethodをそろえてから送信しましょう。
- 隔離した受信口を用意する
未公開の検証用ワークフローへWebhookを置き、POST、Path、認証を設定しましょう。受信後は必要な項目の確認と、後述するRespond to WebhookによるJSON返信だけに絞ります。
- Test URLを待受け状態にする
ノードのTest URLを表示し、Listen for test eventを選んでください。表示されたURLを許可された送信元へ設定し、本番URLを文字列の置換で作ることはしません。
- ダミーを1件送る
送信元やAPIクライアントでPOST、Content-Type、認証ヘッダー、説明用JSONを設定しましょう。実データや秘密値を公開ログへ残さず、まず一回だけ送信します。
- 入力と応答を同じ要求で照合する
エディターの受信データと、送信側で得た応答コード・本文を確認してください。event_idと型が一致し、外部書込みが発生していないことまで照合しましょう。
続いて、認証情報なし、誤った値、正しい値の3通りを、それぞれ待受けを確認しながら試します。前二つは認証で拒否され、正しい値の要求だけが後続へ進むかを確認し、拒否コードと実行の有無を記録してください。
self-hostedでは、送信元から到達できるHTTPSの入口やプロキシ設定も関わります。localhostだからといってトンネルでの公開を全員の必須手順にせず、公開範囲と到達方法を管理者と決めましょう。
body・query・params・headersを取り違えない
入力は、どの領域へ届いたかまで確認してください。同じevent_idという名前でも、JSON本文のbodyと、URLに付くqueryでは参照先が違います。
| 領域 | 説明用の例 | 確認すること |
|---|---|---|
| body | POST JSONのevent_id、type、value | 主例では$json.body.event_idや$json.body.valueに対応するか |
| query | URLのクエリにあるpage等 | bodyの同名項目と混ぜていないか |
| params | Pathのルート変数にあるid等 | ノードで指定したPathと一致するか |
| headers | 要求のヘッダー | 秘密ヘッダーを後続データや返信へそのまま持ち出さないか |
主例の期待する入力は、1 itemのjson内にbodyがあり、event_idが文字列demo-001、valueが数値2という形です。実際のキーと型はOUTPUTで確かめ、値が2に見えても文字列の「2」と同一には扱わないでください。
body.recordsが配列でも、それだけで複数itemに分かれたわけではありません。1 item内の配列を要素ごとに処理したいなら、配列の展開を別の変換として設計しましょう。
Raw Bodyを使う場合は本文の表現が変わり、送信元のHMAC署名には元のバイト列やヘッダーが必要になる場合もあります。一般のJWT authと同じ機能だと考えず、送信元の署名仕様に沿って検証してください。
必須のevent_idがない、typeが許可外、valueの型が不正といった要求は、外部処理の前で拒否します。正しい認証だけで業務入力も正しいと判断せず、必要な項目だけを選んで後続へ渡しましょう。
このダミー入力の検証なら、Webhookの直後へIfノードを置き、Conditionsで型をBoolean、比較をis trueにします。値の欄をExpressionへ切り替え、次の式で「空白だけでない文字列ID・sampleという種別・数値のvalue」を一度に判定してください。
{{ typeof $json.body?.event_id === 'string' && $json.body.event_id.trim() !== '' && $json.body.type === 'sample' && typeof $json.body.value === 'number'}}true出力は受付用、false出力は拒否用のRespond to Webhookへ、それぞれ直接つなぎます。この最小例では間にitemを書き換えるノードやFilterを置かず、拒否側にも応答するitemを残してください。
これは三つの項目を確かめる作例で、すべての送信元へ使える入力検証ではありません。実際の受信契約に合わせて長さ・値の範囲・追加項目も定め、型違いを自動変換して通す設定を選んでいないか確認しましょう。
関連記事:n8nのExpressionとEdit Fieldsでデータを整える
body内の値を参照し、必要なフィールドと型を整える方法を確認できます。
関連記事:n8nのAggregateとSplit Outでitemをまとめる・分ける
1 itemの中の配列と、複数itemを区別して変換したいときの次の読み先です。
受付と処理完了を分けて応答する
Respondは、受付だけを早く返すのか、短い処理の結果まで返すのかを送信元の必要に合わせて選びましょう。返したい完了地点を決めると、応答の意味を取り違えにくくなります。
| Respondの方式 | 向く場面 | 読み違えないこと |
|---|---|---|
| Immediately | ワークフロー開始の受付を早く返したい | 開始の応答であり、後続の保存・送信完了ではない |
| When Last Node Finishes | 短い処理の最後の出力を返したい | 送信元の待ち時間内に完了するか。全件か先頭かも指定 |
| Using Respond to Webhook Node | 指定地点で、成功・拒否などのJSONやコードを明示したい | 各経路から、一つの応答へ到達させる |
主例ではWebhook側をUsing Respond to Webhook Nodeにし、Respond to WebhookノードのRespond WithでJSONを選びます。Response Bodyに定めたJSON、必要に応じてAdd OptionのResponse Codeに合意したコードを指定してください。受け付けたイベントIDだけを返す形なら、入力の全体や秘密ヘッダーを返信せずに済むためです。
説明用の受付応答
{ "accepted": true, "event_id": "demo-001"}acceptedは、この例で定義する受付を表します。外部保存がない主例なので、「投稿や保存先への反映も終わった」という応答にはしません。
実装では、確認した入力のevent_idを参照し、固定のdemo-001を全要求へ返さないでください。
上のIfから直接つないだ受付用ノードなら、Response Body全体をExpressionへ切り替え、次のようにオブジェクトを返します。ここでの$jsonは、そのノードへ届いたitemです。
{{ { accepted: true, event_id: $json.body.event_id} }}この隔離例ではResponse Codeを200にし、false側はJSONの固定値{"accepted":false,"reason":"invalid_input"}とResponse Code 400にする仮契約を使います。実サービスの指定コードがある場合はそれに合わせ、失敗を成功として返信しないでください。
長時間の処理では、送信元のタイムアウトと再送仕様も確認しましょう。先に受付を返すなら、処理結果をどこで確認するかも別に用意し、実行結果が分からないまま同じ要求を繰り返さないことが大切です。
Streaming responseは、対応ノードと受信側がある場合に使えます。通常のイベント通知を受ける基本設定に、必ず追加する機能ではありません。
読み違い
「200だったので、後続の外部保存も完了したはず」と考えてしまう。
確かめ方
HTTP応答、n8nの実行結果、外部保存先の結果を分けて照合する。受付の成功と処理の完了を分けると、どこまで進んだかを説明できます。
分岐・0件・複数itemでも、一つの応答を決める
成功した要求だけでなく、入力不正や対象0件でも、何を返すかを決めてください。途中のFilter等で全itemを落とし、応答ノードへ届かないまま終わる経路を残さないようにしましょう。
Respond to Webhookを使う構成では、応答ノードが動かず正常終了すると標準の200が返る仕様があります。最初の応答前にエラーが起きれば500、二つ目の応答は無視されるので、コードだけで意図したJSONが返ったとは判断しません。
| 入力・状態 | この例で決める応答 | 照合すること |
|---|---|---|
| 正当なダミー | 合意した成功コード、accepted:trueと同じevent_id | 入力IDと応答ID、一回の応答 |
| 必須項目なし・型不正 | 送信元と合意した拒否コードと理由 | 外部処理へ進まないこと |
| 対象0件 | 例としてaccepted:false、reason:no_targetを返す契約 | 応答経路が消えず、実際のcode/bodyが一致すること |
| 複数item | 全件の配列か、先頭の一件かを明示 | 件数とID、どの項目が返信に含まれたか |
この表は、送信元と合意する内容を決めるための独自の仮契約です。サービスごとに必要な拒否コードやJSON、対象なしを正常受付とするか再送対象とするかも違うため、送信元の条件と合わせてください。
Respond to Webhookは最初の入力を基準に動くノードですが、Respond WithのAll Incoming Itemsでは全itemを返す選択ができます。When Last Node Finishes側のAll Entries/First Entry JSON等とは別の設定なので、画面の対象を区別しましょう。
全itemを返すために毎回Aggregateが必要とは限りません。複数の枝から二重に返信を狙わず、一つの要求に対してどの経路が応答を担当するかを決め、0件や未一致も含めて確認してください。
関連記事:n8nのIF・Switch・Filterの違いと条件分岐の作り方
不正入力・未一致・対象なしの行き先を作りたいときに、除外してよいデータと返答を残すデータを分けて考えられます。
公開した版とProduction URLを送信元へ設定する
本番移行は、URLの差し替えだけでは完了しません。検証した版を公開し、Production URLと送信元の本番設定をそろえ、実際の本番実行まで照合します。
現行の公式文書では、編集内容の保存とPublishは別です。Production実行は公開版を使うため、編集中の変更が保存されても本番へ反映したと判断せず、利用中の版と表示を確かめましょう。
- 検証した対象版を記録する
workflow IDと版、公開状態、送信元の環境、Credentialの参照を記録してください。認証なし・不正値・0件なども含め、定めた応答と処理を満たしてから本番へ進みましょう。
- 許可されたワークフローを公開する
Publishは、外部通知から実行できる状態にする操作です。別のTriggerや外部書込みも確認し、実行してよい構成だけを公開してください。
- 公開の完了とProduction URLを確認する
公開は非同期のため、Publishingのままか、一部のTriggerが失敗していないかを確認しましょう。Production URLはノードに表示された値を使い、Test URLの文字列置換では作りません。
- 送信元を切り替え、本番の1件を照合する
送信元の本番URL・Method・認証を設定し、許可されたダミーまたは影響を限定した1件を送ってください。応答、Executionsの対象実行、必要なら外部結果のIDと件数まで確認しましょう。
Production URLで届いたデータは、テストと同じようにエディターへ表示されるわけではありません。Executionsで対象の時刻とイベントIDを確認し、記録が見つからない場合は実行データの保存設定や権限も含めて調べてください。
旧版でActiveなどの表記がある場合は、現行文書のPublishと画面が同じとは限りません。画面の違いを理由に一律の更新を進めず、利用版に対応する公開・停止操作を確認しましょう。
- 送信元の本番環境・URL・Method・認証が、検証した条件に対応しているか
- 検証した版が公開され、Webhookの登録が完了しているか
- 受信したevent_id・値・型が、送信した1件と一致するか
- 実際の応答コードとJSONが、定めた受付・拒否の意味を満たしているか
- Executionsの対象実行と、必要な外部結果のID・件数が対応しているか
再送・機密・容量と、止める手順も決める
タイムアウトなどで同じイベントが再送されると、別の実行として同じ処理が始まる可能性があります。イベントID等を永続的に照合し、副作用の直前で重複と競合を制御する条件を用意してください。
再送の確認例
同じevent_idを2回受けても、外部データの作成は1件という受入条件を置きます。これは設計上の目標で、実測結果や、Webhookだけで自動的に保証される性質ではありません。
保存先APIが対応する冪等キーや、一意制約・競合制御を使う場合も、その適用範囲を確認しましょう。先に重複を調べて後から保存するだけでは、同時受信の間に両方が通る場合があるため、別実行・同時実行まで含めて考える必要があります。
Remove Duplicatesで一つの入力内を整理すること、配信されたWebhookの重複を見つけること、外部APIが処理を一回に保つことは別です。処理途中の失敗も含め、再送前に外部結果を読み戻す判断を残してください。
関連記事:n8nの重複除去|比較キーと履歴の使い分け
itemの重複を何のキー・どの範囲で除くかを整理できます。Webhookの別実行や外部保存の一度だけ処理を、そのまま保証する機能とは分けて読みましょう。
機密情報は、Executionsや返信に必要以上に残さないことも運用条件です。秘密値、完全な受信URL、個人情報を含むpayloadを画像や公開資料へ写さず、保存対象と期間を決めてください。
現行文書のWebhook payload上限はn8n側の基本値で16MBです。self-hostedで変更できる設定があっても、送信元・プロキシ・ホスト側に小さい上限があれば影響するため、値を増やすだけで解決したとは判断しません。
| 止める対象 | 確認すること | 別に残ること |
|---|---|---|
| テスト待受け | 検証が終わった受信口を止める | すでに始まった実行や外部処理 |
| 送信元の配信 | 配信停止・URL変更の対象環境を確認 | 送信元の保留・再送キュー |
| n8nの本番入口 | 管理下でunpublishし、停止状態を確認 | 実行中の処理、過去の投稿・送信・課金 |
| 復帰・版の戻し | 元の公開版と受信契約をそろえて再確認 | 二重作成した外部データ等の個別照合・取消し |
unpublishは入口を止める操作であり、外部で済んだ処理の取消しは別に必要です。停止時は配信、実行中、保留、再送を分けて確認し、復帰前に元の版と契約を照合しましょう。
次に確認したいこと:n8nのWebhookが動かない原因の切り分け
URL・Method・公開版をそろえても届かない、入力や後続ノードで失敗する場合に、発生時刻、イベントID、応答、対象実行を整理し、通信・認証・データ構造を分けて原因を追いたいときの読み先です。
まとめ|入力と応答を確かめ、公開版と本番URLをそろえる
n8nのWebhookは、受信方法・入力・認証・応答と再送条件を決め、隔離したTest URLで確認してから本番へ移します。公開版とProduction URLをそろえ、本番ではExecutionsと必要な外部結果まで照合する流れです。
最初は、説明用の小さいJSONを1件受け、正しい入力と認証だけが予定の応答へ進むかを確かめましょう。応答コードだけでなく、event_id、値の型、実行と副作用の回数も確認してください。
受付と処理完了を分けておく方が、再送すべきか、結果を読み戻すべきかを整理しやすくなります。URLをつなぐことより、受け取った後の判断まで説明できる入口を目指すことが大切です。
次に確認したいこと:n8nの費用と運用方式
受信後の実行回数や運用負担が見えてから、費用と設置方式を別の判断として比較できます。
次に確認したいこと:自動化する工程と人に残す確認
ブログ運営へ広げたい場合は、Webhookの受信成功とは別に、人が内容や公開を確認する工程を決めましょう。