Variables
Variables are how data flows through your workflow. When one node produces output, the next node can use that data through variables. Mastering variables is essential for building effective workflows.
This page covers the concept first, then practical usage and syntax, followed by advanced patterns and troubleshooting.
Time to complete: 25 minutes
What Are Variables?
Variables are references to data produced by nodes. They let you:
- Access data from previous nodes
- Insert dynamic values into fields
- Pass information between steps
Node A produces data → Variable references it → Node B uses it
Example:
A webhook receives {"email": "john@example.com"}. You reference it with:
{{webhooktrigger_1.payload.email}}
Result: john@example.com
Variable Syntax
All variables use double curly braces:
{{node_alias.path.to.value}}
Basic Structure
| Part | Description | Example |
|---|---|---|
{{ | Opening braces | Start of variable |
node_alias | Which node | webhooktrigger_1 |
. | Path separator | Dot notation |
path.to.value | Data location | payload.email |
}} | Closing braces | End of variable |
Examples
{{webhooktrigger_1.payload}} → Full payload object
{{webhooktrigger_1.payload.email}} → Email from payload
{{webhooktrigger_1.payload.user.name}} → Nested user name
{{transformdata_1.result}} → Transform output
{{llmintegration_1.output}} → AI-generated text
How Data Flows
Data flows left to right through your workflow:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Webhook │ ───→ │ Transform │ ───→ │ Send Email │
│ Trigger │ │ Data │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
produces: produces: can access:
payload.email formatted_name - webhooktrigger_1.*
payload.name greeting - transformdata_1.*
Key Rules
- Nodes can only access data from upstream nodes (nodes that executed before them)
- Data is available to all downstream nodes (not just the directly connected one)
- Each node's output is stored under its alias
Variable Scope
What's Available Where
Variables are available based on execution order:
[Trigger] → [Node A] → [Node B] → [Node C]
│ │ │ │
▼ ▼ ▼ ▼
Available Can see Can see Can see
to all Trigger Trigger Trigger
outputs + Node A + A + B
Branching Workflows
In branched workflows, variables from one branch aren't available in another:
┌──→ [Branch A] ──┐
[Trigger] ─┤ ├──→ [Merge]
└──→ [Branch B] ──┘
- Branch A cannot access Branch B's outputs
- Merge node can access both branches
Accessing Different Data Types
Simple Values (Strings, Numbers)
{{contact.email}} → "john@example.com"
{{contact.lead_score}} → 85
{{contact.is_active}} → true
Objects (Nested Data)
Use dot notation to access nested properties:
// Data structure:
{
"user": {
"profile": {
"name": "John",
"email": "john@example.com"
}
}
}
// Access with:
{{webhooktrigger_1.payload.user.profile.name}} → "John"
{{webhooktrigger_1.payload.user.profile.email}} → "john@example.com"
Arrays (Lists)
Access array items by index (starting at 0):
// Data structure:
{
"items": ["Apple", "Banana", "Cherry"]
}
// Access with:
{{data.items[0]}} → "Apple"
{{data.items[1]}} → "Banana"
{{data.items[2]}} → "Cherry"
Array of Objects
Combine array index and dot notation:
// Data structure:
{
"contacts": [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
]
}
// Access with:
{{data.contacts[0].name}} → "Alice"
{{data.contacts[1].email}} → "bob@example.com"
Default Values (Fallbacks)
Provide fallback values when data might be missing:
{{variable|"default value"}}
Examples
{{contact.name|"Valued Customer"}} → Uses name, or "Valued Customer" if missing
{{data.quantity|0}} → Uses quantity, or 0 if missing
{{user.role|"member"}} → Uses role, or "member" if missing
Why Use Defaults?
Without defaults, missing data can break your workflow:
❌ Without default: {{contact.name}} → error if name is null
✅ With default: {{contact.name|"Friend"}} → "Friend" if name is null
Type Conversions
Convert data types when needed:
| Conversion | Syntax | Example |
|---|---|---|
| To Integer | {{var|int}} | {{score|int}} → 85 |
| To Float | {{var|float}} | {{price|float}} → 19.99 |
| To Boolean | {{var|bool}} | {{active|bool}} → true |
| To String | {{var|str}} | {{count|str}} → "42" |
Combined with Defaults
{{quantity|int|1}} → Convert to int, default to 1
{{price|float|0.0}} → Convert to float, default to 0.0
Special Variables
Current Date/Time
{{date}} → Current date (YYYY-MM-DD)
{{time}} → Current time (HH:MM:SS)
{{datetime}} → Full datetime
Workflow Context
{{workflow.id}} → Current workflow ID
{{workflow.name}} → Workflow name
{{execution.id}} → Current execution ID
Common Trigger Variables
Webhook Trigger
{{webhooktrigger_1.payload}} → Request body (JSON)
{{webhooktrigger_1.payload.field}} → Specific field
{{webhooktrigger_1.headers}} → HTTP headers
{{webhooktrigger_1.headers.Authorization}}
{{webhooktrigger_1.params}} → Query parameters
{{webhooktrigger_1.method}} → GET, POST, etc.
Database Trigger
{{databasetrigger_1.entity_id}} → Record ID
{{databasetrigger_1.entity_type}} → contacts, deals, etc.
{{databasetrigger_1.operation}} → INSERT, UPDATE, DELETE
{{databasetrigger_1.new_data}} → Current record
{{databasetrigger_1.old_data}} → Previous record (UPDATE)
{{databasetrigger_1.changed_fields}} → What changed
User Message Trigger
{{usermessagetrigger_1.message}} → User's message
{{usermessagetrigger_1.context}} → Conversation history
{{usermessagetrigger_1.matched}} → Keyword matched
Scheduler Trigger
{{schedulertrigger_1.triggered_at}} → Execution time
{{schedulertrigger_1.schedule_type}} → cron, interval, etc.
{{schedulertrigger_1.iteration}} → Run count
Common Node Outputs
Transform Data
{{transformdata_1.result}} → Transform output
{{transformdata_1.field_name}} → Specific field from return
LLM Integration
{{llmintegration_1.output}} → Generated text
{{llmintegration_1.success}} → true/false
{{llmintegration_1.tokens_used}} → Token count
Email Send
{{emailsend_1.success}} → true/false
{{emailsend_1.message_id}} → Email ID
KB Search
{{kbsearch_1.results}} → Array of matches
{{kbsearch_1.results[0].content}} → First result content
{{kbsearch_1.results[0].similarity}} → Match score
Condition
{{condition_1.result}} → true/false
{{condition_1.evaluated_value}} → Value that was checked
Finding the Right Variable
Using the Variable Picker
The variable picker is your primary tool for finding and inserting variables.
Opening the picker:
- Click in any field that accepts variables
- Type
{{to trigger the picker automatically - Or click the
{x}icon in the field
Navigating the picker:
┌─────────────────────────────────────────┐
│ 🔍 Search... │
├─────────────────────────────────────────┤
│ Available Variables │
│ │
│ ▶ webhooktrigger_1 │ ← Click to expand
│ ▶ transformdata_1 │
│ ▶ llmintegration_1 │
│ │
│ Special Variables │
│ ├── {{date}} │
│ ├── {{time}} │
│ └── {{datetime}} │
└─────────────────────────────────────────┘
Expanding a node:
▼ webhooktrigger_1
├── payload │
│ ├── email "john@example.com" │ ← Preview value
│ ├── name "John Smith" │
│ └── company "Acme Inc" │
├── headers │
│ └── Content-Type "application/json" │
└── method "POST" │
| Section | Shows |
|---|---|
| Nodes | Outputs from each node |
| Search | Find variables by name |
| Preview | See current value |
Searching Variables
Type in the search box to filter:
🔍 email
Results:
├── webhooktrigger_1.payload.email
├── contact.email
└── user.email_address
Variable Preview
Hover over any variable to see:
- Current value (from last test run)
- Data type (string, number, array, object)
- Full path to insert
┌─────────────────────────────────────┐
│ webhooktrigger_1.payload.email │
│ ─────────────────────────────────── │
│ Value: "john@example.com" │
│ Type: string │
│ Click to insert │
└─────────────────────────────────────┘
Inserting Variables
Method 1: Variable Picker (Recommended)
- Position cursor where you want the variable
- Type
{{or click{x} - Navigate/search for your variable
- Click to insert
Before: Hello [cursor here]
After: Hello {{contact.first_name}}
Method 2: Type Directly
If you know the exact path:
{{webhooktrigger_1.payload.email}}
Useful when:
- You know the variable path
- Copying from documentation
- Quick edits
Method 3: Copy & Paste
Copy variables from:
- Other fields in the workflow
- Documentation
- Previous workflows
- Test output panels
Copying Variables
From Node Output Panel
During or after a test:
- Click on a node
- View the Output tab
- Click on any value to copy its variable path
Output Panel:
┌─────────────────────────────────────┐
│ { │
│ "email": "john@example.com", │ ← Click to copy path
│ "name": "John Smith" │
│ } │
└─────────────────────────────────────┘
Copied: {{transformdata_1.email}}
From Another Field
- Select the variable text (including
{{ }}) - Copy with
Ctrl/Cmd + C - Paste with
Ctrl/Cmd + V
From Test Results
In the execution panel:
- Find the execution
- Click on a node
- Copy from the JSON output
Checking Variable Values
During Test Mode
Run a test to see real values:
- Click Test in toolbar
- Enter sample input
- Run the test
- Click any node to see:
- Input: What the node received
- Output: What the node produced
In the Variable Picker
Variables show their last known value:
{{contact.email}}
Preview: "john@example.com"
Note: Preview shows value from last test run. Run a new test for current values.
Using Transform for Debugging
Add a Transform node to inspect variables:
// Debug: log all available data
console.log("Trigger data:", input.webhooktrigger_1);
console.log("Contact:", input.contact);
// Return everything for inspection
return {
debug: true,
all_input: input
};
Using Variables in Fields
Text Fields
Embed variables directly in text:
Hello {{contact.first_name}},
Welcome to {{company.name}}! Your account was created on {{date}}.
Best regards,
{{user.name}}
Multiple Variables
Combine multiple variables:
Order #{{order.id}} for {{customer.name}} - Total: ${{order.total}}
In Conditions
Use variables in condition checks:
Field: {{contact.lead_score}}
Operator: greater_than
Value: 80
In Code/Transform
Access in JavaScript:
const email = input.webhooktrigger_1.payload.email;
const name = input.contact.first_name || "Friend";
return {
greeting: `Hello ${name}`,
formatted_email: email.toLowerCase()
};
Common Variable Patterns
Email Templates
Hello {{contact.first_name|"there"}},
Thank you for your interest in {{product.name}}.
Your order #{{order.id}} has been confirmed.
Best regards,
{{user.name}}
{{company.name}}
Conditional Logic
Use in condition nodes:
Field: {{contact.lead_score}}
Operator: greater_than
Value: 80
API Request Body
{
"customer_id": "{{contact.id}}",
"email": "{{contact.email}}",
"order_total": {{order.total|0}},
"items": {{order.items}}
}
Dynamic URLs
https://api.example.com/users/{{user.id}}/orders/{{order.id}}
Combining Variables
{{contact.first_name}} {{contact.last_name}}
→ "John Smith"
{{contact.first_name}} {{contact.last_name}} ({{contact.email}})
→ "John Smith (john@example.com)"
Conditional Text
Use Transform node for conditional logic:
const name = input.contact.first_name;
return {
greeting: name ? `Hello ${name}!` : "Hello there!"
};
Array to String
Join array items:
const items = input.order.items;
return {
item_list: items.map(i => i.name).join(", ")
};
// → "Apple, Banana, Cherry"
Advanced Techniques
Building Dynamic Content
In Transform node:
const items = input.order.items;
let itemList = items.map((item, i) =>
`${i + 1}. ${item.name} - $${item.price}`
).join('\n');
return {
order_summary: `Order #${input.order.id}\n\n${itemList}\n\nTotal: $${input.order.total}`
};
Accessing Nested Dynamic Keys
When key name is in a variable:
// In Transform node
const fieldName = input.dynamic_field_name;
const value = input.data[fieldName];
return { extracted_value: value };
Flattening Nested Objects
// Convert nested object to flat structure
const contact = input.webhooktrigger_1.payload.contact;
return {
email: contact.email,
name: `${contact.first_name} ${contact.last_name}`,
company: contact.company?.name || "Unknown"
};
Troubleshooting Variables
Variable Not Found
Symptom: undefined, empty, or error when using variable
Check list:
- ✅ Is the node alias spelled correctly?
- ✅ Did the source node execute successfully (before this one)?
- ✅ Is the path correct (case-sensitive)?
- ✅ Does the data exist in the source?
Debugging steps:
- Run a test
- Click on the source node
- Check its Output panel
- Verify the field exists (use the variable picker to confirm the path)
Wrong Value
Symptom: Variable returns unexpected data
Check list:
- ✅ Are you accessing the right node?
- ✅ Is the path complete?
- ✅ Are you using correct array index (starts at 0)?
- ✅ Is the data type correct (string vs number)?
Example fix:
Wrong: {{webhooktrigger_1.email}}
Right: {{webhooktrigger_1.payload.email}}
↑
Missing level
Empty String vs Null
Symptom: Variable appears empty or resolves to nothing
Possible causes:
- Field exists but is empty string
"" - Field is
nullorundefined - Field doesn't exist at all
- A condition skipped the source node
Solution: Use default values
{{contact.company|"No company"}}
Array Index Out of Range
Symptom: Accessing [0] returns undefined
Cause: Array is empty
Solution: Check array length first
// In Transform node
const items = input.data.items || [];
if (items.length > 0) {
return { first_item: items[0] };
} else {
return { first_item: null };
}
Best Practices
Naming / Use Descriptive Aliases
✅ Clear paths: webhooktrigger_1.payload.customer.email
✅ Descriptive aliases: validate_email.result, format_contact_data.full_name
❌ Ambiguous: data.x
❌ Generic: node1.output, transformdata_1.x
Always Use Defaults for Optional Data
✅ Safe: {{contact.company|"N/A"}}
✅ Check arrays have items before accessing
✅ Validate required fields early
❌ Risky: {{contact.company}}
❌ Don't assume data exists
❌ Don't access array[0] without checking length
Validate Early
Add validation at the start of your workflow:
[Trigger] → [Validate Required Fields] → [Continue...]
Document Complex Variables
In node descriptions:
This node uses:
- {{webhooktrigger_1.payload.customer}} - Customer object
- {{webhooktrigger_1.payload.items}} - Array of order items
Test with Edge Cases
Test your workflow with:
- Empty values
- Missing fields
- Very long strings
- Special characters
- Empty arrays
Performance
✅ Use Transform to combine multiple operations
✅ Access only the data you need
✅ Cache repeated calculations
❌ Don't repeatedly access the same nested path
Quick Reference
Syntax Cheatsheet
{{node.field}} → Basic access
{{node.nested.field}} → Nested object
{{node.array[0]}} → Array item
{{node.array[0].field}} → Object in array
{{node.field|"default"}} → With default
{{node.field|int}} → Type conversion
{{date}} → Current date
Common Variables
Webhook: {{webhooktrigger_1.payload.field}}
Database: {{databasetrigger_1.new_data.field}}
Transform: {{transformdata_1.result}}
LLM: {{llmintegration_1.output}}
Email: {{emailsend_1.success}}
Condition: {{condition_1.result}}
Type Conversions
|int → Integer
|float → Decimal
|bool → Boolean
|str → String
Finding Variables
Type {{ Open picker from field
Click {x} Open picker via icon
Search Filter by name
Expand Click node to see fields
Preview Hover for current value
Copying Variables
From picker Click to insert
From output Click value in JSON
From field Select and Ctrl/Cmd + C
Common Issues
undefined Check path spelling
empty Use default value
wrong type Use type conversion
missing Verify source node ran
Next Steps
Now that you understand variables, continue with:
- Configuring Nodes - Fill in node settings
- Using Conditions & Branches - Logic with variables
- Data Transformation - Process data with code
- Testing Workflows - Verify variable values