n8n Variables and Expressions:
Guía de referencia completa 2026

El sistema de expresiones de n8n es lo que separa las automatizaciones simples de los flujos de trabajo verdaderamente dinámicos e impulsados por datos. La sintaxis {{ }} le brinda acceso a datos de cualquier nodo anterior, variables integradas, funciones de JavaScript y configuración del entorno, todo en línea, sin un nodo de código separado. Dominar las expresiones desbloquea todo el poder de n8n. Esta guía es una referencia completa que puede marcar y a la que puede volver.

Conceptos básicos de la sintaxis de expresiones

Envuelva cualquier expresión entre llaves dobles: {{ your expression here }}. Todo lo que está dentro se evalúa como JavaScript. Puede hacer referencia a variables de n8n, usar métodos de cadena, hacer aritmética, llamar a operadores ternarios y encadenar operaciones. Fuera de las llaves se trata como texto literal.

Fundamentos de la sintaxis de expresiones

Las expresiones pueden aparecer en cualquier campo de texto en n8n: parámetros de nodo, encabezados, URL, cuerpos de mensajes y más. Active un campo al modo de expresión haciendo clic en el icono de rayo (⚡) junto a cualquier campo de entrada, o escribiendo {{.

Mezcla de literal vs expresión

# Literal text only (no expression — always shows exactly this) Hello World # Pure expression (entire field is one expression) {{ $json.name }} # Mixed: literal text with embedded expressions Hello, {{ $json.firstName }}! Your order {{ $json.orderId }} is ready. # Multiple expressions in one field {{ $json.city }}, {{ $json.country }}{{ $json.postalCode }} # Arithmetic Total: ${{ ($json.price * $json.quantity).toFixed(2) }} # Conditional (ternary) {{ $json.isVip ? 'VIP Customer' : 'Standard Customer' }}
Editor de expresiones

Haga clic en el icono de rayo ⚡ en cualquier campo para abrir el Editor de expresiones completo. Proporciona autocompletado para todas las variables integradas, una vista previa en vivo que muestra el valor resuelto con sus datos actuales reales y resaltado de sintaxis. Úselo al crear expresiones complejas, mucho más fácil que adivinar.

$json — Acceso a los datos del nodo actual

$json se refiere a los datos JSON del elemento actual que se está procesando. Es la variable más utilizada en n8n.

# Given this item data from the previous node: { "id": 42, "name": "Alice Johnson", "email": "alice@example.com", "address": { "city": "London", "zip": "SW1A 1AA" }, "tags": ["premium", "active"] } # Access flat fields: {{ $json.id }} → 42 {{ $json.name }} → "Alice Johnson" {{ $json.email }} → "alice@example.com" # Access nested objects: {{ $json.address.city }} → "London" {{ $json.address.zip }} → "SW1A 1AA" # Access array elements: {{ $json.tags[0] }} → "premium" {{ $json.tags.length }} → 2 {{ $json.tags.join(', ') }} → "premium, active" # Access fields with spaces or special characters: {{ $json['field name'] }} # bracket notation required {{ $json['user-id'] }} # hyphen in key name

$node — Datos de cualquier nodo anterior

$node le brinda acceso a la salida de cualquier nodo con nombre en su flujo de trabajo, no solo al inmediatamente anterior. Esto es esencial cuando necesita datos de varios pasos atrás.

# Access data from a node named "Get Customer": {{ $node["Get Customer"].json.name }} {{ $node["Get Customer"].json.email }} # Access data from a node named "HTTP Request": {{ $node["HTTP Request"].json.status }} # Access first item from a multi-item node output: {{ $node["List Orders"].json.orderId }} # defaults to current item index # Access a specific item by index (0-based): {{ $node["List Orders"].json[0].orderId }} # always first item # Check node run status: {{ $node["HTTP Request"].runIndex }} # which run (for looped nodes) {{ $node["HTTP Request"].itemIndex }} # current item index
Los nombres de los nodos distinguen entre mayúsculas y minúsculas

$node["Get Customer"] y $node["get customer"] son diferentes. Siempre coincida con el nombre exacto del nodo tal como aparece en el lienzo. Cambie el nombre de sus nodos a nombres descriptivos antes de hacer referencia a ellos: "HTTP Request3" es un objetivo de referencia deficiente.

$items — Todos los elementos de un nodo

$items() devuelve la matriz completa de todos los elementos emitidos por un nodo, no solo el elemento actual. Utilice esto cuando necesite agregar o comparar entre todos los elementos.

# Get all items from the immediately previous node: {{ $items() }} → Array of all items {{ $items().length }} → Total count of items # Get all items from a specific named node: {{ $items("Get Products") }} {{ $items("Get Products").length }} # Access a specific item by index: {{ $items("Get Products")[0].json.name }} # first product name {{ $items("Get Products")[2].json.price }} # third product price # Sum a field across all items (in Code node or expression): {{ $items("Get Orders").reduce((sum, item) => sum + item.json.total, 0) }} # Get all email addresses as an array: {{ $items("Get Contacts").map(item => item.json.email) }} # Find first item matching a condition: {{ $items("Products").find(i => i.json.id === $json.productId)?.json.name }}

Variables integradas: $now, $today, $workflow, $execution

n8n proporciona un conjunto de variables integradas que puede usar en cualquier expresión sin hacer referencia a un nodo.

Variables de fecha y hora

VariableDescriptionExample Output
$nowFecha y hora actuales como un objeto Luxon DateTime2026-03-13T08:00:00.000Z
$todayComienzo de hoy (medianoche) como Luxon DateTime2026-03-13T00:00:00.000Z
$now.toISO()Cadena ISO 8601"2026-03-13T08:00:00.000Z"
$now.toISODate()Cadena solo de fecha"2026-03-13"
$now.toFormat('dd/MM/yyyy')Cadena de formato personalizado"13/03/2026"
$now.toFormat('h:mm a')Hora con AM/PM"8:00 AM"
$now.plus({ days: 7 }).toISODate()7 días a partir de ahora"2026-03-20"
$now.minus({ hours: 24 }).toISO()Hace 24 horasfecha y hora de ayer
$now.weekdayDía de la semana (1=Lun, 7=Dom)5
$now.monthNúmero de mes3
$now.yearAño2026
$now.toMillis()Marca de tiempo de Unix en ms1741863600000

Variables de flujo de trabajo y ejecución

VariableDescriptionExample Output
$workflow.idID único del flujo de trabajo"abc123"
$workflow.nameNombre del flujo de trabajo"Alerta meteorológica matutina"
$workflow.activeSi el flujo de trabajo está activadotrue
$execution.idID único de la ejecución actual"ex_xyz789"
$execution.mode"manual" o "trigger""trigger"
$execution.resumeUrlURL para reanudar una ejecución en esperahttps://...
$itemIndexÍndice del elemento actual que se está procesando0
$runIndexÍndice de ejecución actual (para nodos reintentados)0

JavaScript en expresiones

Todo lo que está dentro de {{ }} es JavaScript. Puede usar la biblioteca estándar completa de JavaScript: métodos de cadena, operaciones de matriz, matemáticas, regex, Date, JSON y más.

Operaciones de cadena

# Uppercase / lowercase {{ $json.name.toUpperCase() }} → "ALICE JOHNSON" {{ $json.name.toLowerCase() }} → "alice johnson" # Trim whitespace {{ $json.email.trim() }} # Extract substring {{ $json.sku.slice(0, 5) }} # first 5 characters {{ $json.description.slice(0, 100) + '...' }} # truncate to 100 chars # Split and rejoin {{ $json.fullName.split(' ')[0] }} # extract first name {{ $json.tags.split(',').map(t => t.trim()) }} # clean split # Replace and regex {{ $json.phone.replace(/[^0-9]/g, '') }} # strip non-digits {{ $json.url.replace('http://', 'https://') }} # Template literal (alternative to mixed expressions) {{ `Hello ${$json.name}, you have ${$json.unread} unread messages.` }} # Pad a number with leading zeros {{ String($json.id).padStart(6, '0') }} → "000042" # Check if string contains a value {{ $json.email.includes('@gmail.com') }} → true/false # Extract domain from email {{ $json.email.split('@')[1] }} → "example.com"

Operaciones numéricas y matemáticas

# Arithmetic {{ $json.price * 1.2 }} # add 20% tax {{ ($json.subtotal + $json.tax).toFixed(2) }} # 2 decimal places # Math functions {{ Math.round($json.score) }} {{ Math.min($json.quantity, 100) }} # cap at 100 {{ Math.max(0, $json.balance) }} # floor at 0 {{ Math.abs($json.difference) }} # absolute value {{ Math.floor($json.rating) }} # round down {{ Math.ceil($json.pages) }} # round up {{ (($json.correct / $json.total) * 100).toFixed(1) + '%' }} # Parse string to number {{ parseInt($json.ageString, 10) }} {{ parseFloat($json.priceString) }} {{ Number($json.valueString) }} # Random number (use in Code node for reproducibility) {{ Math.floor(Math.random() * 100) }}

Operaciones de matriz y objeto

# Check if value exists in array {{ $json.roles.includes('admin') }} → true/false # Filter array (returns new array) {{ $json.orders.filter(o => o.status === 'pending') }} # Map — transform each element {{ $json.products.map(p => p.name) }} # extract names # Reduce — aggregate to single value {{ $json.items.reduce((sum, i) => sum + i.price, 0) }} # Sort array of objects {{ $json.users.sort((a, b) => a.name.localeCompare(b.name)) }} # Get unique values {{ [...new Set($json.categories)] }} # Object manipulation {{ Object.keys($json.settings) }} # array of keys {{ Object.values($json.settings) }} # array of values {{ JSON.stringify($json.metadata) }} # convert to JSON string {{ JSON.parse($json.configString) }} # parse JSON string

Expresiones condicionales

Utilice operadores ternarios de JavaScript y la fusión nula para la lógica condicional directamente en las expresiones:

# Ternary: condition ? valueIfTrue : valueIfFalse {{ $json.score >= 90 ? 'A' : $json.score >= 80 ? 'B' : 'C' }} # Nullish coalescing: use default if value is null/undefined {{ $json.nickname ?? $json.firstName }} {{ $json.city ?? 'Unknown City' }} # Optional chaining: safe access of nested properties {{ $json.user?.address?.city ?? 'No city' }} # Logical OR: use default if value is falsy (0, '', null, undefined) {{ $json.displayName || $json.email }} # Logical AND: only use right side if left is truthy {{ $json.isVip && 'VIP' }} → 'VIP' or false # Checking for empty array {{ $json.items.length === 0 ? 'No items' : `${$json.items.length} items` }} # Multi-condition with logical operators {{ $json.age >= 18 && $json.country === 'US' ? 'Eligible' : 'Not eligible' }}

Variables de entorno en n8n

Para los valores de configuración que no deben estar codificados en los flujos de trabajo (claves de API, URL base, indicadores de características), utilice el sistema de variables integrado de n8n.

Variables de n8n (Configuración → Variables)

Agregado en n8n 0.225, esta es la forma recomendada de almacenar valores reutilizables sin acceso al entorno:

# Set in n8n UI: Settings → Variables → Add Variable Name: API_BASE_URL Value: https://api.yourapp.com/v2 # Use in any expression: {{ $vars.API_BASE_URL }} → "https://api.yourapp.com/v2" {{ $vars.API_BASE_URL + '/users' }} → "https://api.yourapp.com/v2/users" {{ $vars.SUPPORT_EMAIL }} {{ $vars.MAX_RETRY_COUNT }}

Variables de entorno del sistema (solo autoalojado)

# Access OS environment variables (must be allowlisted in n8n config) # Add to n8n environment: N8N_CUSTOM_ENV_VARS=MY_SECRET,MY_BASE_URL {{ $env.MY_SECRET }} # environment variable {{ $env.MY_BASE_URL }} # Note: $env is NOT available on n8n Cloud for security reasons # Use $vars (n8n Variables) instead — works on both Cloud and self-hosted

Datos estáticos: persistencia de valores entre ejecuciones

n8n proporciona un almacén de clave-valor por flujo de trabajo llamado datos estáticos. A diferencia de las variables normales, los valores almacenados aquí persisten entre ejecuciones, lo que resulta útil para rastrear el estado, los contadores o las marcas de tiempo de la última ejecución.

# Static data is read/written in Code nodes only (not expressions) # Get the workflow's static data object const staticData = $getWorkflowStaticData('global'); # Read a value const lastRunTime = staticData.lastRunAt || 'never'; # Write a value (persists after execution ends) staticData.lastRunAt = new Date().toISOString(); staticData.processedCount = (staticData.processedCount || 0) + 1; # Use case: only process records created after last run const cutoff = staticData.lastRunAt || '2000-01-01'; staticData.lastRunAt = new Date().toISOString(); return items.filter(i => i.json.createdAt > cutoff);

Patrones de expresión comunes

Estos patrones resuelven los casos de uso de expresiones más frecuentes en flujos de trabajo reales:

Formato de fecha para diferentes API

# ISO 8601 (most REST APIs) {{ $now.toISO() }} → "2026-03-13T08:00:00.000Z" # Unix timestamp in seconds (Stripe, Twilio) {{ Math.floor($now.toMillis() / 1000) }} → 1741863600 # Human-readable for emails {{ $now.toFormat('MMMM d, yyyy') }} → "March 13, 2026" # Parse an incoming date string {{ DateTime.fromISO($json.createdAt).toFormat('dd/MM/yyyy') }} # Calculate days between two dates {{ DateTime.fromISO($json.dueDate).diff(DateTime.now(), 'days').days }} # Add business days (approximation) {{ $now.plus({ days: 5 }).toISODate() }} # 5 calendar days from now

Creación de URL dinámicas y cadenas de consulta

# Dynamic URL path https://api.example.com/users/{{ $json.userId }}/orders # URL with query parameters built in expression {{ `https://api.example.com/search?q=${encodeURIComponent($json.query)}&page=${$json.page}&limit=50` }} # Conditional URL based on environment variable {{ $vars.ENV === 'production' ? 'https://api.example.com' : 'https://staging.example.com' }}

Manejo seguro de nulos e indefinidos

# Safe nested access (won't throw if intermediate is null) {{ $json.user?.profile?.bio ?? 'No bio provided' }} # Convert null to empty string (for text fields) {{ $json.middleName ?? '' }} # Convert undefined array to empty array before .map() {{ ($json.items ?? []).map(i => i.name) }} # Safely parse a number that might be a string or null {{ $json.amount != null ? parseFloat($json.amount) : 0 }}

Uso eficaz del editor de expresiones

El Editor de expresiones (accesible a través del icono de rayo ⚡ en cualquier campo) es su mejor amigo para crear expresiones complejas. Características clave:

  • Vista previa en vivo: muestra el valor resuelto de su expresión utilizando datos reales de la última ejecución o datos anclados. Si la vista previa muestra [undefined], la ruta es incorrecta.
  • Autocompletar: escriba $ para ver todas las variables disponibles. Escriba $json. para ver todos los campos disponibles de sus datos actuales.
  • Resaltado de sintaxis: hace que las expresiones complejas sean legibles.
  • Mensajes de error: los errores de sintaxis de JavaScript se muestran en línea.
  • Explorador de datos: explore la estructura de datos entrantes en el panel izquierdo mientras crea la expresión.

Errores comunes y cómo solucionarlos

1. "[undefined]" en la salida

Problem: {{ $json.user.name }} → "[undefined]" Causes and fixes: A) The field name is wrong — check the actual JSON keys (they're case-sensitive) Fix: {{ $json.userName }} or {{ $json.user_name }} B) The data structure is nested differently than expected Fix: Use the Expression Editor data explorer to inspect the actual structure C) You're referencing a field that doesn't exist in all items Fix: {{ $json.user?.name ?? 'Unknown' }}

2. La expresión no se evalúa (muestra texto literal)

Problem: Output shows "{{ $json.name }}" as literal text Cause: The field is in "fixed" mode, not "expression" mode Fix: Click the bolt icon ⚡ next to the field to switch to expression mode You'll see the field background change to indicate expression mode

3. TypeError en el acceso nulo

Problem: Cannot read properties of null (reading 'name') Cause: {{ $json.user.name }} where $json.user is null Fix: Use optional chaining: {{ $json.user?.name }} Or with a fallback: {{ $json.user?.name ?? 'Anonymous' }}

4. Datos incorrectos de la referencia $node

Problem: $node["My Node"].json is empty or wrong Common causes: - The node name changed (rename on canvas != update in expression) - The referenced node has multiple outputs and you need a specific one - The node didn't execute in this workflow run (e.g., it was on an IF branch not taken) Fix: Always check the exact node name on the canvas and update expressions after renaming

Preguntas frecuentes

¿Puedo usar async/await en expresiones n8n?
No. Las expresiones deben ser sincrónicas. Para operaciones asíncronas (llamadas API, consultas de bases de