# How to Test a Webhook in n8n

- Tool: n8n
- Difficulty: Intermediate
- Time required: 15-20 minutes
- Compatibility: n8n 1.0+ (self-hosted and Cloud)
- Last updated: March 2026

## TL;DR

To test a webhook in n8n, open the Webhook trigger node and click Listen for Test Event to activate the test URL. Send a request to the test URL (which uses /webhook-test/ instead of /webhook/) using curl, Postman, or your application. The incoming data appears in the node's output panel, letting you inspect headers, body, and query parameters before activating the workflow for production use.

## Testing Webhooks in n8n: Test URLs, Production URLs, and Data Inspection

n8n provides two webhook URLs for every Webhook trigger node: a test URL for development and a production URL for live use. Understanding the difference and knowing how to send test requests, inspect incoming data, and debug common issues is essential for building reliable webhook-driven workflows. This tutorial walks you through the full testing cycle from first request to production activation.

## Before you start

- A running n8n instance (self-hosted or Cloud)
- A workflow with a Webhook trigger node
- curl or Postman installed for sending HTTP requests
- Access to the n8n editor in a browser

## Step-by-step guide

### 1. Understand the test URL vs production URL

Every Webhook trigger node in n8n has two URLs. The test URL contains /webhook-test/ in the path and is only active when you click Listen for Test Event in the editor. It is designed for development and lets you see the incoming data immediately in the node output panel. The production URL contains /webhook/ and is only active when the workflow is toggled to Active. It runs the full workflow in the background. During development, always use the test URL so you can inspect data step by step without activating the workflow.

**Expected result:** You understand that /webhook-test/ is for development and /webhook/ is for production, and they are never active simultaneously.

### 2. Start listening for a test event

Open your workflow in the n8n editor and click on the Webhook trigger node. In the node panel, you will see the test URL displayed. Click the Listen for Test Event button (or click Test Workflow at the top). n8n now waits for an incoming HTTP request at the test URL. The editor shows a spinning indicator while it waits. You have approximately 120 seconds to send a request before the listener times out. Keep the editor tab open and focused while testing — navigating away may interrupt the listener.

**Expected result:** The n8n editor shows a Waiting for test event indicator on the Webhook node.

### 3. Send a test request with curl

Open a terminal and send an HTTP request to the test URL using curl. Include a JSON body with sample data that represents what your real integration will send. Use the -H flag to set the Content-Type header to application/json so n8n correctly parses the body. If your webhook expects query parameters, append them to the URL. If it expects form data, use -d with URL-encoded values and set Content-Type to application/x-www-form-urlencoded instead.

```
# JSON POST request
curl -X POST https://your-n8n.example.com/webhook-test/my-webhook \
  -H 'Content-Type: application/json' \
  -d '{
    "event": "order.created",
    "customer_email": "test@example.com",
    "order_id": 12345,
    "total": 99.99
  }'

# GET request with query parameters
curl 'https://your-n8n.example.com/webhook-test/my-webhook?status=active&page=1'

# Form data POST request
curl -X POST https://your-n8n.example.com/webhook-test/my-webhook \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'name=John&email=john@example.com'
```

**Expected result:** curl returns a response from n8n (typically the workflow output or a simple acknowledgment), and the data appears in the Webhook node's output panel in the editor.

### 4. Inspect the incoming data in the n8n editor

After the test request arrives, the Webhook node's output panel shows the parsed data. Click on the node to open it and review the Output tab. You will see the request body under $json, headers under $headers, query parameters under $query, and URL parameters under $params. Switch between Table view and JSON view to explore the data structure. This is the exact data shape that downstream nodes will receive. If a field is missing or has an unexpected type, fix the sender's request before proceeding.

**Expected result:** The Webhook node output shows the parsed JSON body, headers, query parameters, and any URL path parameters from your test request.

### 5. Test with authentication enabled

If your webhook requires authentication, configure it in the Webhook node settings under Authentication. n8n supports Basic Auth, Header Auth, and JWT. After enabling authentication, your test requests must include the correct credentials. For Basic Auth, use the -u flag in curl. For Header Auth, add the custom header with -H. Test that authenticated requests succeed and unauthenticated requests return a 401 or 403 error.

```
# Basic Auth
curl -X POST https://your-n8n.example.com/webhook-test/my-webhook \
  -u 'myuser:mypassword' \
  -H 'Content-Type: application/json' \
  -d '{"test": true}'

# Header Auth (e.g., X-API-Key)
curl -X POST https://your-n8n.example.com/webhook-test/my-webhook \
  -H 'X-API-Key: your-secret-key-here' \
  -H 'Content-Type: application/json' \
  -d '{"test": true}'

# Verify unauthenticated requests are rejected
curl -v -X POST https://your-n8n.example.com/webhook-test/my-webhook \
  -H 'Content-Type: application/json' \
  -d '{"test": true}'
```

**Expected result:** Authenticated requests are accepted and data appears in the editor. Unauthenticated requests return a 401 Unauthorized response.

### 6. Activate the workflow and switch to the production URL

Once your test data looks correct and all downstream nodes work as expected, toggle the workflow to Active using the switch in the top-right corner of the editor. The production URL (/webhook/) is now live and will run the full workflow for every incoming request. Update your external application or service to send requests to the production URL instead of the test URL. The test URL stops responding once the workflow is active. Verify production behavior by checking the Executions panel for successful runs.

**Expected result:** The workflow is active, the production webhook URL accepts requests, and executions appear in the Executions panel.

## Complete code example

File: `webhook-test-script.sh`

```bash
#!/bin/bash
# Webhook testing script for n8n
# Usage: ./webhook-test-script.sh <webhook_url> [auth_type]

WEBHOOK_URL="${1:?Usage: $0 <webhook_url> [none|basic|header]}"
AUTH_TYPE="${2:-none}"

echo "Testing webhook: $WEBHOOK_URL"
echo "Auth type: $AUTH_TYPE"
echo "---"

# Build auth flags
AUTH_FLAGS=""
case $AUTH_TYPE in
  basic)
    read -p "Username: " USERNAME
    read -sp "Password: " PASSWORD
    echo
    AUTH_FLAGS="-u $USERNAME:$PASSWORD"
    ;;
  header)
    read -p "Header name (e.g., X-API-Key): " HEADER_NAME
    read -sp "Header value: " HEADER_VALUE
    echo
    AUTH_FLAGS="-H '$HEADER_NAME: $HEADER_VALUE'"
    ;;
esac

# Test 1: JSON POST
echo "\n[Test 1] JSON POST request"
curl -s -w "\nHTTP Status: %{http_code}\n" \
  -X POST "$WEBHOOK_URL" \
  $AUTH_FLAGS \
  -H 'Content-Type: application/json' \
  -d '{
    "event": "test.webhook",
    "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'",
    "data": {
      "id": 1,
      "name": "Test Item",
      "value": 42.5
    }
  }'

# Test 2: GET with query params
echo "\n[Test 2] GET request with query parameters"
curl -s -w "\nHTTP Status: %{http_code}\n" \
  $AUTH_FLAGS \
  "$WEBHOOK_URL?action=ping&format=json"

# Test 3: Empty body (edge case)
echo "\n[Test 3] POST with empty body"
curl -s -w "\nHTTP Status: %{http_code}\n" \
  -X POST "$WEBHOOK_URL" \
  $AUTH_FLAGS \
  -H 'Content-Type: application/json' \
  -d '{}'

echo "\n--- All tests complete ---"
```

## Common mistakes

- **Sending requests to the production URL while the workflow is inactive** — undefined Fix: Production URLs only work when the workflow is toggled to Active. Use the test URL (/webhook-test/) during development.
- **Forgetting to set Content-Type: application/json, causing n8n to receive the body as a raw string** — undefined Fix: Always include -H 'Content-Type: application/json' in your curl command when sending JSON data.
- **Navigating away from the editor while waiting for a test event, which stops the listener** — undefined Fix: Keep the editor tab open and focused. Click Listen for Test Event again if the listener timed out.
- **Using the test URL in production integrations** — undefined Fix: The test URL is temporary and only active during manual testing. Always configure external services to use the production URL (/webhook/).

## Best practices

- Always test with the /webhook-test/ URL first before activating the workflow for production
- Pin test data in the Webhook node output to avoid re-sending requests when testing downstream nodes
- Set the response mode to When Last Node Finishes if the caller needs the workflow result, or Immediately for fire-and-forget scenarios
- Always enable authentication on production webhooks to prevent unauthorized access
- Set the WEBHOOK_URL environment variable to your public domain when running n8n behind a reverse proxy or load balancer
- Test edge cases like empty bodies, missing fields, and wrong content types to ensure your workflow handles them gracefully
- Use the Respond to Webhook node for custom response bodies and status codes instead of relying on the default response
- Log webhook payloads to a database or file during initial deployment to debug integration issues

## Frequently asked questions

### What is the difference between the test URL and the production URL in n8n?

The test URL (/webhook-test/) is only active when you click Listen for Test Event in the editor and shows incoming data in the UI. The production URL (/webhook/) is only active when the workflow is toggled to Active and runs the full workflow in the background.

### How long does the test webhook listener stay active?

The test listener stays active for approximately 120 seconds or until it receives one request, whichever comes first. After that, you need to click Listen for Test Event again.

### Can I test webhooks on n8n Cloud?

Yes, n8n Cloud provides publicly accessible webhook URLs out of the box. Copy the test URL from the Webhook node and send requests to it from anywhere.

### Why does my webhook return a 404 error?

A 404 means the URL is not active. For test URLs, ensure you clicked Listen for Test Event. For production URLs, ensure the workflow is toggled to Active. Also verify the webhook path matches exactly, including case sensitivity.

### Can I receive file uploads through a webhook in n8n?

Yes, set the Webhook node's Binary Data option to true. The uploaded file will be available as binary data in downstream nodes. Use multipart/form-data as the content type when sending the request.

### How do I return a custom response from a webhook workflow?

Set the Webhook node's Response Mode to When Last Node Finishes and add a Respond to Webhook node at the end of your workflow. Configure the response body, status code, and headers in that node.

### Can I test webhooks locally without a public URL?

Yes, if n8n runs locally on port 5678, send requests to http://localhost:5678/webhook-test/your-path. For testing with external services, use a tunneling tool like ngrok to expose your local n8n instance.

### Can RapidDev help me set up webhook integrations in n8n?

Yes, RapidDev's engineering team can design and implement webhook-driven n8n workflows with proper authentication, error handling, and response formatting for your specific integration needs.

---

Source: https://www.rapidevelopers.com/n8n-tutorial/how-to-test-a-webhook-in-n8n
© RapidDev — https://www.rapidevelopers.com/n8n-tutorial/how-to-test-a-webhook-in-n8n
