# Example: HTTP Webhook Workflow
Learn to create a simple webhook that receives HTTP requests and processes data.
## What You'll Build
A webhook workflow that:
1. Receives HTTP POST requests
2. Extracts data from request body
3. Logs the data
4. Returns success response
**Time Required:** 10 minutes
**Difficulty:** Beginner
**Prerequisites:** None
---
## Problem Statement
You need an endpoint that receives webhook notifications from external services (e.g., GitHub, Stripe, payment processors) and logs the received data for debugging and monitoring purposes.
**Real-World Use Cases:**
- Receive payment notifications from Stripe
- Log GitHub webhook events
- Process form submissions
- Monitor API callbacks
- Debugging third-party integrations
---
## Solution Architecture
```
HTTP POST Request
↓
[Webhook Node] → Receives request, extracts body
↓
[Code Node] → Logs data to console
↓
[Response] → Returns 200 OK
```
**Workflow Characteristics:**
- **Trigger:** HTTP Webhook
- **Nodes:** 2 (Webhook, Code)
- **Complexity:** Simple
- **Response Time:** <100ms
---
## Step-by-Step Tutorial
### Step 1: Start Conversation in Claude Desktop
```
You: "I need to create a webhook workflow in my staging environment that logs incoming requests"
Claude: I'll help you create a webhook workflow in staging. Let me use the http-webhook-workflow prompt to generate the structure.
[MCP tool call: create_workflow]
{
"instance": "staging",
"name": "Webhook Logger",
"nodes": [
{
"id": "webhook_1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"parameters": {
"path": "webhook-logger",
"responseMode": "onReceived",
"options": {}
}
},
{
"id": "code_1",
"name": "Log Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [450, 300],
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Log incoming webhook data\nconst data = $input.all();\n\nconsole.log('='.repeat(50));\nconsole.log('Webhook Received:', new Date().toISOString());\nconsole.log('Data:', JSON.stringify(data, null, 2));\nconsole.log('='.repeat(50));\n\n// Return the data for next nodes\nreturn data;"
}
}
],
"connections": {
"Webhook": {
"main": [[{ "node": "Log Data", "type": "main", "index": 0 }]]
}
},
"active": false
}
✅ Workflow "Webhook Logger" created successfully in "staging"
Details:
- ID: 123
- Webhook URL: https://staging.app.n8n.cloud/webhook/webhook-logger
- Status: Inactive (activate when ready)
- Nodes: 2 (Webhook, Log Data)
The webhook will log all incoming POST requests to the n8n console.
```
---
### Step 2: Activate the Workflow
```
You: "Activate this workflow"
Claude: I'll activate the workflow now.
[MCP tool call: activate_workflow]
{
"instance": "staging",
"id": "123"
}
✅ Workflow activated successfully
The webhook is now live at:
https://staging.app.n8n.cloud/webhook/webhook-logger
You can test it with:
curl -X POST https://staging.app.n8n.cloud/webhook/webhook-logger \
-H "Content-Type: application/json" \
-d '{"test": "data", "timestamp": "2025-01-15T10:30:00Z"}'
```
---
### Step 3: Test the Webhook
#### Using curl:
```bash
curl -X POST https://staging.app.n8n.cloud/webhook/webhook-logger \
-H "Content-Type: application/json" \
-d '{
"event": "user.signup",
"user_id": 12345,
"email": "user@example.com",
"timestamp": "2025-01-15T10:35:00Z"
}'
```
**Expected Response:**
```json
{"status":"ok"}
```
#### Using Postman:
1. **Method:** POST
2. **URL:** `https://staging.app.n8n.cloud/webhook/webhook-logger`
3. **Headers:** `Content-Type: application/json`
4. **Body (raw JSON):**
```json
{
"event": "payment.success",
"amount": 49.99,
"currency": "USD",
"customer_id": "cus_12345"
}
```
#### Using JavaScript:
```javascript
fetch('https://staging.app.n8n.cloud/webhook/webhook-logger', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event: 'form.submit',
name: 'John Doe',
email: 'john@example.com'
})
})
.then(response => response.json())
.then(data => console.log('Success:', data));
```
---
### Step 4: Verify Execution
```
You: "Show me the most recent execution for this workflow"
Claude: I'll retrieve the latest execution details.
[MCP tool call: list_executions]
{
"instance": "staging",
"workflowId": "123",
"limit": 1
}
Most recent execution:
- Execution ID: 9876
- Status: Success ✅
- Started: 2025-01-15 10:35:23
- Finished: 2025-01-15 10:35:23
- Duration: 245ms
- Mode: webhook
The workflow successfully processed your test request.
Check the n8n logs to see the logged data.
```
---
## Complete Workflow Definition
```json
{
"name": "Webhook Logger",
"nodes": [
{
"id": "webhook_1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"parameters": {
"path": "webhook-logger",
"responseMode": "onReceived",
"options": {}
}
},
{
"id": "code_1",
"name": "Log Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [450, 300],
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Log incoming webhook data\nconst data = $input.all();\n\nconsole.log('='.repeat(50));\nconsole.log('Webhook Received:', new Date().toISOString());\nconsole.log('Data:', JSON.stringify(data, null, 2));\nconsole.log('='.repeat(50));\n\nreturn data;"
}
}
],
"connections": {
"Webhook": {
"main": [[{ "node": "Log Data", "type": "main", "index": 0 }]]
}
},
"active": true,
"settings": {
"saveExecutionProgress": true,
"saveManualExecutions": true,
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all"
}
}
```
---
## Testing Checklist
- [x] Webhook receives POST requests
- [x] Data logged to n8n console
- [x] Returns 200 OK response
- [x] Execution appears in history
- [x] Works with different JSON payloads
- [ ] Security: Add authentication (next step)
- [ ] Monitoring: Set up error alerts
---
## Viewing Logged Data
### Method 1: n8n UI
1. Open n8n UI
2. Navigate to **Executions** tab
3. Click on the execution
4. Select "Log Data" node
5. View the output in **Output** panel
### Method 2: Docker Logs (if using Docker)
```bash
docker logs n8n 2>&1 | grep "Webhook Received"
```
### Method 3: n8n Server Logs
```bash
# If running n8n locally
tail -f ~/.n8n/logs/n8n.log | grep "Webhook Received"
```
---
## Common Pitfalls
### Issue 1: Webhook Returns 404
**Symptoms:**
```bash
curl: (22) The requested URL returned error: 404
```
**Causes:**
- Workflow not activated
- Wrong webhook path in URL
- Typo in webhook path
**Solution:**
1. Verify workflow is active: `You: "Is workflow 123 in staging active?"`
2. Check webhook path matches URL
3. Ensure exact path spelling: `webhook-logger` not `webhook_logger`
---
### Issue 2: Data Not Logging
**Symptoms:**
- Webhook responds 200 OK
- But no logs appear in console
**Solution:**
1. Check n8n console logs (not browser console)
2. Open n8n UI → Executions → View Details
3. Click "Log Data" node to see output
4. Verify Code node has `console.log()` statement
---
### Issue 3: Workflow Not Triggering
**Symptoms:**
- No execution created when webhook called
- Webhook returns error
**Checklist:**
```
You: "Debug workflow 123 in staging - webhook not triggering"
Claude: I'll help debug. Let me check:
1. Is workflow active? ✓
2. Get workflow details to verify webhook configuration
3. Check recent executions for errors
```
**Common fixes:**
- Activate workflow
- Check webhook URL is correct
- Verify HTTP method (POST vs GET)
- Test with simple curl first
---
### Issue 4: Invalid JSON Error
**Symptoms:**
```
Error: Unexpected token in JSON at position 0
```
**Cause:** Sending non-JSON data to webhook expecting JSON
**Solution:**
```javascript
// ❌ Wrong - plain text
curl -d "test=data"
// ✅ Correct - JSON
curl -H "Content-Type: application/json" -d '{"test":"data"}'
```
---
## Next Steps
### 1. Add Data Validation
Enhance workflow to validate incoming data:
```
You: "Add validation to workflow 123 to check that 'email' and 'user_id' fields exist"
Claude: I'll add an IF node for validation.
[Adds validation node between Webhook and Log Data]
```
### 2. Add Error Handling
Handle malformed requests gracefully:
```javascript
{
"name": "Error Handler",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "try {\n const data = $input.all();\n // Validate required fields\n if (!data[0].json.email) {\n throw new Error('Missing email field');\n }\n return data;\n} catch (error) {\n console.error('Validation error:', error.message);\n return [{ json: { error: error.message } }];\n}"
}
}
```
### 3. Store Data in Database
Connect to PostgreSQL, MongoDB, or other database:
```
You: "Add a PostgreSQL node after the logger that saves the webhook data to a 'webhook_events' table"
```
### 4. Send Notifications
Alert team on specific events:
```
You: "Add a Slack notification when the webhook receives a 'payment.failed' event"
```
---
## Real-World Enhancement Examples
### Example 1: GitHub Webhook Handler
```json
{
"name": "GitHub Webhook Handler",
"nodes": [
{
"name": "Webhook",
"parameters": { "path": "github-events" }
},
{
"name": "Extract Event Type",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const event = $json.headers['x-github-event'];\nconst action = $json.body.action;\nreturn [{ json: { event, action, data: $json.body } }];"
}
},
{
"name": "Route by Event",
"type": "n8n-nodes-base.switch",
"parameters": {
"rules": [
{ "value": "push" },
{ "value": "pull_request" },
{ "value": "issue" }
]
}
}
]
}
```
### Example 2: Stripe Payment Webhook
```json
{
"name": "Stripe Payment Webhook",
"nodes": [
{
"name": "Webhook",
"parameters": { "path": "stripe-payments" }
},
{
"name": "Verify Stripe Signature",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "// Verify webhook signature for security\nconst stripe = require('stripe');\nconst signature = $json.headers['stripe-signature'];\n// Validation logic here\nreturn [$json];"
}
},
{
"name": "Process Payment",
"type": "n8n-nodes-base.switch"
}
]
}
```
---
## Key Takeaways
✅ **Learned:**
- Create simple webhook workflows via Claude Desktop
- Activate and test webhooks
- View execution logs
- Debug common webhook issues
✅ **Best Practices:**
- Always test in staging first
- Validate incoming data
- Log important events
- Monitor webhook executions
✅ **Next Level:**
- Add authentication
- Implement data validation
- Store data persistently
- Send notifications on events
---
**Estimated Reading Time:** 15 minutes
**Hands-On Time:** 10 minutes
**Total Time:** 25 minutes