Skip to main content

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

PartDescriptionExample
{{Opening bracesStart of variable
node_aliasWhich nodewebhooktrigger_1
.Path separatorDot notation
path.to.valueData locationpayload.email
}}Closing bracesEnd 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

  1. Nodes can only access data from upstream nodes (nodes that executed before them)
  2. Data is available to all downstream nodes (not just the directly connected one)
  3. 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:

ConversionSyntaxExample
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
{{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:

  1. Click in any field that accepts variables
  2. Type {{ to trigger the picker automatically
  3. 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" │
SectionShows
NodesOutputs from each node
SearchFind variables by name
PreviewSee 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

  1. Position cursor where you want the variable
  2. Type {{ or click {x}
  3. Navigate/search for your variable
  4. 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:

  1. Click on a node
  2. View the Output tab
  3. 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

  1. Select the variable text (including {{ }})
  2. Copy with Ctrl/Cmd + C
  3. Paste with Ctrl/Cmd + V

From Test Results

In the execution panel:

  1. Find the execution
  2. Click on a node
  3. Copy from the JSON output

Checking Variable Values

During Test Mode

Run a test to see real values:

  1. Click Test in toolbar
  2. Enter sample input
  3. Run the test
  4. 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:

  1. ✅ Is the node alias spelled correctly?
  2. ✅ Did the source node execute successfully (before this one)?
  3. ✅ Is the path correct (case-sensitive)?
  4. ✅ Does the data exist in the source?

Debugging steps:

  1. Run a test
  2. Click on the source node
  3. Check its Output panel
  4. Verify the field exists (use the variable picker to confirm the path)

Wrong Value

Symptom: Variable returns unexpected data

Check list:

  1. ✅ Are you accessing the right node?
  2. ✅ Is the path complete?
  3. ✅ Are you using correct array index (starts at 0)?
  4. ✅ 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 null or undefined
  • 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:

  1. Configuring Nodes - Fill in node settings
  2. Using Conditions & Branches - Logic with variables
  3. Data Transformation - Process data with code
  4. Testing Workflows - Verify variable values