Skip to main content
โšก Calmops

n8n Webhooks and API Integration: Complete Guide

Introduction

Webhooks and API integrations are the backbone of modern automation. n8n provides powerful nodes for both receiving events via webhooks and making outbound API calls. This guide covers everything you need to build robust webhook-powered workflows and integrate with any API.

Understanding Webhooks in n8n

How Webhooks Work

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Webhook Flow                                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                      โ”‚
โ”‚  External Service              n8n                                    โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€            โ”€โ”€โ”€โ”€โ”€โ”€                                   โ”‚
โ”‚                                                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                           โ”‚
โ”‚  โ”‚ Stripe   โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚ Webhook  โ”‚                           โ”‚
โ”‚  โ”‚ Payment  โ”‚   HTTP POST    โ”‚ Trigger  โ”‚                           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜                           โ”‚
โ”‚                                 โ”‚                                    โ”‚
โ”‚                                 โ–ผ                                    โ”‚
โ”‚                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                           โ”‚
โ”‚                          โ”‚   Process    โ”‚                           โ”‚
โ”‚                          โ”‚   Request    โ”‚                           โ”‚
โ”‚                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                           โ”‚
โ”‚                                 โ”‚                                    โ”‚
โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ”‚
โ”‚                    โ–ผ            โ–ผ            โ–ผ                      โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚              โ”‚  Update  โ”‚ โ”‚   Send   โ”‚ โ”‚   Call   โ”‚                โ”‚
โ”‚              โ”‚  Databaseโ”‚ โ”‚   Slack  โ”‚ โ”‚   API    โ”‚                โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Webhook Types

Type Trigger Use Case
Production Real-time events Payment processing
Test Manual test Development
Webhook Standard HTTP General purpose
REST Hook Subscription-based Long-lived events

Receiving Webhooks

Basic Webhook Setup

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Webhook Configuration                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                      โ”‚
โ”‚  Webhook Node:                                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚  โ”‚                                             โ”‚                   โ”‚
โ”‚  โ”‚  Path: my-webhook                          โ”‚                   โ”‚
โ”‚  โ”‚  Method: POST                               โ”‚                   โ”‚
โ”‚  โ”‚  Response Mode: On Received                 โ”‚                   โ”‚
โ”‚  โ”‚  Response Data: All Entries                 โ”‚                   โ”‚
โ”‚  โ”‚                                             โ”‚                   โ”‚
โ”‚  โ”‚  Webhook URL:                               โ”‚                   โ”‚
โ”‚  โ”‚  https://your-n8n.com/webhook/my-webhook   โ”‚                   โ”‚
โ”‚  โ”‚                                             โ”‚                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Configuration Options

# Webhook Node Settings
{
  "path": "stripe-payment",
  "method": "POST",
  "responseMode": "onReceived",
  "responseData": "allEntries",
  "options": {
    "rawBody": false,
    "headerAuthentication": {
      "type": "Bearer Token",
      "property": "authorization"
    }
  }
}

Handling Different Methods

# Handle GET, POST, PUT, DELETE
Method: "{{ $input.params.method }}"

# Access in workflow
{{ $input.body }}           # Request body
{{ $input.params }}         # Query parameters
{{ $input.headers }}        # Request headers
{{ $input.files }}          # Uploaded files

Responding to Webhooks

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Webhook Response                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                      โ”‚
โ”‚  Node: Respond to Webhook                                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                       โ”‚
โ”‚  โ”‚                                          โ”‚                       โ”‚
โ”‚  โ”‚  Response Body:                          โ”‚                       โ”‚
โ”‚  โ”‚  {                                       โ”‚                       โ”‚
โ”‚  โ”‚    "status": "success",                  โ”‚                       โ”‚
โ”‚  โ”‚    "message": "Order received",          โ”‚                       โ”‚
โ”‚  โ”‚    "order_id": "{{ $json.order_id }}"   โ”‚                       โ”‚
โ”‚  โ”‚  }                                       โ”‚                       โ”‚
โ”‚  โ”‚                                          โ”‚                       โ”‚
โ”‚  โ”‚  Response Status Code: 200               โ”‚                       โ”‚
โ”‚  โ”‚  Response Headers: Content-Type: json     โ”‚                       โ”‚
โ”‚  โ”‚                                          โ”‚                       โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ”‚
โ”‚                                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Making API Calls

HTTP Request Node

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    HTTP Request Node                                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                      Configuration                          โ”‚    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  Method: GET / POST / PUT / DELETE / PATCH                  โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  URL: https://api.example.com/v1/endpoint                   โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  Authentication:                                             โ”‚    โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ None                                                   โ”‚    โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ Basic Auth                                             โ”‚    โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ Bearer Token                                           โ”‚    โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ API Key                                                โ”‚    โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ OAuth2                                                 โ”‚    โ”‚
โ”‚  โ”‚  โ””โ”€โ”€ Header Auth                                            โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  Headers:                                                    โ”‚    โ”‚
โ”‚  โ”‚  Content-Type: application/json                             โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  Body:                                                      โ”‚    โ”‚
โ”‚  โ”‚  {                                                           โ”‚    โ”‚
โ”‚  โ”‚    "data": "{{ $json.data }}"                               โ”‚    โ”‚
โ”‚  โ”‚  }                                                           โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ”‚  Query Parameters:                                           โ”‚    โ”‚
โ”‚  โ”‚  limit: 100                                                  โ”‚    โ”‚
โ”‚  โ”‚  offset: 0                                                  โ”‚    โ”‚
โ”‚  โ”‚                                                              โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Authentication Methods

Bearer Token

Authentication:
  Type: Bearer Token
  Token: "{{ $credentials.api_token }}"

Basic Auth

Authentication:
  Type: Basic Auth
  User: "{{ $credentials.username }}"
  Password: "{{ $credentials.password }}"

API Key

Authentication:
  Type: API Key
  Header: X-API-Key
  Value: "{{ $credentials.api_key }}"

OAuth2

Authentication:
  Type: OAuth2
  Client ID: "{{ $credentials.client_id }}"
  Client Secret: "{{ $credentials.client_secret }}"
  Authorization URL: https://provider.com/oauth/authorize
  Access Token URL: https://provider.com/oauth/token
  Scopes: read write

Request Body Examples

# JSON Body
Body Content:
{
  "name": "{{ $json.name }}",
  "email": "{{ $json.email }}",
  "metadata": {
    "source": "webhook",
    "timestamp": "{{ $now.toISOString() }}"
  }
}

# Form Data
Body Content Type: Form URL Encoded
Body: name=John&[email protected]

# Raw Body (for files)
Body Content Type: Binary File

Advanced API Patterns

Pagination

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Handling Pagination                               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                   โ”‚
โ”‚  โ”‚   Trigger   โ”‚                                                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                   โ”‚
โ”‚         โ”‚                                                          โ”‚
โ”‚         โ–ผ                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                   โ”‚
โ”‚  โ”‚   HTTP      โ”‚ โ”€โ”€โ–บ GET /users?page=1                           โ”‚
โ”‚  โ”‚   Request   โ”‚                                                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                   โ”‚
โ”‚         โ”‚                                                          โ”‚
โ”‚         โ–ผ                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                   โ”‚
โ”‚  โ”‚    If       โ”‚ โ”€โ”€โ–บ {{ $json.hasMore === true }}                โ”‚
โ”‚  โ”‚             โ”‚                                                   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                   โ”‚
โ”‚     โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”                                                       โ”‚
โ”‚     โ”‚       โ”‚                                                       โ”‚
โ”‚    YES     NO                                                       โ”‚
โ”‚     โ”‚       โ”‚                                                       โ”‚
โ”‚     โ–ผ       โ–ผ                                                       โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚ โ”‚  Wait   โ”‚ โ”‚ Continue   โ”‚                                        โ”‚
โ”‚ โ”‚ (rate)  โ”‚ โ”‚             โ”‚                                        โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚      โ”‚                                                              โ”‚
โ”‚      โ–ผ                                                              โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                     โ”‚
โ”‚ โ”‚ Loop Back   โ”‚ โ—„โ”€โ”€ Increment page                                โ”‚
โ”‚ โ”‚ to HTTP     โ”‚                                                   โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                     โ”‚
โ”‚                                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Code Implementation

// Using Split In Batches for pagination
const response = await $input.first();
const data = response.json;

// Get pagination info
const nextPage = response.json.next_page;
const hasMore = response.json.has_more;

// Store for next iteration
$input.first().json.hasMore = hasMore;
$input.first().json.nextPage = nextPage;

return [{
  json: {
    items: data.items,
    hasMore: hasMore || false,
    nextPage: nextPage
  }
}];

Rate Limiting

# Using Wait node for rate limiting
1. HTTP Request (Batch 1)
2. If: more_pages === true
3. Wait: 1000ms (respect API limits)
4. HTTP Request (Batch 2)

Retry Logic

# Automatic retry configuration
{
  "retryOnFail": true,
  "maxTries": 3,
  "wait": 1000,
  "maxWait": 10000
}

Error Handling for API Calls

# Handle API errors
1. HTTP Request
   - Continue on Fail: true
   
2. If Error Exists
   - Log to database
   - Notify via Slack
   
3. If Success
   - Continue processing
// Error handling in Code node
try {
  const response = await axios.get(url);
  return { success: true, data: response.data };
} catch (error) {
  // Check for specific errors
  if (error.response?.status === 429) {
    // Rate limited - retry
    throw new Error('Rate limited - should retry');
  }
  
  if (error.response?.status === 401) {
    // Unauthorized - notify
    return { 
      success: false, 
      error: 'Authentication failed',
      action: 'notify_admin'
    };
  }
  
  // Other errors
  return { success: false, error: error.message };
}

Real-World Examples

Stripe Payment Processing

# Stripe Webhook Handler

1. Webhook Trigger
   Path: stripe-webhook
   Headers: stripe-signature
   
2. Code (Verify Signature)
   - Verify Stripe signature
   - Parse event
   
3. Switch (Event Type)
   - payment_intent.succeeded โ†’ Process Order
   - payment_intent.payment_failed โ†’ Notify Customer
   - customer.subscription.created โ†’ Create Subscription
   - invoice.payment_failed โ†’ Send Alert

4. Database (Update)
   - Update order status
   
5. Slack/Email (Notify)
   - Send confirmation

GitHub Integration

# GitHub Webhook Handler

1. Webhook Trigger
   Path: github-webhook
   
2. Switch (Event Type)
   - push โ†’ Run Build
   - pull_request โ†’ Run Tests
   - issues.opened โ†’ Create Task in Linear
   - release.published โ†’ Deploy & Notify

3. Conditional Logic
   - Branch filter
   - Repository filter

CRM Data Sync

# Two-way CRM Sync

Direction 1: External โ†’ n8n
1. Webhook Trigger (receive CRM updates)
2. Process data
3. Update local database

Direction 2: n8n โ†’ External
1. Schedule Trigger (every hour)
2. Fetch changes from database
3. Batch API calls to CRM
4. Handle conflicts
5. Log sync status

Working with GraphQL

GraphQL in n8n

# Using HTTP Request for GraphQL
{
  "method": "POST",
  "url": "https://api.github.com/graphql",
  "authentication": "Bearer",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "query": "query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { name description } }",
    "variables": {
      "owner": "{{ $json.owner }}",
      "name": "{{ $json.repo }}"
    }
  }
}

GraphQL vs REST

Feature REST GraphQL
Multiple endpoints Multiple Single
Data shape Fixed Flexible
Over-fetching Common Avoided
Under-fetching Common Avoided
Caching Simple Complex
Learning curve Lower Higher

Best Practices

Good Patterns

# Good: Validate webhook source
1. Webhook Trigger
2. Code: Verify signature/secret
3. If invalid โ†’ Stop & Error

# Good: Handle idempotency
1. Webhook Trigger
2. Code: Check if processed (ID)
3. If new โ†’ Process
4. If exists โ†’ Skip (prevent duplicates)

# Good: Timeout handling
{
  "timeout": 30000,
  "maxTimeout": 60000
}

Bad Patterns

# Bad: No authentication on webhooks
# Always validate webhook source!

# Bad: Storing secrets in workflow
# Use Credentials instead!

# Bad: Not handling errors
# Always add error handling!

Security

Webhook Security

# Add webhook verification
1. Webhook Trigger
   - Enable header authentication
   - Set expected header
   
2. Code Node
   - Verify signature/hmac
   - Validate source IP
   - Check timestamp (prevent replay)

API Key Security

# Never expose credentials
# GOOD: Use n8n credentials
Authentication:
  Type: API Key
  Credentials: My API Key (saved)

# BAD: Hardcode in workflow
URL: https://api.com?key=secret123

Testing Webhooks

Testing Tools

# Using curl
curl -X POST https://your-n8n.com/webhook/test \
  -H "Content-Type: application/json" \
  -d '{"event": "test", "data": {"id": 123}}'

# Using n8n test button
# Click "Test workflow" in editor
# n8n sends test webhook

Local Development

# Use ngrok for local testing
ngrok http 5678

# Configure webhook URL in external service
# to ngrok URL

Monitoring and Debugging

Execution Logging

# Enable detailed logging
{
  "logExecution": "always",
  "saveDataOnError": "all"
}

Health Checks

# Monitor webhook health
1. Schedule Trigger (every 5 min)
2. HTTP Request โ†’ health endpoint
3. If: health === unhealthy
4. Slack โ†’ Alert team

Conclusion

Mastering webhooks and API integration in n8n opens endless automation possibilities. Always validate webhook sources, handle errors gracefully, and implement proper authentication for secure integrations.

Resources

Comments