Contents

n8n Webhook Tutorial: Receive External Data and Respond

Webhook lets an external service proactively notify n8n when an event occurs. For example:

  • Someone submits a website form
  • A payment platform reports a successful payment
  • GitHub gets a new Pull Request
  • You want your own program to trigger an n8n workflow

The n8n Webhook node generates a URL. Any HTTP request sent to that URL starts the workflow.

Create a webhook

  1. Add a workflow and select Webhook as the first node.
  2. Configure:
    • HTTP Method: Usually POST
    • Path: The URL path, such as contact-form
    • Respond: When to respond (explained below)

Two URLs appear above the node:

URLFormatWhen it works
Test URLhttps://your-domain/webhook-test/contact-formReceives one request after you click “Listen for test event”
Production URLhttps://your-domain/webhook/contact-formAfter you publish the workflow
Webhook node showing the Test URL and Production URL
Webhook node: Switch between the Test URL and Production URL at the top. The URL shown here uses localhost, which means no public URL has been configured yet.

The most common mistake is configuring an external service with the Test URL and then not receiving data after publishing the workflow. For production use, be sure to switch to the Production URL.

Test

  1. Click Listen for test event.
  2. Send a request from the terminal:
curl -X POST https://your-domain/webhook-test/contact-form \
  -H "Content-Type: application/json" \
  -d '{"name": "John Smith", "email": "ming@example.com", "message": "I’d like to ask about pricing"}'
  1. The received data appears in the Webhook node’s OUTPUT:
{
  "headers": { "content-type": "application/json", "...": "..." },
  "params": {},
  "query": {},
  "body": {
    "name": "John Smith",
    "email": "ming@example.com",
    "message": "I’d like to ask about pricing"
  }
}

In subsequent nodes, read the submitted data with {{ $json.body.name }}. URL parameters (such as ?id=123) are available at {{ $json.query.id }}.

Response options

The Respond option determines when n8n responds and what it returns to the caller:

OptionBehavior
ImmediatelyResponds as soon as the request arrives; the workflow continues running in the background
When Last Node FinishesWaits for the entire workflow to finish and returns the last node’s data
Using 'Respond to Webhook' NodeThe Respond to Webhook node in the workflow determines the response content

Choose Immediately when the caller only needs to know that the request was received (for example, a payment notification). To return the processing result (for example, to create an API), use the Respond to Webhook node.

Build a simple API with n8n

[Webhook GET /price] ─▶ [Google Sheets lookup] ─▶ [Respond to Webhook]
A workflow made up of Webhook, Edit Fields, and Respond to Webhook
Webhook → format the data → Respond to Webhook returns JSON

Configure the Respond to Webhook node:

  • Respond With: JSON, text, binary file, or redirect
  • Response Code: For example, 200 or 404
  • Response Headers: For example, CORS headers


{ "product": "{{ $json.name }}", "price": {{ $json.price }} }

Path parameters

The Path can include variables:

orders/:orderId

When you call /webhook/orders/A123, {{ $json.params.orderId }} is A123.

Authenticate requests

The Production URL is public, so anyone who knows it can call it. Protect it with these methods:

  1. Authentication option: Basic Auth, Header Auth, or JWT Auth. For example, configure Header Auth with the name X-API-Key; the caller must include the correct value.
  2. Verify signatures: Many services (Stripe, GitHub, LINE, and others) include a signature in the Header. You can verify it with a Code node.
  3. IP allowlist: Configure IP(s) Whitelist in the Webhook Options.
  4. Use a random, hard-to-guess string in the path.

Receive files

When a form uploads a file (multipart/form-data), the file appears in the binary data. You can connect it directly to nodes such as Google Drive or Extract from File.

Make your n8n instance reachable by external services

External services must be able to reach n8n over the network:

  • Production deployment: Use a server with a domain and HTTPS, and configure the Webhook URL environment variable correctly. Otherwise, the URL shown by n8n will be http://localhost:5678/.... See Self-hosting.
  • Local testing: Tools such as Cloudflare Tunnel and ngrok can temporarily expose local port 5678 to the internet.

Common issues

404: The requested webhook is not registered

  • When using the Test URL: You did not click Listen for test event first, or it has already received a request.
  • When using the Production URL: The workflow has not been published.
  • The HTTP method does not match (for example, the node is set to POST but you call it with GET).

The received body is empty

Make sure the caller sends the Content-Type: application/json header.

The external service reports a timeout

You selected When Last Node Finishes, and the workflow takes too long to run. Switch to Immediately or shorten the workflow.

Updated October 12, 2026