The KAGAMI mark КАГАМИ
kagami.bg/academy · reference · machine-readable viewVERIFIED 2026-10-01 · UPDATED 2026-10-01
IDENTITY
module
n8n-00 · n8n cheat sheet
series
n8n
level
All levels
duration
reference (about 25 min to read)
trust_label
VERIFIED 2026-10-01 (nodes, environment variables, CLI commands, expression syntax and install steps checked against docs.n8n.io; current stable and beta read from the docs install page) · UPDATED 2026-10-01 · NOT TESTED (no n8n instance was run for this check)
versions
n8n 2.x line · docs list stable 2.41.4 and beta 2.42.1 on 2026-10-01 · image docker.n8n.io/n8nio/n8n · default port 5678 · docs announce n8n 3.0 for October 2026 (npm install no longer supported, Docker only)
language
human view: en · bulgarian edition: /academy/n8n/n8n · Обобщаващ справочник (Cheat Sheet).html
previous / next
series index: https://kagami.bg/en/academy/n8n/ · lesson 1: Installation and first workflow
PURPOSE

One-page reference for self-hosted n8n 2.x, the workflow automation platform: core concepts (workflow, node, item, execution, credentials, expression), node families, expression syntax, the Code node (JavaScript and native Python), Docker install, Server CLI and public REST API, the environment variables that matter, queue mode and a symptom-to-fix table. Replaces older notes that still described 1.x behaviour (basic auth, active toggle, Pyodide Python).

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

n8n lesson 1, Installation and first workflow: https://kagami.bg/en/academy/n8n/ · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
n8nautomationworkflowsexpressionsdockercliqueue-modecheat-sheet
VERIFIED · 01.10.2026 UPDATED · 01.10.2026

n8n: nodes, expressions, CLI and settings in one place

Everything important about n8n on one page — concepts, nodes, expressions, the Code node, Docker, commands and environment variables. Checked against the official documentation for the 2.x line: from our old notes we removed what no longer exists (basic-auth login, "activating" workflows, Python through Pyodide).

⏱ reference · ~25 min All levels n8n Nodes · Expressions · Docker · CLI
n8n on your own machine (self-hosted)🔒 local Ollama (local model)🔒 local Gmail, cloud models and other external services🌐 global
🔄
UPDATED · 01.10.2026 — what changed
The old cheat sheet described n8n 1.x. The documentation today covers 2.x (stable 2.41.4, beta 2.42.1 on this date). Fixed: a login with N8N_BASIC_AUTH_* does not appear in the docs — on first open you create an owner account; "activate" is replaced by publish (n8n publish:workflow, while update:workflow is deprecated); Python in the Code node is now native Python (_items, bracket access), not Pyodide; WEBHOOK_URL is a deprecated alias of N8N_WEBHOOK_URL; the default EXECUTIONS_DATA_MAX_AGE is 336 hours, and Execute Command and Local File Trigger are off. Renamed nodes: Execute Workflow → Execute Sub-workflow, Window Buffer Memory → Simple Memory, HTML Extract → HTML. Removed because unconfirmed: n8n list:workflow, "F5 to pin", "Ctrl+D duplicates" (in the docs P pins data and D deactivates a node), a "JSON Parse" node, a 3-minute timeout for Respond to Webhook. Removed for privacy: the section about our internal machines and ports — replaced by a general network-protection rule.
⚠️
What we have not run ourselves
For this check we did not start n8n. Everything is checked against docs.n8n.io as of 01.10.2026, but it is not tested by us — that is why there is no "TESTED" label. Least verified (marked ⚠️ below): access to environment variables from the Code node, and the compose file template.

01What you'll learn

This is a reference, not a step-by-step lesson — so section 03 is laid out as "task → answer" cards. You will find:

02Before you start

What you need

📌
The image and the version
The image is docker.n8n.io/n8nio/n8n (the docs also show it as n8nio/n8n — the same product). The beta tag (old name next) is the unstable version, stable (old name latest) the stable one. In production pin a version instead of following "latest", and read the release notes before updating.
⚠️
n8n 3.0 is coming (October 2026)
The install page in the docs says that from n8n 3.0 (announced for October 2026) npm install n8n / npx n8n no longer works and n8n is distributed through Docker only. An existing npm install keeps working for now, but new installs and future upgrades should use Docker. Version 1 of the AI Agent node is also removed in 3.0.
⛔
Secrets and access
Keys, passwords and tokens live in n8n credentials — never in node fields, in expressions or on a page like this one. Here you only see placeholders such as <SECRET>. Do not expose n8n straight to the internet without HTTPS and a reverse proxy.

03Steps

For a reference the "steps" are cards by task. Take the one you need.

  1. Core concepts

    ConceptWhat it is
    WorkflowA diagram of connected nodes that runs on a trigger or manually. Saved as JSON and can be exported/imported (see card 6).
    NodeThe building block: receives items, processes them and passes them on.
    ItemA unit of data — one JSON object in the array a node passes on.
    ExecutionOne run of a workflow. Stored in the database; visible in the Executions tab. By default both successful and failed runs are saved, and old ones are deleted after 336 hours (card 9).
    CredentialsEncrypted access data. Encrypted with N8N_ENCRYPTION_KEY; one credential can serve many workflows.
    ExpressionA dynamic value in a field, written in {{ }} with JavaScript. In an empty field press = to switch to expression mode.
    Sub-workflowA workflow called from another through the Execute Sub-workflow node; it starts with an Execute Sub-workflow Trigger.
    PublishingIn 2.x the old "active/inactive" toggle is replaced by Publish / Unpublish. Production webhook URLs are registered when you publish.
  2. Nodes: what to use for what

    Names follow the current docs. Marker: [off] — disabled by default in 2.x (turn on through NODES_EXCLUDE).

    GroupNodeWhat for
    TriggersWebhookHTTP request from an external system; has a test and a production URL
    Schedule TriggerOn a schedule (cron or interval); the time zone is GENERIC_TIMEZONE
    Email Trigger (IMAP)New email in a mailbox
    Gmail TriggerNew message in Gmail
    Chat TriggerBuilt-in chat — for AI agents
    Execute Sub-workflow TriggerCalled from another workflow
    Manual TriggerManual start for building and checking
    Error Trigger · Local File Trigger [off]Catches errors from another workflow · watches changes in the file system
    ActionsHTTP RequestCalls a REST API
    Send EmailSends mail through SMTP
    GmailReads and sends through Gmail
    Read/Write File From DiskFile access on the machine running n8n
    Postgres · RedisQueries to PostgreSQL · work with Redis
    SSHCommands on a remote machine
    Execute Command [off]Commands on the machine running n8n (in Docker — inside the container)
    FlowIf · SwitchBranch by condition · by value
    MergeMerges streams
    Loop Over Items (Split in Batches)Processes items in batches; has loop and done outputs
    WaitA pause
    Execute Sub-workflowCalls another workflow
    Respond to WebhookReturns a response to the webhook caller
    Stop and ErrorStops with your own error message (sent to the Error Trigger)
    AIAI AgentAn agent with a model and tools; requires at least one tool (tool sub-node)
    Basic LLM ChainOne LLM call: prompt → answer
    Text Classifier · Sentiment Analysis · Information ExtractorClassifies · scores tone · pulls structured data out of text
    Summarization ChainSummarises long text
    Ollama Chat ModelA local model through Ollama 🔒 local
    Embeddings OllamaVector embeddings locally 🔒 local
    Simple MemoryShort-term agent memory (formerly "Window Buffer Memory")
    Qdrant Vector Store · Simple Vector StoreVector store (external · in memory)
    MCP Client ToolGives the agent tools from an MCP server
    UtilityCodeJavaScript or Python (card 5)
    Edit Fields (Set)Adds, renames, reorders fields without code
    Filter · Sort · LimitFilter by condition · sort · first N
    Remove DuplicatesRemoves repeated items
    Aggregate · SummarizeCollects items into one · groups and calculates (sum, count)
    HTML · MarkdownExtracts data from HTML with CSS selectors · converts HTML ↔ Markdown
    CryptoHash and signature
    Date & TimeFormats and calculates dates
    Edit ImageImage processing
    💡
    You often do not need a loop
    Most nodes already process every item in the list. Loop Over Items is for cases where you need batches or a pause between requests (for example because of API limits). If you build a loop with reset, always add an end condition — otherwise the execution loops forever.
  3. Expressions: reference

    ExpressionMeaning
    {{ $json.field }}A field of the current item
    {{ $json["field name"] }}A field with a space in its name
    {{ $json.user.email }} · {{ $json.tags[0] }}Nested field · first element of an array
    {{ $input.first().json.id }}The first input item (also .last(), .all())
    {{ $input.all().length }}Number of input items
    {{ $('Node Name').item.json.x }}Data from a specific node for the matching item
    {{ $('Node Name').all() }}All items that node output (also .first(), .last())
    {{ $prevNode.name }}The name of the node the data came from
    {{ $workflow.name }} · {{ $execution.id }}Workflow name · execution ID
    {{ $now }} · {{ $today }}Now (Luxon DateTime, in the workflow time zone) · midnight today
    {{ $if(condition, if_true, if_false) }} · {{ $ifEmpty(value, fallback) }}Short conditionals
    {{ $vars.name }} · {{ $fromAI('key') }}Custom variable · a value the model fills in (in agent tools)
    expressions
    // dates (Luxon)
    {{ $now.toFormat('dd.MM.yyyy') }}
    {{ $now.plus({ days: 7 }).toISO() }}
    {{ DateTime.fromISO($json.createdAt).toFormat('dd.MM.yyyy') }}
    
    // condition
    {{ $json.amount > 1000 ? 'VIP' : 'Standard' }}
    
    // text and numbers
    {{ $json.email.split('@')[0] }}
    {{ [$json.firstName, $json.lastName].join(' ') }}
    {{ Math.round($json.price * 1.2) }}
    
    // JSON for a request body
    {{ JSON.stringify($json) }}
    
    // fallback value
    {{ $json.name ?? 'Unknown' }}
    💡
    Expressions and the Code node are not the same thing
    Some helpers ($if(), $jmespath() and others) work only in the expression editor, not in the Code node. Methods tagged "Custom n8n functionality" in the reference may be missing there — use native Luxon (toFormat) and plain JavaScript. Note: plus()/minus() in expressions accept (number, unit) or an object, while native Luxon accepts only an object.
  4. Data flow: Webhook, response and errors

    Webhook → process → respond. In the Webhook node set Respond to "Using 'Respond to Webhook' node", then place Respond to Webhook after the nodes whose data you return. It runs once, with the first item.

    Webhook → If (validation) → Code / Edit Fields → Postgres (write) → Respond to Webhook

    • The test URL works while you listen for an event (Listen for test event) and shows the data in the editor. Path: /webhook-test/<path>.
    • The production URL is registered when you publish the workflow; runs show up in Executions. Path: /webhook/<path>.
    • The largest request body is 16 MiB by default (N8N_PAYLOAD_SIZE_MAX).
    • An HTML response is wrapped in an <iframe> automatically (since 1.103.0) — scripts that reach for the top-level window will not work.

    Errors. Build a separate workflow that starts with an Error Trigger (for example "Error Handler"). In the main workflow: Options → Settings → Error workflow and pick it. The Error Trigger cannot be tested with a manual run — it fires only when an automatically started workflow fails. Stop and Error sends a custom message to it.

    Schedule → fetch → notify: Schedule Trigger → HTTP Request → Filter (new only) → Loop Over Items → Send Email. AI pipeline: Webhook or Email Trigger → Edit Fields (prepare the prompt) → AI Agent (with a model and a tool) → write.

  5. The Code node: JavaScript and native Python

    Two modes: Run Once for All Items (the default — the code runs once for everything) and Run Once for Each Item. Inside, there is no file or HTTP access — use Read/Write File From Disk and HTTP Request.

    JavaScript · all items
    const out = [];
    for (const item of $input.all()) {
      out.push({
        json: {
          fullName: item.json.firstName + ' ' + item.json.lastName,
          processedAt: new Date().toISOString(),
        },
      });
    }
    return out;
    
    // filtering
    // return $input.all().filter(i => i.json.status === 'active');
    
    // everything in one item
    // return [{ json: { all: $input.all().map(i => i.json) } }];
    Python (native) · all items
    result = []
    for item in _items:
        data = item["json"]
        result.append({"json": {
            "id": data["id"],
            "total": data["price"] * data["qty"],
        }})
    return result
    🐍
    Python in 2.x: what changed
    The old Pyodide-based Python is removed. Native Python runs only on task runners in external mode (the separate n8nio/runners image), uses _items (all) and _item (one at a time), field access is only ["json"]["field"] (not item.json.field), and the other n8n built-in variables are not available. Modules beyond the standard library must be included in the runners image.
    ⚠️
    Environment variables from the Code node ⚠️
    The 2.0 notes say access to environment variables from the Code node is blocked by default (N8N_BLOCK_ENV_ACCESS_IN_NODE), but the variables table still shows a default of false. Do not rely on either: for secrets use credentials, not environment variables. $evaluateExpression() no longer works in the Code node — write the logic directly in JavaScript, or evaluate the expression in Edit Fields before the Code node.
  6. Installing and managing with Docker

    Fastest (fresh install; read the script before running it; needs Docker with compose v2):

    bash
    curl -fsSL https://get.n8n.io | sh

    Manually, for trying it out only (data lives in the n8n_data volume; the editor is at http://localhost:5678):

    bash
    docker volume create n8n_data
    
    docker run -it --rm --name n8n -p 5678:5678 \
      -e GENERIC_TIMEZONE="<TIMEZONE>" \
      -e TZ="<TIMEZONE>" \
      -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
      -v n8n_data:/home/node/.n8n \
      docker.n8n.io/n8nio/n8n

    The first time, n8n asks you to create an owner account — that is how you log in (basic auth with N8N_BASIC_AUTH_* does not appear in the docs). N8N_RUNNERS_ENABLED is no longer needed from 2.0.

    A compose file template with PostgreSQL ⚠️ (assembled from the variables in the docs; not run by us — the official examples are in the n8n-io/n8n-hosting repository):

    compose.yml
    services:
      n8n:
        image: docker.n8n.io/n8nio/n8n:<VERSION>
        restart: unless-stopped
        ports:
          - "5678:5678"
        environment:
          - GENERIC_TIMEZONE=<TIMEZONE>
          - TZ=<TIMEZONE>
          - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
          - N8N_ENCRYPTION_KEY=<SECRET>
          - N8N_HOST=<YOUR-DOMAIN>
          - N8N_PROTOCOL=https
          - N8N_WEBHOOK_URL=https://<YOUR-DOMAIN>/
          - DB_TYPE=postgresdb
          - DB_POSTGRESDB_HOST=<DB-HOST>
          - DB_POSTGRESDB_DATABASE=<DATABASE>
          - DB_POSTGRESDB_USER=<USER>
          - DB_POSTGRESDB_PASSWORD=<SECRET>
        volumes:
          - n8n_data:/home/node/.n8n
    volumes:
      n8n_data:

    Even with PostgreSQL keep the /home/node/.n8n volume — keys, logs and other important files are there. Without N8N_ENCRYPTION_KEY n8n generates a key itself on first start; if you set one, keep it somewhere safe — without it saved credentials cannot be read.

    bash · managing
    docker ps
    docker logs -f --tail=100 n8n
    docker restart n8n
    docker stats n8n
    
    # update (compose)
    docker compose pull
    docker compose down
    docker compose up -d
    
    # update (docker run): pull the image, stop and remove the old container, start again
    docker pull docker.n8n.io/n8nio/n8n
  7. CLI and REST API

    The Server CLI runs on the same machine as n8n and touches the database directly. In Docker: docker exec -u node -it <container> n8n <command>.

    bash · Server CLI
    n8n execute --id <ID>
    
    # publishing (replaces update:workflow since 2.0)
    n8n publish:workflow --id=<ID>
    n8n unpublish:workflow --id=<ID>
    
    # backup of workflows and credentials
    n8n export:workflow --backup --output=backups/latest/
    n8n export:credentials --backup --output=backups/latest/
    
    # restore
    n8n import:workflow --separate --input=backups/latest/
    n8n import:credentials --separate --input=backups/latest/
    
    # security check
    n8n audit
    • publish:workflow / unpublish:workflow touch the database — if n8n is running, the change takes effect after a restart. There is no --all for publishing (on purpose), but there is one for unpublish.
    • update:workflow is deprecated since 2.0. We could not find n8n list:workflow in the current docs — do not rely on it.
    • export:credentials --decrypted writes secrets as plain text — use it only for a deliberate transfer and then delete the file securely.
    • Imported workflows stay inactive by default (--activeState=false).
    • --backup covers workflows and credentials only; a full instance backup has more parts — see "Back up and restore" in the docs.

    REST API (from another machine): a key from Settings → n8n API, sent in the X-N8N-API-KEY header. The API is not available during the n8n Cloud free trial.

    bash · REST and health
    curl 'https://<YOUR-N8N>/api/v1/workflows?active=true' \
      -H 'accept: application/json' \
      -H 'X-N8N-API-KEY: <API-KEY>'
    
    # call a production webhook
    curl -X POST 'https://<YOUR-N8N>/webhook/<PATH>' \
      -H 'Content-Type: application/json' \
      -d '{"key": "value"}'
    
    # liveness check
    curl -sf 'https://<YOUR-N8N>/healthz'
  8. Keyboard shortcuts (per the docs)

    GroupShortcuts
    WorkflowCtrl/Cmd+S save · Ctrl/Cmd+Z undo · Ctrl/Cmd+Shift+Z redo · Ctrl/Cmd+Enter execute · Ctrl/Cmd+Alt+N new · Ctrl/Cmd+O open
    CanvasSpace+drag or middle button — pan · +/- zoom · 0 reset zoom · 1 fit the workflow · Ctrl/Cmd+wheel zoom
    NodesN node panel · Ctrl/Cmd+A all · Ctrl/Cmd+C/X/V · F2 rename · P pin data · D deactivate · Delete delete · Shift+S sticky note
    OtherCtrl/Cmd+K command bar · Escape closes the node panel

    Running the "whole workflow" and "this node only" are separate buttons in the editor; pinning data freezes a node's output while you build.

  9. Environment variables and queue mode

    VariableMeaning
    N8N_HOST · N8N_PORT · N8N_PROTOCOLThe host name, port (5678) and protocol (http/https) used to reach n8n
    N8N_WEBHOOK_URLBase URL of webhooks behind a reverse proxy; must be reachable from outside. WEBHOOK_URL is a deprecated alias (since 2.35.0)
    N8N_EDITOR_BASE_URL · N8N_PROXY_HOPSPublic editor URL (for emails and SSO) · how many reverse proxies sit in front
    GENERIC_TIMEZONE · TZn8n's time zone (default America/New_York!) — matters for schedules · container clock
    N8N_ENCRYPTION_KEYKey that encrypts credentials; generated automatically by default. Keep it; in queue mode it is the same everywhere
    DB_TYPEpostgresdb for production · SQLite by default. MySQL/MariaDB are not supported since 2.0
    N8N_LOG_LEVELinfo (default) · warn · error · debug
    EXECUTIONS_DATA_PRUNE · EXECUTIONS_DATA_MAX_AGEClean up old executions (on by default) · age in hours (default 336 = 14 days)
    EXECUTIONS_DATA_SAVE_ON_SUCCESS / _ON_ERRORall or none; everything is saved by default
    N8N_METRICStrue turns on the /metrics endpoint (off by default)
    N8N_PAYLOAD_SIZE_MAXLargest request body in MiB (16)
    N8N_DISABLE_UItrue disables the editor
    NODES_EXCLUDEWhich nodes are disabled; Execute Command and Local File Trigger are there by default
    N8N_ENFORCE_SETTINGS_FILE_PERMISSIONStrue sets 0600 permissions on the settings file

    Queue mode (many workers): the main instance receives triggers and webhooks and puts executions in a queue in Redis; workers pick them up and run them.

    1. Redis (QUEUE_BULL_REDIS_HOST, QUEUE_BULL_REDIS_PORT, default 6379) and PostgreSQL — SQLite with queue mode is not recommended.
    2. EXECUTIONS_MODE=queue on the main instance and on every worker; the same N8N_ENCRYPTION_KEY everywhere.
    3. Worker: n8n worker (--concurrency=N, default 10; 5 or more recommended). Optional: separate webhook processes with n8n webhook.
    4. Binary data in the file system is not supported in queue mode — use external storage (S3).
    🛡️
    Network protection — a general rule
    Run n8n behind a reverse proxy with HTTPS; only the editor entrance and webhooks should be visible from outside — not the database, Redis or workers. Addresses and ports of a specific installation do not belong on pages like this one.
  10. Quick diagnostics: symptom → cause → fix

    SymptomLikely causeFix
    The production webhook does not respondThe workflow is not published (only the test URL works)Publish it; use /webhook/…, not /webhook-test/…
    The webhook shows a wrong address behind a proxyn8n does not know its external addressSet N8N_WEBHOOK_URL (and N8N_PROXY_HOPS)
    The schedule fires at the wrong hourThe zone is the default America/New_YorkSet GENERIC_TIMEZONE (and TZ)
    After a move, credentials cannot be readA different N8N_ENCRYPTION_KEYRestore the old key; in queue mode — the same on all instances
    No Execute Command or Local File Trigger nodeDisabled by default since 2.0Change NODES_EXCLUDE — only if you understand the risk
    Python in the Code node does not start or complains about item.jsonNative Python needs task runners in external mode and bracket accessRun the n8nio/runners image; use _items and item["json"]
    $evaluateExpression() in Code returns nullNot supported with task runnersWrite the logic in JavaScript or evaluate the expression in Edit Fields before Code
    The error workflow does not fire in a manual testThe Error Trigger runs only from an automatic executionTest through a trigger or a published workflow
    CLI publishing has no effectn8n is running while the CLI writes to the databaseRestart n8n
    A webhook request is rejected for sizeOver 16 MiBRaise N8N_PAYLOAD_SIZE_MAX (with more memory and CPU)
    The database keeps growingAll executions are savedKeep EXECUTIONS_DATA_PRUNE on and lower EXECUTIONS_DATA_MAX_AGE

04Check

Checklist

Quiz

1. How do you publish a workflow from the command line in 2.x?

2. In queue mode, what must be the same on the main instance and the workers?

3. Where should an API key for an external service live?

05What's next

06Sources

  1. n8n: one-line setup · install with Docker · with Docker Compose — image, volume, versions, n8n 3.0.
  2. Server CLI and REST API authentication — publish:workflow, export/import, X-N8N-API-KEY.
  3. What changes in 2.0 — publishing, native Python, disabled nodes, task runners.
  4. Environment variables — the Deployment, Endpoints, Executions, Queue mode, Security and Timezone sections.
  5. Queue mode — Redis, workers, the encryption key.
  6. Expression reference and the Code node.
  7. AI Agent · Webhook · Respond to Webhook · Error Trigger.
  8. Keyboard shortcuts.
  9. GitHub: n8n-io/n8n — quick start and the compose definition.