🏠 Home / Hub

n8n 04 — HTTP & Webhooks

The HTTP Request node and the Webhook trigger are the backbone of most n8n integrations. This lesson covers them in depth, including authentication, pagination, and error handling.

1. HTTP Request Node In Depth

The HTTP Request node can call any REST API — GET, POST, PUT, PATCH, DELETE. It handles JSON, form data, binary files, and more.

SettingOptions / Notes
MethodGET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
URLStatic or expression: https://api.example.com/users/{{ $json.id }}
AuthenticationNone, Basic, Header, OAuth2, Digest, AWS
Query ParametersKey-value pairs appended to URL
HeadersContent-Type, custom headers
Body Content TypeJSON, Form-Data, x-www-form-urlencoded, Raw, Binary
Response FormatAuto-detect, JSON, Text, File
OptionsTimeout, retry on fail, follow redirects, ignore SSL

2. Authentication Types

Header Auth (most common for API keys)

Name:  Authorization
Value: Bearer eyJhbGciOiJIUzI1NiJ9...

# Or for X-API-Key style:
Name:  X-API-Key
Value: your-api-key-here

Basic Auth

Username: myuser
Password: mypassword
# n8n auto-encodes as Base64 in Authorization header

OAuth2

1. Create OAuth2 credential (Client ID + Secret)
2. Set Authorization URL and Token URL from the service docs
3. Add required scopes (e.g. "read:users write:repos")
4. Click "Connect" — browser opens for user consent
5. n8n stores and auto-refreshes the token
Always use stored Credentials instead of pasting tokens directly into node fields. Credentials are encrypted and reusable.

3. Sending a JSON Body

# POST with JSON body (key-value mode)
Method: POST
URL: https://api.example.com/users
Body Content Type: JSON
Body Parameters:
  name  = {{ $json.name }}
  email = {{ $json.email }}
  role  = "viewer"

# POST with raw JSON (full control)
Body Content Type: JSON
Body (raw):
{
  "name": "{{ $json.name }}",
  "email": "{{ $json.email }}",
  "metadata": {
    "source": "n8n-automation",
    "createdAt": "{{ $now.toISO() }}"
  }
}

4. Pagination Handling

Many APIs return paginated results. Enable "Pagination" in the HTTP Request node options:

# Offset-based pagination (page 1, 2, 3...)
Pagination Type: Update a parameter in each request
Parameter: page
Start value: 1
Increment by: 1
Continue while: {{ $response.body.data.length > 0 }}

# Cursor-based pagination (next_cursor token)
Pagination Type: Response contains next URL
Next URL path: $.meta.next_page_url

# Max pages safety limit: set "Max Requests" = 20
Always set a "Max Requests" limit when paginating to prevent infinite loops if the API behaves unexpectedly.

5. Webhook Trigger — Testing with curl & Postman

# 1. Add Webhook node as trigger
# 2. Copy the "Test URL" shown in the node panel
# 3. Click "Execute Workflow" (puts n8n in listen mode)
# 4. Send a request from curl:

curl -X POST https://your-n8n.com/webhook-test/abc123 \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: mysecret" \
  -d '{
    "event": "form_submitted",
    "name": "Alice",
    "email": "alice@example.com"
  }'

# In Postman:
# Method: POST
# URL: (paste test URL)
# Body: raw / JSON
# Send — n8n captures the request
Use the "Test URL" during development — it captures one request and shows you the data, then you pin it for building the rest of the workflow without re-sending.

6. Webhook Response

By default, n8n returns 200 OK with { "message": "Workflow was started" } immediately. For custom responses, use the Respond to Webhook node.

# Respond to Webhook node settings:
Respond When: Last node finishes
Response Code: 200
Response Body: JSON
Response Data:
{
  "status": "success",
  "id": "{{ $('Save to DB').item.json.inserted_id }}",
  "message": "Record created"
}

# To return an error:
Response Code: 400
Response Body:
{
  "error": "Validation failed",
  "field": "email"
}

7. Building a REST Webhook Receiver

Full example: receive a form POST, validate it, append to Google Sheets, return a confirmation.

1. Webhook (POST /form-submit)
      ↓
2. Code Node — validate required fields
   const body = $input.first().json.body;
   if (!body.email) throw new Error('Email required');
   return [{ json: body }];
      ↓
3. Google Sheets — Append Row
   Sheet: "Leads"
   Columns: name, email, message, timestamp
      ↓
4. Respond to Webhook
   Code: 200
   Body: { "success": true, "message": "Thanks!" }

8. Error Handling for HTTP Requests

Retry on Fail

# In HTTP Request node → Options tab:
Retry On Fail: ON
Max Tries: 3
Wait Between Tries: 1000ms (1 second)

Check HTTP status code

# Enable "Include Response Headers and Status"
# Then in the next IF node:
{{ $json.statusCode }} equals 200   → success branch
{{ $json.statusCode }} not equals 200 → error branch

# Or check for specific error
{{ $json.statusCode }} >= 400  → handle error

On Error setting (per node)

Continue (ignore errors)     → workflow keeps running
Stop Workflow                → stops this branch
Continue With Error Output   → error data goes to next node
For critical integrations, use "Continue With Error Output" so you can log or alert on failures rather than silently swallowing them.

📌 Study Checklist