Appearance
n8n Workflow Automation Cheat Sheet
Overview
n8n is a powerful, open-source workflow automation platform that enables users to connect different systems, services, and APIs to create automated workflows with minimal coding. What sets n8n apart from other automation tools is its unique combination of flexibility, extensibility, and AI capabilities, making it suitable for both simple automations and complex enterprise workflows.
As a self-hostable solution, n8n gives users complete control over their data and workflows, addressing privacy and security concerns that come with cloud-only solutions. Its node-based visual interface allows for intuitive workflow creation while still providing the depth and customization options that technical users need. With support for JavaScript transformations, conditional logic, error handling, and a growing library of integrations, n8n has emerged as a favorite among developers and technical teams looking to automate processes without sacrificing control or capabilities.
In the AI era, n8n has positioned itself as a key tool for orchestrating AI workflows, with built-in nodes for popular AI services and the ability to create custom integrations with any API-accessible AI model or service. This makes it an essential tool for organizations looking to incorporate AI into their business processes while maintaining governance and control.
Installation and Setup
Self-Hosted Installation
bash
# Using npm
npm install n8n -g
n8n start
# Using Docker
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
# Using Docker Compose
# Create docker-compose.yml with:
# version: '3'
# services:
# n8n:
# image: n8nio/n8n
# restart: always
# ports:
# - "5678:5678"
# volumes:
# - ~/.n8n:/home/node/.n8n
# environment:
# - N8N_ENCRYPTION_KEY=your-secret-key
# - N8N_PROTOCOL=https
# - N8N_HOST=n8n.example.com
docker-compose up -d
Cloud Installation
n8n offers a cloud version at n8n.cloud with various pricing tiers, from free to enterprise.
Environment Configuration
bash
# Basic configuration
export N8N_ENCRYPTION_KEY=your-secret-key
export N8N_PROTOCOL=https
export N8N_HOST=n8n.example.com
export N8N_PORT=5678
# Database configuration (PostgreSQL)
export DB_TYPE=postgresdb
export DB_POSTGRESDB_HOST=postgres
export DB_POSTGRESDB_PORT=5432
export DB_POSTGRESDB_DATABASE=n8n
export DB_POSTGRESDB_USER=n8n
export DB_POSTGRESDB_PASSWORD=password
# Queue configuration (Redis)
export QUEUE_BULL_REDIS_HOST=redis
export QUEUE_BULL_REDIS_PORT=6379
# Authentication
export N8N_BASIC_AUTH_ACTIVE=true
export N8N_BASIC_AUTH_USER=admin
export N8N_BASIC_AUTH_PASSWORD=password
Core Concepts
Workflows
Workflows are the main building blocks in n8n. They consist of nodes connected together to define a process flow.
Nodes
Nodes represent actions, triggers, or operations in a workflow. Each node has specific functionality, like sending an email, querying a database, or processing data.
Connections
Connections link nodes together, defining the flow of data from one node to another.
Triggers
Triggers are special nodes that start a workflow execution, such as webhooks, schedules, or events from external systems.
Executions
Executions are instances of a workflow being run, either manually or automatically triggered.
Basic Workflow Creation
Creating a New Workflow
- Navigate to the n8n interface (default:
n8n.example.com
) - Click "Workflows" in the sidebar
- Click "Create new workflow"
- Enter a name for your workflow
- Click "Save"
Adding and Connecting Nodes
- Click the "+" button to add a node
- Search for the desired node type
- Configure the node's settings
- Connect nodes by dragging from the output dot of one node to the input dot of another
- Click "Execute workflow" to test
Basic Workflow Example
javascript
// HTTP Request Node Configuration
{
"url": "https://api.example.com/data",
"method": "GET",
"authentication": "Basic Auth",
"username": "user",
"password": "pass"
}
// Function Node to Transform Data
function transform(items) {
return items.map(item => {
return {
id: item.json.id,
name: item.json.name.toUpperCase(),
created: new Date(item.json.created_at).toISOString()
};
});
}
// Send Email Node Configuration
{
"to": "recipient@example.com",
"subject": "Data Report",
"text": "=== Please find the data report attached ===",
"attachments": "={{ $json.report }}"
}
Triggers and Scheduling
Webhook Trigger
javascript
// Webhook Node Configuration
{
"path": "incoming-data",
"responseMode": "onReceived",
"responseData": "firstEntryJson"
}
// Access in browser or via curl
// https://n8n.example.com/webhook/incoming-data
// curl -X POST -H "Content-Type: application/json" -d '{"data":"test"}' https://n8n.example.com/webhook/incoming-data
Schedule Trigger
javascript
// Cron Node Configuration
{
"triggerTimes": {
"item": [
{
"mode": "everyWeek",
"hour": 9,
"minute": 0,
"dayOfWeek": 1 // Monday
}
]
}
}
// Every 5 minutes
{
"triggerTimes": {
"item": [
{
"mode": "everyX",
"unit": "minutes",
"value": 5
}
]
}
}
Trigger on File Changes
javascript
// Watch Files Node Configuration
{
"folder": "/data/incoming",
"includeSubfolders": true,
"fileExtensions": [
"csv",
"xlsx"
]
}
Data Manipulation
Function Node
javascript
// Basic transformation
function transform(items) {
return items.map(item => {
return {
...item.json,
fullName: `${item.json.firstName} ${item.json.lastName}`,
age: calculateAge(item.json.birthDate)
};
});
}
function calculateAge(birthDate) {
const today = new Date();
const birth = new Date(birthDate);
let age = today.getFullYear() - birth.getFullYear();
const monthDiff = today.getMonth() - birth.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
age--;
}
return age;
}
// Filtering data
function filter(items) {
return items.filter(item => {
return item.json.status === 'active' && item.json.age > 18;
});
}
// Aggregating data
function aggregate(items) {
const result = {
count: items.length,
sum: 0,
average: 0,
min: Infinity,
max: -Infinity
};
items.forEach(item => {
const value = item.json.amount;
result.sum += value;
result.min = Math.min(result.min, value);
result.max = Math.max(result.max, value);
});
result.average = result.sum / result.count;
return [{ json: result }];
}
Split In Batches Node
javascript
// Split In Batches Node Configuration
{
"batchSize": 10,
"options": {
"includeBatchIndex": true
}
}
Merge Node
javascript
// Merge Node Configuration
{
"mode": "merge",
"mergeByFields": {
"values": [
{
"field1": "id",
"field2": "userId"
}
]
}
}
// Concatenate mode
{
"mode": "concatenate"
}
// Multiplex mode (combine all items from all inputs)
{
"mode": "multiplex"
}
Error Handling and Flow Control
Error Workflow
javascript
// Error Trigger Node
// This node triggers when another workflow fails
// Error Workflow Example
// 1. Error Trigger Node
// 2. Send Email Node with error details
{
"to": "admin@example.com",
"subject": "Workflow Error: {{ $workflow.name }}",
"text": "Error in workflow: {{ $workflow.name }}\n\nError: {{ $json.error }}\n\nExecution ID: {{ $execution.id }}"
}
IF Node
javascript
// IF Node Configuration
{
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "equal",
"value2": "success"
}
]
}
}
// Multiple conditions with AND/OR
{
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "equal",
"value2": "pending"
}
],
"number": [
{
"value1": "={{ $json.amount }}",
"operation": "larger",
"value2": 1000
}
],
"boolean": [
{
"value1": "={{ $json.isVIP }}",
"operation": "equal",
"value2": true
}
],
"combinationMode": "any" // "all" for AND, "any" for OR
}
}
Switch Node
javascript
// Switch Node Configuration
{
"rules": {
"values": [
{
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "equal",
"value2": "new"
}
]
},
"outputIndex": 0
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "equal",
"value2": "processing"
}
]
},
"outputIndex": 1
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "equal",
"value2": "completed"
}
]
},
"outputIndex": 2
}
]
},
"fallbackOutput": 3
}
Wait Node
javascript
// Wait Node Configuration
{
"amount": 5,
"unit": "minutes"
}
// Wait until specific date
{
"dateTime": "={{ new Date($json.scheduledTime).toISOString() }}"
}
Working with APIs
HTTP Request Node
javascript
// Basic GET request
{
"url": "https://api.example.com/users",
"method": "GET",
"authentication": "None",
"options": {}
}
// POST request with JSON body
{
"url": "https://api.example.com/users",
"method": "POST",
"authentication": "Bearer Token",
"token": "{{ $node['Get Token'].json.access_token }}",
"bodyContentType": "json",
"body": {
"name": "{{ $json.name }}",
"email": "{{ $json.email }}",
"role": "user"
},
"options": {
"redirect": {
"follow": true,
"maxRedirects": 5
},
"timeout": 10000
}
}
// Handling pagination
{
"url": "https://api.example.com/users",
"method": "GET",
"authentication": "None",
"options": {
"qs": {
"page": "={{ $parameter.page || 1 }}",
"limit": 100
}
}
}
OAuth Authentication
javascript
// OAuth2 Configuration
{
"authentication": "OAuth2",
"oAuth2Api": "custom",
"authUrl": "https://auth.example.com/oauth/authorize",
"accessTokenUrl": "https://auth.example.com/oauth/token",
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"scope": "read write",
"authQueryParameters": "",
"authentication": "body"
}
Webhook Response Node
javascript
// Webhook Response Node Configuration
{
"respondWith": "json",
"responseBody": "={{ { success: true, data: $json.processedData } }}",
"options": {
"responseCode": 200,
"responseHeaders": {
"X-Powered-By": "n8n"
}
}
}
Database Operations
Postgres Node
javascript
// Query execution
{
"operation": "executeQuery",
"query": "SELECT * FROM users WHERE status = $1 AND created_at > $2",
"values": [
"={{ $json.status }}",
"={{ $json.date }}"
]
}
// Insert operation
{
"operation": "insert",
"table": "users",
"columns": "firstName,lastName,email,createdAt",
"values": [
"={{ $json.first_name }}",
"={{ $json.last_name }}",
"={{ $json.email }}",
"={{ new Date().toISOString() }}"
]
}
// Update operation
{
"operation": "update",
"table": "users",
"updateKey": "id",
"columns": "status,updatedAt",
"values": [
"active",
"={{ new Date().toISOString() }}"
]
}
MongoDB Node
javascript
// Find documents
{
"operation": "find",
"collection": "users",
"options": {
"limit": 100,
"sort": {
"createdAt": -1
}
},
"query": "={{ { status: $json.status } }}"
}
// Insert document
{
"operation": "insertOne",
"collection": "logs",
"document": "={{ {
action: $json.action,
userId: $json.userId,
timestamp: new Date(),
details: $json.details
} }}"
}
// Update document
{
"operation": "updateOne",
"collection": "users",
"filter": "={{ { _id: $json.userId } }}",
"update": "={{ {
$set: {
status: $json.newStatus,
updatedAt: new Date()
}
} }}",
"options": {
"upsert": false
}
}
File Operations
Read Binary Files Node
javascript
// Read Binary Files Node Configuration
{
"filePath": "/data/reports/latest.pdf"
}
// Read multiple files with pattern
{
"filePath": "/data/reports/*.csv"
}
Write Binary File Node
javascript
// Write Binary File Node Configuration
{
"filePath": "={{ '/data/processed/' + $json.filename }}",
"fileName": "={{ $json.filename }}",
"binaryPropertyName": "data",
"options": {
"encoding": "utf8",
"createParentPath": true
}
}
CSV Node
javascript
// Parse CSV
{
"operation": "parse",
"options": {
"headerRow": true,
"delimiter": ",",
"includeEmptyLines": false,
"skipLines": 0
}
}
// Create CSV
{
"operation": "create",
"options": {
"headerRow": true,
"delimiter": ",",
"includeEmptyLines": false
}
}
AI Integration
OpenAI Node
javascript
// Text completion
{
"authentication": "apiKey",
"apiKey": "{{ $node['Credentials'].json.openai_api_key }}",
"operation": "completion",
"model": "gpt-4",
"options": {
"prompt": "={{ 'Summarize the following text in 3 bullet points:\\n\\n' + $json.text }}",
"maxTokens": 500,
"temperature": 0.7,
"topP": 1,
"presencePenalty": 0,
"frequencyPenalty": 0,
"stop": []
}
}
// Chat completion
{
"authentication": "apiKey",
"apiKey": "{{ $node['Credentials'].json.openai_api_key }}",
"operation": "chatCompletion",
"messages": "={{ [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: $json.userMessage }
] }}",
"model": "gpt-4",
"options": {
"temperature": 0.7,
"maxTokens": 1000
}
}
Anthropic Node
javascript
// Claude message
{
"authentication": "apiKey",
"apiKey": "{{ $node['Credentials'].json.anthropic_api_key }}",
"operation": "message",
"model": "claude-3-opus-20240229",
"messages": "={{ [
{ role: 'user', content: $json.userMessage }
] }}",
"options": {
"temperature": 0.7,
"maxTokens": 1000
}
}
AI Document Processing
javascript
// Document processing workflow
// 1. Read Binary Files Node (PDF)
// 2. PDF Extract Node
{
"operation": "extractText"
}
// 3. Text Splitter Node
{
"operation": "splitByCharacter",
"options": {
"chunkSize": 1000,
"chunkOverlap": 200
}
}
// 4. OpenAI Node (for each chunk)
{
"operation": "chatCompletion",
"messages": "={{ [
{ role: 'system', content: 'Extract key information from this document chunk.' },
{ role: 'user', content: $json.text }
] }}",
"model": "gpt-4",
"options": {
"temperature": 0.3
}
}
// 5. Merge Node (combine all extracted information)
// 6. OpenAI Node (final summary)
{
"operation": "chatCompletion",
"messages": "={{ [
{ role: 'system', content: 'Create a comprehensive summary of this document based on the extracted information.' },
{ role: 'user', content: $json.extractedInfo }
] }}",
"model": "gpt-4",
"options": {
"temperature": 0.5
}
}
Advanced Features
Subworkflows
javascript
// Execute Workflow Node Configuration
{
"workflowId": 123,
"options": {
"waitForResponse": true
}
}
// Passing data to subworkflow
{
"workflowId": 123,
"options": {
"waitForResponse": true
},
"parameters": "={{ {
userId: $json.id,
action: 'process',
data: $json.payload
} }}"
}
Credentials Management
javascript
// Access credentials in HTTP Request Node
{
"url": "https://api.example.com/data",
"method": "GET",
"authentication": "Basic Auth",
"username": "={{ $credentials.username }}",
"password": "={{ $credentials.password }}"
}
Webhook Authentication
javascript
// Webhook Node with Basic Auth
{
"path": "secure-endpoint",
"authentication": {
"basicAuth": {
"user": "admin",
"password": "secret"
}
},
"responseMode": "onReceived",
"responseData": "firstEntryJson"
}
// Webhook Node with Custom Auth (Header)
{
"path": "api-endpoint",
"httpMethod": "POST",
"authentication": {
"customAuth": {
"checkOn": "header",
"name": "X-API-KEY",
"value": "your-secret-api-key"
}
},
"responseMode": "lastNode",
"responseData": "firstEntryJson"
}
Rate Limiting
javascript
// Limit Node Configuration
{
"maxConcurrency": 5,
"options": {
"batchSize": 10,
"batchInterval": 1000
}
}
Workflow Variables
javascript
// Set Variable Node
{
"variableName": "totalAmount",
"value": "={{ $json.amount }}"
}
// Get Variable Node
{
"variableName": "totalAmount"
}
// Using variables in expressions
"={{ $vars.totalAmount * 1.1 }}" // Add 10% tax
Deployment and Production
Environment Variables
bash
# Set environment variables for production
export N8N_ENCRYPTION_KEY=your-production-key
export N8N_PROTOCOL=https
export N8N_HOST=n8n.yourdomain.com
export N8N_PORT=5678
export N8N_BASIC_AUTH_ACTIVE=true
export N8N_BASIC_AUTH_USER=admin
export N8N_BASIC_AUTH_PASSWORD=secure-password
# Database configuration
export DB_TYPE=postgresdb
export DB_POSTGRESDB_HOST=production-db.yourdomain.com
export DB_POSTGRESDB_PORT=5432
export DB_POSTGRESDB_DATABASE=n8n_prod
export DB_POSTGRESDB_USER=n8n_user
export DB_POSTGRESDB_PASSWORD=db-password
# Queue configuration
export QUEUE_BULL_REDIS_HOST=redis.yourdomain.com
export QUEUE_BULL_REDIS_PORT=6379
Docker Compose for Production
yaml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
restart: always
ports:
- "5678:5678"
environment:
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_PROTOCOL=https
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=${DB_USER}
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- EXECUTIONS_PROCESS=main
- EXECUTIONS_MODE=queue
- GENERIC_TIMEZONE=UTC
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
- redis
postgres:
image: postgres:14
restart: always
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d n8n"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
postgres_data:
redis_data:
Scaling with Multiple Workers
bash
# Main process (API, UI, Webhook)
export EXECUTIONS_PROCESS=main
export EXECUTIONS_MODE=queue
# Worker processes (execute workflows)
export EXECUTIONS_PROCESS=worker
export EXECUTIONS_MODE=queue
Backup and Restore
bash
# Export workflows
n8n export:workflow --all --output=workflows-backup.json
# Import workflows
n8n import:workflow --input=workflows-backup.json
# Backup credentials (encrypted)
n8n export:credentials --all --output=credentials-backup.json
# Import credentials
n8n import:credentials --input=credentials-backup.json --separate
Best Practices
Workflow Organization
- Naming Convention: Use clear, descriptive names for workflows and nodes
- Documentation: Add descriptions to workflows and complex nodes
- Modularization: Break complex processes into subworkflows
- Tags: Use tags to categorize and organize workflows
- Version Control: Export important workflows regularly
Performance Optimization
- Batch Processing: Use Split In Batches for large datasets
- Pagination: Implement proper pagination for API calls
- Caching: Use Set/Get Variable nodes to cache repeated data
- Limit Concurrency: Use Limit node to prevent overwhelming external services
- Database Efficiency: Write efficient queries and use indexes
Error Handling
- Error Workflows: Create dedicated error handling workflows
- Retry Mechanisms: Implement retry logic for transient failures
- Validation: Validate data before processing
- Logging: Log important events and errors
- Notifications: Set up alerts for critical failures
Security
- Credentials: Use the built-in credentials system instead of hardcoding
- Environment Variables: Store sensitive information in environment variables
- Authentication: Secure webhook endpoints with authentication
- Access Control: Implement proper user permissions
- Audit Logs: Monitor workflow executions and changes
Troubleshooting
Common Issues
Workflow Not Triggering
- Cause: Incorrect trigger configuration, webhook URL not accessible, or scheduling issues
- Solution: Verify trigger settings, check webhook accessibility, and confirm timezone settings
Node Execution Failures
- Cause: Invalid data format, missing required fields, or API rate limits
- Solution: Use Function nodes to validate and transform data, implement error handling, and add rate limiting
Performance Issues
- Cause: Processing large datasets, inefficient queries, or resource constraints
- Solution: Implement batch processing, optimize database queries, and scale n8n deployment
Authentication Errors
- Cause: Expired credentials, incorrect API keys, or OAuth token issues
- Solution: Update credentials, verify API key permissions, and refresh OAuth tokens
This comprehensive n8n cheat sheet provides everything needed to build sophisticated workflow automations. From basic setup to advanced production deployment patterns, use these examples and best practices to create powerful, flexible automation workflows with n8n's versatile platform.