Variables
Store and manage data throughout your workflow
Variables store and manage data throughout your workflow execution.
Variable Types
Input Variables
Data passed to the workflow when it starts:
javascript// Access trigger input data {{ input.customer_id }} {{ input.data.email }} {{ input.headers['x-custom-header'] }}
Node Output Variables
Results from previous nodes:
javascript// Access node outputs by node name {{ nodes.http_request_1.response.body }} {{ nodes.ai_agent.response.content }} {{ nodes.database_query.rows[0].name }}
Workflow Variables
Custom variables you define:
javascript// Set in a Set Variables node {{ variables.order_total }} {{ variables.is_premium }} {{ variables.retry_count }}
System Variables
Built-in variables available everywhere:
javascript{{ workflow.id }} // Current workflow ID {{ workflow.name }} // Workflow name {{ execution.id }} // Current execution ID {{ execution.started_at }} // Execution start time {{ tenant.id }} // Tenant ID {{ now() }} // Current timestamp
Setting Variables
Set Variables Node
json{ "type": "set_variables", "variables": { "order_total": "{{ nodes.calculate.result.total }}", "is_premium": "{{ input.customer.tier == 'premium' }}", "items_count": "{{ input.items.length }}", "timestamp": "{{ now() }}" } }
Increment/Decrement
json{ "type": "set_variables", "variables": { "retry_count": "{{ variables.retry_count + 1 }}", "remaining": "{{ variables.remaining - 1 }}" } }
Conditional Assignment
json{ "type": "set_variables", "variables": { "discount": "{{ input.amount > 1000 ? 0.1 : 0.05 }}", "status": "{{ nodes.api.response.success ? 'completed' : 'failed' }}" } }
Variable Scope
Global Scope
Variables available throughout the entire workflow:
[Trigger] → [Set Variables] → [Action 1] → [Action 2]
│ │ │ │
└── input └── variables └── Both └── Both
Loop Scope
Variables specific to loop iterations:
javascript// Inside a loop {{ loop.item }} // Current item {{ loop.index }} // Current index (0-based) {{ loop.is_first }} // True if first iteration {{ loop.is_last }} // True if last iteration {{ loop.length }} // Total items
Branch Scope
Variables from parallel branches:
javascript// After a merge node {{ branches.branch_1.result }} {{ branches.branch_2.result }}
Expression Syntax
Basic Operations
javascript// Arithmetic {{ input.price * input.quantity }} {{ variables.total + 10 }} {{ input.amount / 100 }} // String concatenation {{ input.first_name + ' ' + input.last_name }} {{ 'Order #' + input.order_id }} // Comparisons {{ input.amount > 100 }} {{ input.status == 'active' }} {{ input.email != null }}
Array Operations
javascript// Access by index {{ input.items[0] }} {{ input.items[input.items.length - 1] }} // Array methods {{ input.items.length }} {{ input.items.includes('value') }} {{ input.tags.join(', ') }}
Object Operations
javascript// Nested access {{ input.customer.address.city }} {{ input.metadata['custom-key'] }} // Optional chaining {{ input.customer?.address?.city ?? 'Unknown' }}
Built-in Functions
| Function | Description | Example |
|---|---|---|
now() | Current timestamp | {{ now() }} |
uuid() | Generate UUID | {{ uuid() }} |
json() | Parse JSON string | {{ json(input.data) }} |
stringify() | Convert to JSON | {{ stringify(input.object) }} |
format() | Format date | {{ format(now(), 'YYYY-MM-DD') }} |
lower() | Lowercase string | {{ lower(input.email) }} |
upper() | Uppercase string | {{ upper(input.code) }} |
trim() | Trim whitespace | {{ trim(input.name) }} |
split() | Split string | {{ split(input.tags, ',') }} |
round() | Round number | {{ round(input.price, 2) }} |
abs() | Absolute value | {{ abs(input.difference) }} |
min() | Minimum value | {{ min(input.values) }} |
max() | Maximum value | {{ max(input.values) }} |
String Functions
javascript// Formatting {{ lower(input.email) }} // lowercase {{ upper(input.code) }} // UPPERCASE {{ capitalize(input.name) }} // Capitalize {{ trim(input.value) }} // Remove whitespace // Manipulation {{ replace(input.text, 'old', 'new') }} // Replace {{ substring(input.text, 0, 10) }} // Substring {{ split(input.csv, ',') }} // Split to array // Testing {{ startsWith(input.url, 'https://') }} // Starts with {{ endsWith(input.email, '@gmail.com') }} // Ends with {{ contains(input.text, 'keyword') }} // Contains {{ matches(input.phone, '^\+1') }} // Regex match
Date Functions
javascript// Current time {{ now() }} // ISO timestamp {{ timestamp() }} // Unix timestamp // Formatting {{ format(now(), 'YYYY-MM-DD') }} // 2025-01-15 {{ format(now(), 'HH:mm:ss') }} // 14:30:00 {{ format(now(), 'MMMM D, YYYY') }} // January 15, 2025 // Calculations {{ addDays(now(), 7) }} // Add 7 days {{ addHours(now(), 24) }} // Add 24 hours {{ diffDays(date1, date2) }} // Days between dates // Parsing {{ parseDate(input.date, 'MM/DD/YYYY') }} // Parse custom format
Conditional Expressions
javascript// Ternary operator {{ input.amount > 100 ? 'premium' : 'standard' }} // Null coalescing {{ input.name ?? 'Unknown' }} // Logical operators {{ input.active && input.verified }} {{ input.status == 'pending' || input.status == 'review' }} {{ !input.disabled }}
Data Transformation
Map Transform
json{ "type": "transform", "operation": "map", "source": "{{ input.users }}", "transform": { "id": "{{ item.id }}", "full_name": "{{ item.first_name }} {{ item.last_name }}", "email_domain": "{{ split(item.email, '@')[1] }}" } }
Filter Transform
json{ "type": "transform", "operation": "filter", "source": "{{ input.orders }}", "condition": "{{ item.total > 100 && item.status == 'pending' }}" }
Reduce Transform
json{ "type": "transform", "operation": "reduce", "source": "{{ input.items }}", "initial": 0, "expression": "{{ accumulator + item.price * item.quantity }}" }
Variable Picker UI
Using the Variable Picker
- Click in any input field
- Click the
{{}}button or pressCtrl/Cmd + Space - Browse available variables by category
- Click to insert or type to filter
- Press Enter to select
Variable Categories
| Category | Icon | Description |
|---|---|---|
| Input | ↓ | Trigger input data |
| Nodes | ◆ | Previous node outputs |
| Variables | x | Workflow variables |
| System | ⚙ | System variables |
| Functions | f | Built-in functions |
Autocomplete
The variable picker provides:
- Type hints: Shows expected data types
- Sample values: Preview of actual data
- Documentation: Description of each variable
- Recent: Recently used variables
Best Practices
Naming Conventions
javascript// Good - descriptive names {{ variables.order_total }} {{ variables.customer_email }} {{ variables.retry_count }} // Avoid - unclear names {{ variables.x }} {{ variables.temp }} {{ variables.data }}
Null Safety
javascript// Always handle potential nulls {{ input.customer?.name ?? 'Guest' }} {{ input.items?.length ?? 0 }} {{ input.metadata?.custom ?? {} }}
Type Conversion
javascript// String to number {{ parseInt(input.quantity) }} {{ parseFloat(input.price) }} // Number to string {{ String(input.id) }} {{ input.amount.toString() }} // Boolean conversion {{ Boolean(input.value) }} {{ !!input.enabled }}
Complex Expressions
For complex logic, use Execute Code node:
json{ "type": "execute_code", "language": "javascript", "code": "const items = input.items.filter(i => i.active); const total = items.reduce((sum, i) => sum + i.price, 0); return { items, total, count: items.length };" }
Debugging Variables
View Variable Values
- Run workflow in debug mode
- Click on any node
- View "Variables" tab in debug panel
- See all available variables at that point
Log Variables
json{ "type": "execute_code", "code": "console.log('Current variables:', { input, variables, nodes }); return input;" }
Variable Inspector
The debug panel shows:
- Variable name and path
- Current value
- Data type
- Source (input, node, or set)
Next Steps
- Debugging - Debug workflows
- Error Handling - Handle failures
- Actions - Action nodes