Skip to main content

Webhook Integration Example

This example demonstrates advanced webhook patterns including data validation, conditional routing, and multi-branch processing. Perfect for building production-ready API endpoints.

Workflow Overview

The workflow handles incoming webhook data with:
  1. Webhook Trigger - Receives and validates incoming requests
  2. IF Node - Conditional routing based on data validation
  3. Set Nodes - Separate processing for valid and invalid data
  4. Merge Node - Combines results from different branches
  5. Respond to Webhook - Returns appropriate responses

Use Cases

  • Form submission handlers
  • Third-party integration endpoints
  • Event processing pipelines
  • Data validation and sanitization

Complete Workflow JSON

{
  "name": "Advanced Webhook Integration",
  "nodes": [
    {
      "id": "webhook-1",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [250, 350],
      "parameters": {
        "httpMethod": "POST",
        "path": "submit-form",
        "responseMode": "lastNode",
        "options": {
          "rawBody": false
        }
      },
      "webhookId": "form-submission"
    },
    {
      "id": "if-1",
      "name": "Validate Data",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [450, 350],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "condition-1",
              "leftValue": "={{$json.email}}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "contains",
                "singleValue": "@"
              }
            },
            {
              "id": "condition-2",
              "leftValue": "={{$json.name}}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            },
            {
              "id": "condition-3",
              "leftValue": "={{$json.message}}",
              "rightValue": "10",
              "operator": {
                "type": "string",
                "operation": "lengthGt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "set-valid",
      "name": "Process Valid Data",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [650, 250],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "assign-1",
              "name": "status",
              "value": "success",
              "type": "string"
            },
            {
              "id": "assign-2",
              "name": "message",
              "value": "Form submitted successfully",
              "type": "string"
            },
            {
              "id": "assign-3",
              "name": "data",
              "value": "={{$json}}",
              "type": "object"
            },
            {
              "id": "assign-4",
              "name": "timestamp",
              "value": "={{$now}}",
              "type": "string"
            },
            {
              "id": "assign-5",
              "name": "id",
              "value": "={{$runIndex}}-{{$now.toUnixInteger()}}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "set-invalid",
      "name": "Handle Invalid Data",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [650, 450],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "assign-1",
              "name": "status",
              "value": "error",
              "type": "string"
            },
            {
              "id": "assign-2",
              "name": "message",
              "value": "Validation failed: Please check email format, name, and message length (min 10 characters)",
              "type": "string"
            },
            {
              "id": "assign-3",
              "name": "errors",
              "value": "={{{
  email: $json.email ? ($json.email.includes('@') ? null : 'Invalid email format') : 'Email required',
  name: $json.name ? null : 'Name required',
  message: $json.message && $json.message.length > 10 ? null : 'Message must be at least 10 characters'
}}}",
              "type": "object"
            },
            {
              "id": "assign-4",
              "name": "timestamp",
              "value": "={{$now}}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "merge-1",
      "name": "Merge Results",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [850, 350],
      "parameters": {
        "mode": "append",
        "options": {}
      }
    },
    {
      "id": "respond-1",
      "name": "Send Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [1050, 350],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{$json}}",
        "options": {
          "responseCode": "={{$json.status === 'error' ? 400 : 200}}"
        }
      }
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Validate Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Data": {
      "main": [
        [
          {
            "node": "Process Valid Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Handle Invalid Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Valid Data": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Handle Invalid Data": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Results": {
      "main": [
        [
          {
            "node": "Send Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "active": false
}

Step-by-Step Breakdown

1

Webhook Configuration

The webhook receives POST requests with form data. It’s configured to parse JSON automatically.Key Settings:
  • rawBody: false - Automatically parses JSON
  • responseMode: lastNode - Returns final node output
2

Data Validation

The IF node validates three conditions using AND logic:
  1. Email contains ”@”
  2. Name is not empty
  3. Message is longer than 10 characters
Routing:
  • TRUE branch → Valid data processing
  • FALSE branch → Error handling
3

Valid Data Processing

When validation passes, the workflow:
  • Sets success status
  • Generates unique ID with timestamp
  • Preserves original data
  • Adds processing metadata
4

Invalid Data Handling

When validation fails, the workflow:
  • Sets error status
  • Generates detailed error messages
  • Returns specific validation failures
  • Includes timestamp for logging
5

Merge and Respond

Both branches merge at a single point and send the appropriate response:
  • Valid: HTTP 200 with success message
  • Invalid: HTTP 400 with error details

Response Examples

Success Response (HTTP 200)

{
  "status": "success",
  "message": "Form submitted successfully",
  "data": {
    "name": "John Doe",
    "email": "[email protected]",
    "message": "This is a test message that is longer than 10 characters"
  },
  "timestamp": "2024-03-15T10:30:00.000Z",
  "id": "0-1710497400"
}

Error Response (HTTP 400)

{
  "status": "error",
  "message": "Validation failed: Please check email format, name, and message length (min 10 characters)",
  "errors": {
    "email": "Invalid email format",
    "name": "Name required",
    "message": "Message must be at least 10 characters"
  },
  "timestamp": "2024-03-15T10:30:00.000Z"
}
Production Tip: Consider adding rate limiting and authentication for public webhooks to prevent abuse.

Advanced Patterns

Add Database Storage

Insert a database node after valid data processing to persist submissions:
{
  "name": "Save to Database",
  "type": "n8n-nodes-base.postgres",
  "parameters": {
    "operation": "insert",
    "table": "form_submissions"
  }
}

Send Notifications

Add a Slack or email node to notify your team of new submissions:
{
  "name": "Notify Team",
  "type": "n8n-nodes-base.slack",
  "parameters": {
    "resource": "message",
    "operation": "post",
    "channel": "#notifications"
  }
}

Add Honeypot Protection

Include additional validation to detect bot submissions using hidden form fields.

Next Steps

Build docs developers (and LLMs) love