n8n AI Automation Template
WorkflowReady-to-import n8n workflow for AI automation.
n8n AI Automation Template
Overview
Ready-to-import n8n workflow template for building AI-powered automation tasks. n8n is a powerful workflow automation platform that enables you to connect apps, APIs, and services with AI capabilities through a visual node-based interface.
What is n8n?
n8n (nodemation) is an open-source workflow automation tool that allows you to:
- Connect 300+ apps: Native integrations with popular services
- Visual workflow builder: Drag-and-drop node-based interface
- AI integration: Built-in AI nodes for OpenAI, LangChain, and more
- Self-hosted or cloud: Deploy on your infrastructure or use n8n.cloud
- Webhooks and triggers: Event-driven automation
- Code nodes: Custom JavaScript/TypeScript code execution
- Error handling: Built-in retry logic and error workflows
Template Structure
n8n-template/
├── workflows/
│ ├── ai-content-generator.json # Content generation workflow
│ ├── ai-data-processor.json # Data processing workflow
│ ├── ai-notification-system.json # Notification workflow
│ └── ai-approval-workflow.json # Approval workflow
├── credentials/
│ ├── openai.json # OpenAI API credentials template
│ ├── slack.json # Slack credentials template
│ ├── email.json # Email credentials template
│ └── webhook.json # Webhook configuration
├── nodes/
│ ├── custom-nodes/ # Custom node implementations
│ └── ai-prompts/ # Prompt templates
├── docs/
│ ├── setup-guide.md # Setup instructions
│ └── troubleshooting.md # Troubleshooting guide
├── docker/
│ ├── Dockerfile # Docker configuration
│ └── docker-compose.yml # Docker Compose setup
└── README.md
Installation
Option 1: n8n Cloud (Easiest)
# Sign up at https://n8n.io/pricing
# No installation required - use hosted service
Option 2: Self-Hosted with Docker
# Pull and run n8n
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
# Access at http://localhost:5678
Option 3: Docker Compose (Production)
# docker-compose.yml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
- N8N_HOST=n8n.yourdomain.com
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.yourdomain.com/
- GENERIC_TIMEZONE=UTC
- TZ=UTC
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_network
nginx:
image: nginx:alpine
container_name: n8n_nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- n8n
networks:
- n8n_network
volumes:
n8n_data:
networks:
n8n_network:
driver: bridge
# nginx.conf
events {
worker_connections 1024;
}
http {
upstream n8n {
server n8n:5678;
}
server {
listen 80;
server_name n8n.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.yourdomain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://n8n;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
Option 4: npm Global Install
# Install n8n globally
npm install n8n -g
# Run n8n
n8n start
# Or with tunnel for testing webhooks
n8n start --tunnel
Importing Workflows
Method 1: Import from File
- Open n8n editor at http://localhost:5678
- Click Workflows → Import from File
- Select the JSON workflow file
- Configure credentials
- Activate the workflow
Method 2: Import from URL
- Open n8n editor
- Click Workflows → Import from URL
- Paste the workflow URL
- Configure credentials
Method 3: Copy/Paste JSON
- Open n8n editor
- Click the canvas to focus
- Paste the workflow JSON (Ctrl+V / Cmd+V)
- Configure credentials
Core Nodes
Trigger Nodes
Webhook Trigger
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "your-webhook-id",
"httpMethod": "POST",
"path": "ai-process",
"responseMode": "responseNode",
"options": {}
}
Schedule Trigger
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [250, 300],
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * *" // Every day at 9 AM
}
]
}
}
Manual Trigger
{
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [250, 300]
}
AI Nodes
OpenAI Chat Model
{
"name": "OpenAI Chat Model",
"type": "n8n-nodes-base.openAiChatModel",
"typeVersion": 1,
"position": [400, 200],
"credentials": {
"openAiApi": {
"id": "your-credential-id",
"name": "OpenAI"
}
},
"parameters": {
"model": "gpt-4o",
"options": {
"temperature": 0.7,
"maxTokens": 4096
}
}
}
AI Agent
{
"name": "AI Agent",
"type": "n8n-nodes-base.aiAgent",
"typeVersion": 1,
"position": [600, 300],
"parameters": {
"agentType": "conversationalAgent",
"prompt": "You are a helpful assistant. Answer questions based on the context provided.",
"options": {
"systemMessage": "You are a helpful AI assistant.",
"maxIterations": 5
}
}
}
AI Chain
{
"name": "AI Chain",
"type": "n8n-nodes-base.aiChain",
"typeVersion": 1,
"position": [600, 400],
"parameters": {
"chainType": "stuff",
"prompt": {
"promptTemplate": "Based on the following context: {{context}}\n\nQuestion: {{question}}\n\nAnswer:"
},
"options": {}
}
}
LangChain Memory
{
"name": "Buffer Memory",
"type": "n8n-nodes-base.bufferMemory",
"typeVersion": 1,
"position": [400, 400],
"parameters": {
"memorySize": 10,
"options": {}
}
}
Vector Store
{
"name": "Chroma Vector Store",
"type": "n8n-nodes-base.chromaVectorStore",
"typeVersion": 1,
"position": [400, 500],
"credentials": {
"chromaApi": {
"id": "your-credential-id",
"name": "Chroma"
}
},
"parameters": {
"collectionName": "my-documents",
"options": {}
}
}
Action Nodes
HTTP Request
{
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [800, 300],
"parameters": {
"method": "POST",
"url": "https://api.example.com/endpoint",
"authentication": "genericCredentialType",
"genericAuthType": "openAiApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParametersJson": "{\n \"key\": \"value\"\n}",
"options": {
"timeout": 30000
}
}
}
Code Node
{
"name": "Code",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [800, 400],
"parameters": {
"jsCode": "// Process the data\nconst items = $input.all();\n\nreturn items.map(item => {\n const data = item.json;\n \n // Custom processing logic\n return {\n json: {\n ...data,\n processed: true,\n timestamp: new Date().toISOString()\n }\n };\n});",
"options": {}
}
}
Set Node
{
"name": "Set",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [800, 500],
"parameters": {
"values": {
"json": [
{
"name": "result",
"value": "={{ $json.ai_response }}"
}
]
},
"options": {}
}
}
Merge Node
{
"name": "Merge",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [1000, 300],
"parameters": {
"mode": "combine",
"options": {}
}
}
Switch Node
{
"name": "Switch",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [800, 600],
"parameters": {
"rules": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json.status }}",
"rightValue": "success",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
"options": {}
}
}
Wait Node
{
"name": "Wait",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [800, 700],
"parameters": {
"resume": "string",
"waitUntil": "={{ $now.plus({ hours: 1 }).toISO() }}",
"options": {}
}
}
Error Trigger
{
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1,
"position": [250, 500],
"parameters": {}
}
Example Workflows
Workflow 1: AI Content Generator
{
"name": "AI Content Generator",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "content-gen-webhook",
"httpMethod": "POST",
"path": "generate-content",
"responseMode": "responseNode"
},
{
"name": "OpenAI Chat Model",
"type": "n8n-nodes-base.openAiChatModel",
"typeVersion": 1,
"position": [450, 200],
"credentials": {
"openAiApi": { "id": "openai-cred", "name": "OpenAI" }
},
"parameters": {
"model": "gpt-4o",
"options": { "temperature": 0.7 }
}
},
{
"name": "AI Agent",
"type": "n8n-nodes-base.aiAgent",
"typeVersion": 1,
"position": [650, 300],
"parameters": {
"agentType": "conversationalAgent",
"prompt": "You are a content writer. Create engaging blog posts.",
"model": "={{ $node['OpenAI Chat Model'].json }}"
}
},
{
"name": "Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [850, 300],
"credentials": {
"slackApi": { "id": "slack-cred", "name": "Slack" }
},
"parameters": {
"operation": "post",
"channel": "#content",
"text": "={{ $json.output }}"
}
},
{
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [850, 450],
"parameters": {
"respondWith": "json",
"responseBody": "{\n \"status\": \"success\",\n \"content\": \"{{ $json.output }}\"\n}"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]] },
"OpenAI Chat Model": { "aiModel": [[{ "node": "AI Agent", "type": "aiModel", "index": 0 }]] },
"AI Agent": { "main": [[{ "node": "Slack", "type": "main", "index": 0 }], [{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] }
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": ["AI", "Content", "Automation"],
"triggerCount": 0,
"updatedAt": "2026-05-15T00:00:00.000Z",
"versionId": "1.0.0"
}
Workflow 2: AI Data Processor
{
"name": "AI Data Processor",
"nodes": [
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [250, 300],
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 0 * * *" }]
}
},
{
"name": "HTTP Request - Fetch Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [450, 200],
"parameters": {
"method": "GET",
"url": "https://api.example.com/data",
"options": {}
}
},
{
"name": "OpenAI Chat Model",
"type": "n8n-nodes-base.openAiChatModel",
"typeVersion": 1,
"position": [450, 400],
"credentials": {
"openAiApi": { "id": "openai-cred", "name": "OpenAI" }
},
"parameters": {
"model": "gpt-4o",
"options": { "temperature": 0 }
}
},
{
"name": "AI Agent - Analyze",
"type": "n8n-nodes-base.aiAgent",
"typeVersion": 1,
"position": [650, 300],
"parameters": {
"agentType": "conversationalAgent",
"prompt": "Analyze the following data and provide insights. Format as JSON.",
"model": "={{ $node['OpenAI Chat Model'].json }}"
}
},
{
"name": "Code - Format Output",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [850, 200],
"parameters": {
"jsCode": "const analysis = $input.first().json;\nreturn {\n json: {\n summary: analysis.output,\n timestamp: new Date().toISOString(),\n source: 'daily-automation'\n }\n};"
}
},
{
"name": "Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [1050, 200],
"credentials": {
"googleSheetsOAuth2Api": { "id": "sheets-cred", "name": "Google Sheets" }
},
"parameters": {
"operation": "append",
"sheetId": "your-sheet-id",
"options": {}
}
},
{
"name": "Email Send",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [1050, 400],
"credentials": {
"smtp": { "id": "smtp-cred", "name": "SMTP" }
},
"parameters": {
"toEmail": "team@example.com",
"subject": "Daily Data Analysis Report",
"message": "={{ $json.summary }}",
"options": {}
}
}
],
"connections": {
"Schedule Trigger": { "main": [[{ "node": "HTTP Request - Fetch Data", "type": "main", "index": 0 }]] },
"HTTP Request - Fetch Data": { "main": [[{ "node": "AI Agent - Analyze", "type": "main", "index": 0 }]] },
"OpenAI Chat Model": { "aiModel": [[{ "node": "AI Agent - Analyze", "type": "aiModel", "index": 0 }]] },
"AI Agent - Analyze": { "main": [[{ "node": "Code - Format Output", "type": "main", "index": 0 }]] },
"Code - Format Output": { "main": [[{ "node": "Google Sheets", "type": "main", "index": 0 }, { "node": "Email Send", "type": "main", "index": 0 }]] }
},
"settings": { "executionOrder": "v1" },
"staticData": null,
"tags": ["AI", "Data", "Automation", "Daily"],
"triggerCount": 0,
"updatedAt": "2026-05-15T00:00:00.000Z",
"versionId": "1.0.0"
}
Workflow 3: AI Notification System
{
"name": "AI Notification System",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "notify-webhook",
"httpMethod": "POST",
"path": "notify",
"responseMode": "responseNode"
},
{
"name": "IF - Check Priority",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [450, 250],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.priority }}",
"operation": "equals",
"value2": "high"
}
]
}
}
},
{
"name": "OpenAI - Summarize",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1,
"position": [650, 150],
"credentials": {
"openAiApi": { "id": "openai-cred", "name": "OpenAI" }
},
"parameters": {
"resource": "chat",
"operation": "create",
"model": "gpt-4o-mini",
"messages": [
{
"content": "Summarize this notification in 2 sentences: {{ $json.message }}",
"role": "user"
}
]
}
},
{
"name": "Slack - High Priority",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [650, 350],
"credentials": {
"slackApi": { "id": "slack-cred", "name": "Slack" }
},
"parameters": {
"operation": "post",
"channel": "#alerts",
"text": "🚨 HIGH PRIORITY: {{ $json.message }}",
"otherOptions": {
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "🚨 High Priority Alert" }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{{ $json.message }}" }
}
]
}
}
},
{
"name": "Email - Normal",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [850, 350],
"credentials": {
"smtp": { "id": "smtp-cred", "name": "SMTP" }
},
"parameters": {
"toEmail": "team@example.com",
"subject": "Notification: {{ $json.title }}",
"message": "={{ $json.message }}",
"options": {}
}
},
{
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [850, 150],
"parameters": {
"respondWith": "json",
"responseBody": "{\n \"status\": \"delivered\",\n \"channel\": \"{{ $json.channel }}\"\n}"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "IF - Check Priority", "type": "main", "index": 0 }]] },
"IF - Check Priority": {
"main": [
[{ "node": "OpenAI - Summarize", "type": "main", "index": 0 }],
[{ "node": "Email - Normal", "type": "main", "index": 0 }]
]
},
"OpenAI - Summarize": { "main": [[{ "node": "Slack - High Priority", "type": "main", "index": 0 }]] },
"Slack - High Priority": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] },
"Email - Normal": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] }
},
"settings": { "executionOrder": "v1" },
"staticData": null,
"tags": ["AI", "Notification", "Alerts"],
"triggerCount": 0,
"updatedAt": "2026-05-15T00:00:00.000Z",
"versionId": "1.0.0"
}
Workflow 4: AI Approval Workflow
{
"name": "AI Approval Workflow",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "approval-webhook",
"httpMethod": "POST",
"path": "request-approval",
"responseMode": "responseNode"
},
{
"name": "OpenAI - Evaluate",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1,
"position": [450, 200],
"credentials": {
"openAiApi": { "id": "openai-cred", "name": "OpenAI" }
},
"parameters": {
"resource": "chat",
"operation": "create",
"model": "gpt-4o",
"messages": [
{
"content": "You are an approval evaluator. Review the following request and determine if it should be approved based on these criteria:\n\n1. Budget under $10,000\n2. Within project scope\n3. No compliance issues\n\nRequest: {{ $json.request }}\n\nRespond with JSON: {\"approved\": true/false, \"reason\": \"explanation\", \"confidence\": 0-1}",
"role": "system"
},
{
"content": "{{ $json.request }}",
"role": "user"
}
],
"options": { "temperature": 0.1 }
}
},
{
"name": "Code - Parse Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [650, 200],
"parameters": {
"jsCode": "const response = $input.first().json;\ntry {\n const parsed = JSON.parse(response.message.content);\n return { json: parsed };\n} catch (e) {\n return { json: { approved: false, reason: 'Failed to parse AI response', confidence: 0 } };\n}"
}
},
{
"name": "IF - Approved?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [850, 150],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.approved }}",
"value2": true
}
]
}
}
},
{
"name": "Slack - Approved",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [1050, 100],
"credentials": {
"slackApi": { "id": "slack-cred", "name": "Slack" }
},
"parameters": {
"operation": "post",
"channel": "#approvals",
"text": "✅ Approved: {{ $json.reason }}\nConfidence: {{ $json.confidence }}",
"otherOptions": {
"blocks": [
{
"type": "section",
"text": { "type": "mrkdwn", "text": "✅ *Approval Granted*\n{{ $json.reason }}\n\nConfidence: {{ $json.confidence }}" }
}
]
}
}
},
{
"name": "Slack - Needs Review",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [1050, 250],
"credentials": {
"slackApi": { "id": "slack-cred", "name": "Slack" }
},
"parameters": {
"operation": "post",
"channel": "#approvals",
"text": "⚠️ Needs Human Review: {{ $json.reason }}",
"otherOptions": {
"blocks": [
{
"type": "section",
"text": { "type": "mrkdwn", "text": "⚠️ *Needs Human Review*\n{{ $json.reason }}\n\nPlease review manually." }
}
]
}
}
},
{
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [1250, 150],
"parameters": {
"respondWith": "json",
"responseBody": "{\n \"status\": \"{{ $json.approved ? 'approved' : 'needs_review' }}\",\n \"reason\": \"{{ $json.reason }}\",\n \"confidence\": {{ $json.confidence }}\n}"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "OpenAI - Evaluate", "type": "main", "index": 0 }]] },
"OpenAI - Evaluate": { "main": [[{ "node": "Code - Parse Response", "type": "main", "index": 0 }]] },
"Code - Parse Response": { "main": [[{ "node": "IF - Approved?", "type": "main", "index": 0 }]] },
"IF - Approved?": {
"main": [
[{ "node": "Slack - Approved", "type": "main", "index": 0 }],
[{ "node": "Slack - Needs Review", "type": "main", "index": 0 }]
]
},
"Slack - Approved": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] },
"Slack - Needs Review": { "main": [[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]] }
},
"settings": { "executionOrder": "v1" },
"staticData": null,
"tags": ["AI", "Approval", "Workflow"],
"triggerCount": 0,
"updatedAt": "2026-05-15T00:00:00.000Z",
"versionId": "1.0.0"
}
Credentials Setup
OpenAI Credentials
{
"name": "OpenAI",
"data": {
"apiKey": "sk-..."
},
"type": "openAiApi",
"typeVersion": 1
}
Slack Credentials
{
"name": "Slack",
"data": {
"accessToken": "xoxb-..."
},
"type": "slackApi",
"typeVersion": 1
}
Google Sheets Credentials
- Create Google Cloud project
- Enable Google Sheets API
- Create OAuth 2.0 credentials
- Download credentials JSON
- Import in n8n
SMTP Credentials
{
"name": "SMTP",
"data": {
"host": "smtp.example.com",
"port": 587,
"secure": false,
"auth": {
"user": "your-email@example.com",
"pass": "your-app-password"
}
},
"type": "smtp",
"typeVersion": 1
}
Environment Variables
# .env file
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your-secure-password
N8N_HOST=n8n.yourdomain.com
N8N_PROTOCOL=https
N8N_PORT=5678
N8N_PATH_BASE=/
WEBHOOK_URL=https://n8n.yourdomain.com/
GENERIC_TIMEZONE=UTC
TZ=UTC
N8N_ENCRYPTION_KEY=your-encryption-key
N8N_USER_MANAGEMENT_JWT_SECRET=your-jwt-secret
Security Best Practices
Authentication
# Enable basic auth
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=<strong-password>
# Enable JWT auth for user management
N8N_USER_MANAGEMENT_ENABLED=true
N8N_USER_MANAGEMENT_JWT_SECRET=<random-secret>
HTTPS Configuration
# Use SSL termination at reverse proxy
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Webhook Security
// Add webhook authentication
{
"name": "Webhook",
"parameters": {
"httpMethod": "POST",
"path": "secure-webhook",
"responseMode": "responseNode",
"options": {
"authentication": "headerAuth",
"headerAuth": {
"name": "Authorization",
"value": "Bearer {{ $env.WEBHOOK_SECRET }}"
}
}
}
}
Credential Encryption
# Generate encryption key
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
# Store securely (e.g., in secrets manager)
echo "N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY" >> .env
Monitoring and Logging
Execution History
- View all workflow executions in n8n UI
- Filter by status (success, error, waiting)
- View execution details and data
Webhook Monitoring
# Check webhook logs
docker logs n8n | grep webhook
# Or access n8n logs
docker exec -it n8n cat /home/node/.n8n/logs/main.log
Error Handling
// Add error trigger workflow
{
"name": "Error Handler",
"nodes": [
{
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1
},
{
"name": "Slack - Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"operation": "post",
"channel": "#errors",
"text": "⚠️ Workflow Error: {{ $json.workflow.name }}"
}
}
],
"connections": {
"Error Trigger": { "main": [[{ "node": "Slack - Alert" }]] }
}
}
Best Practices
Workflow Design
- Modular workflows: Break complex workflows into smaller ones
- Use sub-workflows: Call other workflows with Execute Workflow node
- Error handling: Always add error paths
- Documentation: Add notes to nodes explaining their purpose
- Version control: Export workflows regularly for backup
Performance Optimization
- Batch processing: Process items in batches for large datasets
- Caching: Use cache for repeated API calls
- Parallel execution: Use parallel branches for independent tasks
- Pagination: Handle paginated API responses properly
- Rate limiting: Respect API rate limits with wait nodes
Security
- Use environment variables: Store secrets in env vars, not in workflows
- Validate inputs: Sanitize webhook inputs
- Use HTTPS: Always use HTTPS for webhooks
- Limit permissions: Use minimal required API scopes
- Regular audits: Review workflow permissions regularly
Troubleshooting
Common Issues
Workflow not executing:
- Check if workflow is activated
- Verify trigger is configured correctly
- Check execution logs for errors
API credential errors:
- Verify API keys are correct and not expired
- Check API scopes/permissions
- Ensure credentials are properly configured
Webhook not receiving requests:
- Verify webhook URL is correct
- Check firewall/network settings
- Ensure n8n is accessible from the internet
Execution timeout:
- Increase timeout in node settings
- Break workflow into smaller parts
- Use async processing for long tasks
Debugging
// Add debug logging in Code node
console.log('Input data:', JSON.stringify($input.all(), null, 2));
console.log('Environment:', process.env);
// Return debug info
return {
json: {
...result,
_debug: {
inputCount: $input.all().length,
timestamp: new Date().toISOString()
}
}
};
Resources
- n8n Documentation: https://docs.n8n.io/
- n8n Templates: https://n8n.io/workflows
- n8n Community: https://community.n8n.io/
- n8n GitHub: https://github.com/n8n-io/n8n
- n8n Discord: https://discord.gg/n8n
Last updated: May 2026
