🔧 n8n Complete Cheat Sheet

v2025.05 - Comprehensive Reference Guide
📋 JSON Deep Dive

What is JSON?

JSON (JavaScript Object Notation) is a lightweight, text-based data format used for storing and exchanging data between systems. Think of it as a universal language for data.

Why JSON? It's human-readable, language-independent, lightweight, and supported everywhere.

JSON vs Other Formats

JSON
✅ Lightweight
✅ Human-readable
✅ Native JS support
XML
❌ Verbose
✅ Schema validation
❌ Harder to parse
CSV
✅ Simple
❌ No nested data
❌ No data types

JSON Structure Breakdown

{
  "name": "John Doe",
  "age": 30,
  "isActive": true,
  "salary": null,
  "skills": [
    "JavaScript",
    "Python"
  ],
  "address": {
    "street": "123 Main St",
    "city": "New York"
  }
}

Data Types Explained

Type Example Rules & Notes
String "Hello World" Must use double quotes, supports escape characters (\n, \t, \")
Number 42, -3.14, 1.2e5 No quotes, supports integers, decimals, scientific notation
Boolean true, false Lowercase only, represents true/false conditions
Null null Represents absence of value (not 0 or empty string)
Array [1, "text", true] Ordered list, can contain any data types
Object {"key": "value"} Key-value pairs, keys must be strings

Real-World JSON Examples

User Profile
{
  "userId": 12345,
  "username": "john_doe",
  "profile": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "preferences": {
      "theme": "dark",
      "notifications": true
    }
  },
  "roles": ["user", "admin"],
  "lastLogin": "2024-01-15T10:30:00Z"
}
API Response
{
  "status": "success",
  "data": [
    {
      "id": 1,
      "title": "Learn n8n",
      "completed": false,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ],
  "meta": {
    "total": 1,
    "page": 1,
    "limit": 10
  }
}

JSON & Expressions in n8n

OpenAI Node JSON Access
OpenAI node showing how to access JSON data with expressions like {{ $json.postContent }}
Access Pattern Example Use Case
Simple field {{ $json.name }} Get top-level field
Nested object {{ $json.user.profile.email }} Access deeply nested data
Array element {{ $json.items[0] }} Get first array item
Dynamic field {{ $json["field-name"] }} Fields with special characters
All array items {{ $json.items.map(item => item.name) }} Extract field from all items
From the image above: The expression {{ $json.postContent }} accesses the "postContent" field from the input data, which contains an array of social media posts that can be processed by the AI model.

JSON Manipulation in n8n

// Convert object to JSON string
{{ $json.data.toJsonString() }}

// Parse JSON string to object
{{ JSON.parse($json.jsonString) }}

// Check if field exists
{{ $json.field !== undefined }}

// Get all object keys
{{ Object.keys($json) }}

// Get array length
{{ $json.items.length }}

// Map over array (use normal JavaScript)
{{ $json.items.map(item => item.name) }}

// Filter array
{{ $json.items.filter(item => item.active) }}

// Merge objects
{{ Object.assign({}, $json, {newField: "value"}) }}

Common JSON Issues & Solutions

❌ Common Mistakes
  • Single quotes: 'invalid'
  • Trailing commas: {a: 1,}
  • Comments: // not allowed
  • Undefined values
✅ Correct Format
  • Double quotes: "valid"
  • No trailing commas
  • No comments allowed
  • Use null instead
🌐 How APIs Actually Work

API Fundamentals

API (Application Programming Interface) is like a waiter in a restaurant - you tell the waiter what you want, they take your order to the kitchen, and bring back your food.

Real-World Analogy:
🍕 You (Client) → 👨‍💼 Waiter (API) → 👨‍🍳 Kitchen (Server) → 🍕 Food (Data)

The API Request Journey

  1. Client sends request - "I want user info for ID 123"
  2. API processes request - Validates, authenticates, routes
  3. Server handles logic - Database queries, calculations
  4. Response sent back - User data or error message

HTTP Methods Explained

Method Purpose Real Example Idempotent*
GET Retrieve data Get user profile, list products
POST Create new data Register user, create order
PUT Update/replace entirely Update entire user profile
PATCH Partial update Change just the email address
DELETE Remove data Delete user account
*Idempotent means: You can make the same request multiple times and get the same result. For example, getting user data (GET) or deleting a specific item (DELETE) will have the same effect whether you do it once or ten times. Creating a new user (POST) is NOT idempotent because each request creates a new user.

Understanding Request Structure

METHOD /endpoint HTTP/1.1
Host: api.example.com
Header-Name: Header-Value
Content-Type: application/json
Authorization: Bearer your_token
{
  "requestBody": "data"
}
Request Parts:
  • Method: What action to perform
  • URL: Where to send request
  • Headers: Metadata about request
  • Body: Data being sent (POST/PUT)
Response Parts:
  • Status Code: Success/error indicator
  • Headers: Metadata about response
  • Body: The actual data returned

Status Codes Explained

Success (2xx)
  • 200 OK - Request succeeded
  • 201 Created - New resource created
  • 204 No Content - Success, no data returned
Client Errors (4xx)
  • 400 Bad Request - Invalid request
  • 401 Unauthorized - Need authentication
  • 403 Forbidden - Access denied
  • 404 Not Found - Resource doesn't exist
Server Errors (5xx)
  • 500 Internal Server Error - Server crashed
  • 502 Bad Gateway - Server unreachable
  • 503 Service Unavailable - Server overloaded

Authentication Explained

Type How it Works Example
API Key Secret string that identifies your app Like showing an ID card
Bearer Token Temporary access token Like a movie ticket
Basic Auth Username + Password combination Like hotel check-in
OAuth 2.0 Permission-based access Like "Sign in with Google"

cURL Commands Breakdown

# Basic GET request
curl https://api.example.com/users
# GET with authentication
curl -H "Authorization: Bearer TOKEN" \
  https://api.example.com/users
# POST with JSON data
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"name": "John", "email": "john@email.com"}' \
  https://api.example.com/users
# Save response to file
curl -o response.json https://api.example.com/data

Common API Patterns

RESTful URLs
  • GET /users - Get all users
  • GET /users/123 - Get specific user
  • POST /users - Create new user
  • PUT /users/123 - Update user 123
  • DELETE /users/123 - Delete user 123
🌐 HTTP Request Node

HTTP Request Configuration Interface

HTTP Request Node Configuration
Complete HTTP Request node configuration showing all available options and settings
What you see in the interface above:
  • Method Dropdown: Shows "GET" selected (top of interface)
  • URL Field: Contains "https://example.com" as placeholder
  • Authentication: Set to "None" with dropdown for other options
  • Send Query Parameters: Toggle enabled with "q1=answer" example
  • Send Headers: Toggle enabled with "header1=value" example
  • Send Body: Toggle enabled, showing JSON format
  • JSON Body: Contains sample {"key": 2} structure

Method Selection (As shown in dropdown)

Method Purpose When to Use
GET Retrieve data Fetching user info, search results
POST Create new resource Creating users, submitting forms
PUT Update entire resource Replacing user profile completely
PATCH Partial update Updating just email or name
DELETE Remove resource Deleting user accounts, posts

URL Configuration (From URL field)

// Static URL (as shown)
https://example.com
// Dynamic URLs with expressions
https://api.example.com/users/{{ $json.userId }}
// DON'T add query parameters in URL // ❌
https://api.example.com/search?q=value
// ✅ Use the Query Parameters section instead
Important: Don't add query parameters like ?q=value directly to the URL. Instead, use the "Send Query Parameters" section below. n8n will automatically construct the final URL with your parameters.

Query Parameters (As demonstrated)

The interface shows "Send Query Parameters" toggle enabled with an example:

// Example shown in interface:
q1=answer
Name: q1
Value: answer
// This creates:
https://example.com?q1=answer
// Dynamic query parameters
Name: search
Value: {{ $json.searchTerm }}
Name: limit
Value: {{ $json.pageSize || 10 }}
// Multiple parameters create:
// https://api.example.com?search=term&limit=10

Headers Configuration (From Headers section)

The interface shows "Send Headers" enabled with header1=value example:

// Example from interface
Name: header1
Value: value
// Real-world headers
Name: Authorization
Value: Bearer {{ $credentials.apiToken }}
Name: Content-Type
Value: application/json
Name: Accept
Value: application/json

Request Body (From Body section)

The interface shows JSON body type selected with a sample structure:

// Example from interface
{
  "key": 2
}

// Dynamic JSON body
{
  "userId": {{ $json.id }},
  "name": "{{ $json.fullName }}",
  "email": "{{ $json.email }}",
  "metadata": {{ JSON.stringify($json.metadata) }}
}

Authentication Options (From Auth dropdown)

The interface shows "None" selected, but other options include:

Type Implementation When to Use
None No authentication Public APIs
Basic Auth Username + Password Simple protected APIs
Header Auth Custom header with token API key authentication
OAuth1/OAuth2 Token-based authentication Social media APIs
Predefined Credential Saved in n8n credentials Reusable authentication

Body Content Types Available

The interface shows "JSON" selected, but you can choose:

  • JSON: For API calls expecting JSON data
  • Form-Data: For file uploads and multipart forms
  • Form URL Encoded: For traditional form submissions
  • Raw: For custom data formats (XML, text, etc.)

Testing Your Configuration

💡 Pro Tip: Use the "Test step" button (shown in red at top of interface) to validate your HTTP request before running the full workflow. This helps catch configuration errors early.
🤖 AI Agent Architecture

AI Agent Workflow Structure

AI Agent Workflow
Complete AI Agent workflow showing connections between Memory, Tools, Models, and Output Parsers
Components visible in the workflow:
  • AI Agent2: Central orchestrator (Tools Agent)
  • OpenAI Chat Model: Language model for responses
  • Buffer Memory: Conversation context storage
  • Pinecone Vector Store: Document embeddings and retrieval
  • Tools: MCP Client, Google Sheets integration
  • Output Parsers: Structured response formatting

AI Agent Components Explained

Memory (1:1)
One agent → One memory
Memory - Stores chat history
Remembers previous messages when you chat with the model multiple times, especially useful with the built-in chat feature
Model (Required)
OpenAI - GPT models
Anthropic - Claude models
Tools (1:N)
One agent → Multiple tools
Vector Store, MCP Client, Google Sheets - All are tools
Output Parser
Auto-fixing - Uses AI to fix malformed responses
Structured Output - Ensures consistent format

Tool Integration Patterns

From the diagram above:
Pinecone Vector Store → Tool for semantic search (with embedding model)
Google Sheets → Tool for spreadsheet operations
MCP Client → Tool for external API connections
Auto-fixing Output Parser → Fixes responses that don't match your schema
Vector Store Tool: Converts text into numerical vectors (embeddings) for semantic search. Unlike simple memory which stores chat history, vector stores help find relevant documents based on meaning, not just keywords. It's a tool that the agent can use to retrieve information from large document collections.

Prompt Structure Best Practices

System Prompt:
- Persona: Define AI's role and behavior
- Task: Specific objectives to accomplish
- Context: Background information and constraints
- Format: Expected output structure

User Input: {{ $json.userMessage }}

Tools Available:
- Google Sheets (read/write)
- Vector search via Pinecone
- Web APIs through MCP Client

Memory Management

Memory in n8n:
Memory stores chat conversation history so the AI remembers previous messages. You can choose different storage backends (Simple Memory, MongoDB, Postgres, Redis, etc.) but they all do the same thing - just store the data in different places.
Component Purpose Use Case
Memory Store chat conversation history Multi-turn conversations, remember context
Vector Store (Tool) Store and query documents by meaning Search knowledge base, find relevant docs
Memory vs Vector Store:
Memory = Remembers what the user said in chat
Vector Store = Searches through documents/knowledge base
These are completely different things that serve different purposes.

Implementation Tips

  • ✅ Use specific, clear prompts
  • ✅ Implement proper error handling
  • ✅ Set up rate limit management
  • ✅ Test with various input types
  • ✅ Monitor token usage costs
  • ✅ Combine multiple tools for complex tasks
⌨️ Keyboard Shortcuts

Workflow Control

Action Shortcut
Save Workflow Ctrl + S
Execute Workflow Ctrl + Enter
New Workflow Ctrl + Alt + N
Undo Ctrl + Z
Redo Ctrl + Shift + Z

Canvas Navigation

Action Shortcut
Move Canvas Space + Drag
Zoom In + or =
Zoom Out - or _
Fit to View 1
Reset Zoom 0

Node Operations

Action Shortcut
Select All Ctrl + A
Copy Node Ctrl + C
Paste Node Ctrl + V
Delete Node Delete
Disable Node D
Rename Node F2
Add Node Tab
🔧 Built-in Nodes

Trigger Nodes

Node Description
Manual Execute manually by user
Schedule Time-based execution
Webhook HTTP request trigger
Form Form submission trigger
Chat Chat message trigger

Core Processing Nodes

Node Description
Set Add/modify field values
Code JavaScript processing
IF Conditional branching
Merge Combine data streams
Split Split arrays into items
Filter Filter data by conditions

Data Transformation

Node Description
Aggregate Group and summarize data
Sort Sort data by criteria
Limit Limit output items
Remove Duplicates Remove duplicate entries
💡 Expressions

Basic Syntax

// Basic field access
{{ $json.fieldName }}

// Node reference
{{ $node["Node Name"].json.field }}

// Array access
{{ $json.items[0].name }}

// Process all array items (use normal JavaScript)
{{ $json.items.map(item => item.value) }}

Common Patterns

Pattern Example
Conditional {{ $json.age > 18 ? "Adult" : "Minor" }}
String concat {{ $json.first + " " + $json.last }}
Date format {{ $now.format("yyyy-MM-dd") }}
Array filter {{ $json.items.filter(item => item.active) }}
Array map {{ $json.users.map(user => user.name) }}

Built-in Variables

$json - Current item data
$node - Other node data
$now - Current timestamp
$today - Today's date
$execution - Execution data
$workflow - Workflow info
$itemIndex - Current item index
$input - Input items

String Operations

// Transform case
{{ $json.text.toLowerCase() }}
{{ $json.text.toUpperCase() }}

// String manipulation
{{ $json.text.trim() }}
{{ $json.text.replace("old", "new") }}
{{ $json.text.substring(0, 10) }}

// Check content
{{ $json.email.includes("@gmail.com") }}
{{ $json.text.startsWith("Hello") }}
⚙️ Node Common Settings

Node Settings

Setting Description
Always Output Data Returns empty item when no data (avoid infinite loops)
Execute Once Processes only first item, ignores rest
Retry On Fail Automatically retries failed executions

Error Handling

Option Behavior
Stop Workflow Stops entire workflow on error
Continue Continues with last valid data
Continue (Error Output) Passes error to next node
💡 Pro Tip: Always add error handling for production workflows. Use "Continue (Error Output)" for custom error processing.
🚀 Quick Start Checklist

Workflow Creation Steps

  1. Choose your trigger (Manual, Webhook, Schedule)
  2. Add data source (HTTP Request, Database, File)
  3. Transform data (Set, Code, IF nodes)
  4. Add business logic (loops, conditions)
  5. Output or action (Save, Send, Update)
  6. Test with sample data
  7. Add error handling
  8. Save and activate

Debugging Tips

🔍 Debug Process:
1. Execute workflow step by step
2. Check data between nodes
3. Use console.log in Code nodes
4. Verify expressions with test data
5. Check error outputs

Performance Tips

  • ⚡ Limit batch sizes for large datasets
  • ⚡ Use filters early to reduce data volume
  • ⚡ Optimize loops and conditions
  • ⚡ Cache frequently used data
  • ⚡ Use webhooks over polling when possible

Data Pinning for Cost Savings

Data Pinning Example
Pinning data from HTTP Request to save API calls - notice "This data is pinned" indicator
How Pinning Works:
In our example above, we pinned the output of our Phantombuster API call. This means:
  • No additional API calls when testing downstream nodes
  • Save credits/costs on expensive APIs
  • Faster testing - no need to wait for API responses
  • Pin multiple nodes for complex workflows
💡 Pro Tip: Pin data at expensive API nodes (like AI models, search APIs, or data extraction services) during workflow development. You can always unpin when ready to run with live data.