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