🔌N8N API Integration Fundamentals
Learn to connect N8N to any external service via APIs. This comprehensive guide covers HTTP methods, authentication, error handling, and real-world integration patterns.
Key Topics
- • HTTP methods (GET, POST, PUT, DELETE)
- • Authentication (API keys, OAuth, Basic Auth)
- • Request headers and query parameters
- • JSON payload construction
- • Response parsing and transformation
- • Error handling and retries
- • Rate limiting strategies
Prerequisites
- • Basic understanding of HTTP/REST APIs
- • N8N account (free tier included)
- • API key from your target service
- • Postman (optional, for API testing)
- • 60 minutes for complete setup
🔐Authentication Methods Deep Dive
1. API Key Authentication
Simplest method - key passed in header or URL parameter.
// Method 1: Header (Recommended)
Headers:
- X-API-Key: sk_live_xxxxxxxxxxxx
- Content-Type: application/json
// Method 2: Query Parameter
URL: https://api.example.com/data?apikey=sk_live_xxxxxxxxxxxx
// Method 3: Body
POST /api/endpoint
Body: {
"apiKey": "sk_live_xxxxxxxxxxxx",
"data": { ... }
}N8N Setup:
HTTP Request Node → Authentication → None + Custom Headers → Add Header "X-API-Key" with credential
2. Basic Authentication
Username and password encoded in Base64.
// Raw credentials username: john@example.com password: secure_password // Base64 encoded Authorization: Basic am9obkBleGFtcGxlLmNvbTpzZWN1cmVfcGFzc3dvcmQ= // N8N automatically encodes Node: HTTP Request Authentication: Basic Auth Username: john@example.com Password: secure_password
3. Bearer Token (JWT/OAuth)
Temporary token requiring refresh mechanism.
// Step 1: Get Access Token
POST https://auth.example.com/oauth/token
Body: {
"client_id": "your_client_id",
"client_secret": "your_secret",
"grant_type": "client_credentials"
}
Response: {
"access_token": "eyJhbGc...",
"expires_in": 3600
}
// Step 2: Use Token in API Calls
Headers:
- Authorization: Bearer eyJhbGc...
// Step 3: N8N - Store in workflow variables
Set Token Node → HTTP Request Node (use token variable)🔄HTTP Methods & Request Patterns
GET - Retrieve Data
// Simple GET URL: https://api.example.com/users/123 Method: GET Headers: - Authorization: Bearer token // With Query Parameters URL: https://api.example.com/users?status=active&limit=10 OR URL: https://api.example.com/users Query Parameters: - status: active - limit: 10 - offset: 0
POST - Create Data
// Standard POST
Method: POST
URL: https://api.example.com/users
Headers:
- Content-Type: application/json
- Authorization: Bearer token
Body (JSON):
{
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}
// N8N: Use JSON/RAW body, not x-www-form-urlencodedPUT/PATCH - Update Data
// PUT - Replace entire resource
Method: PUT
URL: https://api.example.com/users/123
Body: {
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin"
}
// PATCH - Partial update
Method: PATCH
URL: https://api.example.com/users/123
Body: {
"role": "admin" // Only update this field
}DELETE - Remove Data
// Simple DELETE
Method: DELETE
URL: https://api.example.com/users/123
Headers:
- Authorization: Bearer token
// Often returns 204 No Content or 200 with confirmation
Response: { "success": true, "message": "User deleted" }⚙️Response Handling & Data Transformation
Parse JSON Responses
// API Response
{
"data": {
"user": {
"id": 123,
"name": "John",
"contacts": [
{ "type": "email", "value": "john@example.com" },
{ "type": "phone", "value": "+1234567890" }
]
}
},
"status": "success"
}
// N8N - Access nested values
{{$json.data.user.id}} // = 123
{{$json.data.user.contacts[0].value}} // = john@example.com
// N8N - Transform data
Use Merge/Transform node:
{
"userId": "{{$json.data.user.id}}",
"email": "{{$json.data.user.contacts[0].value}}"
}Error Response Handling
// HTTP Request Node Error
Response Status: 400
Body: {
"error": "Invalid email format",
"code": "INVALID_INPUT"
}
// N8N - Add error handler
Continue on Fail: ON
↓
IF error occurred:
IF status === 404 → Log "User not found"
IF status === 401 → Log "Authentication failed"
IF status === 429 → Wait 60 seconds, retry
ELSE → Send alert emailArray/Batch Processing
// API returns array of items
[
{ "id": 1, "name": "Item A" },
{ "id": 2, "name": "Item B" },
{ "id": 3, "name": "Item C" }
]
// N8N - Loop through array
Loop Node:
For each item in response:
POST to another API with item data
Store result in database
// Or use Expression:
{{$json.map(item => ({...item, processed: true}))}}⚡Production Best Practices
Rate Limiting
- • Check API docs for rate limits
- • Add delays between requests
- • Implement exponential backoff
- • Cache responses when possible
- • Use batch endpoints if available
Reliability
- • Add retry logic for failed requests
- • Log all API calls for debugging
- • Validate response before processing
- • Store API responses in database
- • Monitor workflow execution history
Security
- • Store API keys as credentials
- • Never commit keys to version control
- • Use OAuth for user permissions
- • Validate SSL certificates
- • Audit API access logs
Performance
- • Use query parameters for filtering
- • Request only needed fields
- • Implement pagination for large results
- • Use webhooks instead of polling
- • Monitor execution times
🐛Debugging API Integration Issues
401 Unauthorized
Cause: Invalid/expired authentication
Fix: Verify API key, check header format, renew token
400 Bad Request
Cause: Malformed request body or invalid parameters
Fix: Validate JSON, check required fields, test in Postman first
429 Too Many Requests
Cause: Rate limit exceeded
Fix: Add delays, use batch endpoints, queue requests
503 Service Unavailable
Cause: API server down or overloaded
Fix: Implement retry with exponential backoff, add health checks
🔗Common API Integration Examples
Stripe Payment API
// Create a customer POST https://api.stripe.com/v1/customers Headers: - Authorization: Bearer sk_test_xxx - Content-Type: application/x-www-form-urlencoded Body: email=customer@example.com&name=John Doe // Create a payment intent POST https://api.stripe.com/v1/payment_intents Body: amount=2000¤cy=usd&customer=cus_xxx // N8N Workflow: Trigger → HTTP Request (Create Customer) → Set Customer ID → HTTP Request (Create Payment Intent) → Send confirmation email
Airtable Database API
// Create record
POST https://api.airtable.com/v0/appXXX/TableName
Headers:
- Authorization: Bearer patXXX.xxx
- Content-Type: application/json
Body:
{
"fields": {
"Name": "New Contact",
"Email": "contact@example.com",
"Status": "Active"
}
}
// Get records with filter
GET https://api.airtable.com/v0/appXXX/TableName
Query Parameters:
- filterByFormula: {Status}='Active'
- maxRecords: 100
- sort[0][field]: Created
- sort[0][direction]: descSlack Messaging API
// Post message to channel
POST https://slack.com/api/chat.postMessage
Headers:
- Authorization: Bearer xoxb-xxx
- Content-Type: application/json
Body:
{
"channel": "#general",
"text": "Workflow completed successfully!",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Status:* ✅ Complete\n*Records:* 42"
}
}
]
}
// N8N: Use Slack node or HTTP Request for advanced formattingGoogle Sheets API
// Append row to spreadsheet
POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:append
Headers:
- Authorization: Bearer ya29.xxx (OAuth2 token)
Query:
- valueInputOption: USER_ENTERED
Body:
{
"values": [
["2025-01-15", "John Doe", "john@example.com", "Active"]
]
}
// Read data from sheet
GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}
Response:
{
"values": [
["Date", "Name", "Email", "Status"],
["2025-01-15", "John Doe", "john@example.com", "Active"]
]
}🪝Webhook Setup Tutorial
What Are Webhooks?
Webhooks are HTTP callbacks that deliver real-time data when events occur, eliminating the need for polling APIs repeatedly.
Polling vs Webhooks
❌ Polling (inefficient)
- • Check API every 5 minutes
- • Waste API calls if no changes
- • Delayed data (up to 5 min)
- • Hits rate limits quickly
✅ Webhooks (efficient)
- • Instant notification on change
- • Only calls when needed
- • Real-time data delivery
- • Saves API quota
N8N Webhook Node Setup
// Step 1: Add Webhook node to N8N
Node: Webhook
HTTP Method: POST
Path: /my-custom-webhook
Authentication: None (or Header Auth for security)
// Step 2: Get webhook URL
Production: https://your-n8n.com/webhook/my-custom-webhook
Test: https://your-n8n.com/webhook-test/my-custom-webhook
// Step 3: Configure in external service
Example - GitHub webhook for new issues:
Payload URL: https://your-n8n.com/webhook/github-issues
Content type: application/json
Events: Issues → created
// Step 4: Process incoming data
{
"action": "opened",
"issue": {
"id": 123,
"title": "Bug report",
"body": "Description...",
"user": {
"login": "username"
}
}
}
// N8N: Access data with {{$json.issue.title}}Webhook Security Best Practices
- • Signature Verification: Validate webhook signatures (HMAC) to ensure requests are from trusted sources
- • Header Authentication: Add custom header like "X-Webhook-Secret" that must match expected value
- • IP Whitelisting: Only accept requests from known IP ranges (GitHub, Stripe provide IP lists)
- • HTTPS Only: Never use HTTP for webhooks - always require SSL/TLS encryption
- • Idempotency: Handle duplicate webhook deliveries gracefully (same event sent twice)
- • Timeout Handling: Respond within 5 seconds or service may retry (process async if needed)
✅Implementation Checklist
Want the full AI SaaS Builder playbook?
A complete ship operating system for building AI SaaS on Claude API, Next.js, Supabase, and Cursor AI. Six modules. From validation to deploy to launch to recurring revenue. Built by an operator who ships and sells.