Variables & Expressions
Variables are how your chatbot flow remembers information throughout a conversation. When a customer answers a question, when you fetch data from an external system, or when a webhook sends data — all of that is stored in variables that you can use anywhere in the flow.
What are variables?
A variable is a named placeholder that holds a value. For example:
{{customer_name}}might hold "Rahul"{{order_total}}might hold "2500"{{selected_product}}might hold "Premium Plan"
You use variables by typing their name inside double curly braces: {{variable_name}}
Where do variables come from?
| Source | How it works | Example variable |
|---|---|---|
| System | Automatically available in every flow | {{customer_name}}, {{customer_phone}} |
| Trigger | Passed by the trigger when the flow starts | {{order.catalog_id}}, {{trigger_1.ad.headline}} |
| Question node | Customer types an answer → saved to the variable you specify | {{user_email}}, {{order_number}} |
| HTTP Call node | External system returns data → saved with the node's name as prefix | {{http_call_1.status}}, {{http_call_1.result.tracking_url}} |
| Contact data | Get Details action fetches contact info → saved with a prefix | {{lead_name}}, {{lead_email}} |
| Script node | Script calculates a result → saved with the node's name as prefix | {{script_1.discount_amount}}, {{script_1.final_price}} |
| Interactive responses | Button clicks and list selections | {{button_id}}, {{row_id}} |
System variables
These are available in every flow, regardless of trigger type:
| Variable | Description | Example value |
|---|---|---|
{{customer_name}} | Customer's name from their WhatsApp profile | John Doe |
{{customer_phone}} | Customer's phone number | +919876543210 |
{{initial_message}} | The first message the customer sent that triggered the flow | Hello, I need help |
{{whatsapp_message_id}} | Unique ID of the triggering WhatsApp message | wamid.HBgLMTY1MDg5... |
Last interaction variables
When a customer taps a button or selects a list row, the value is captured in these variables for use in the next nodes:
| Variable | Description | Example value |
|---|---|---|
{{_last_button_payload}} | Payload of the last button the customer tapped (the dynamic value, e.g. a custom payload) | approve_REQ123 |
{{_last_button_text}} | Visible label of the last button tapped | Approve |
{{_last_row_payload}} | Payload of the last list row selected | order_42 |
{{_last_row_text}} | Visible title of the last list row selected | Order #42 |
{{_last_template_button_clicked}} | Payload of the last template quick-reply button tapped | confirm_order |
A Button Click trigger can extract part of a payload into a variable you name (via Extract to Variable). For example, payload approve_REQ123 with pattern approve_ saved to approval_id makes {{approval_id}} = REQ123 available throughout the flow. Your extracted variables also appear in the Expression Builder's variable list.
Node names and data flow
Every node in your flow has a node name — this is how the system organizes data and how you reference a node's output in later nodes. Understanding node names is key to building flows where data moves from one step to the next.
Default node names
When you add a node to the canvas, it gets an automatic name based on its type and a sequential number:
| Node type | Default name examples |
|---|---|
| Trigger | trigger_1 |
| Message | message_1, message_2, message_3 |
| Interactive Message | interactive_message_1, interactive_message_2 |
| Question | question_1, question_2 |
| Condition | condition_1, condition_2 |
| Router | router_1, router_2 |
| HTTP Call | http_call_1, http_call_2 |
| Script | script_1, script_2 |
| Lead Management | lead_management_1, lead_management_2 |
| Template Message | template_message_1, template_message_2 |
| Media Message | media_message_1, media_message_2 |
| SPM | interactive_spm_1 |
| MPM | interactive_mpm_1 |
| WhatsApp Flow | whatsapp_flow_1 |
| End | end_1, end_2 |
Renaming a node
You can rename any node to something more descriptive by editing the Node Name field in the node's configuration panel.
2. Find the Node Name field at the top of the config
3. Capture the field showing a custom name like "fetch_customer" with the variables hint below
Save to:
static/img/screenshots/chatbot-flows/variables/node-name-input.pngThe Node Name field shows a helpful hint: Variables: {{node_name.variable}} — this tells you how to reference this node's output in other nodes.
Naming rules:
- Only letters, numbers, and underscores allowed
- Cannot start with a number
- Maximum 50 characters
- Must be unique across the flow
Auto-refactoring on rename
If you rename a node that is already referenced by other nodes, the system shows a confirmation dialog listing all the places where the old name is used. If you confirm, it automatically updates all references throughout the flow.
For example, if you rename http_call_1 to fetch_order and 3 other nodes use {{http_call_1.status}}, the system will update them all to {{fetch_order.status}}.
2. Capture the confirmation dialog showing the list of affected references
Save to:
static/img/screenshots/chatbot-flows/variables/node-name-refactor-dialog.pngIf a node name is used in other nodes (shown as "Used in X place(s)" beneath the name field), renaming it will update all those references. Make sure the new name is correct before confirming.
How data flows between nodes
When a node runs, its output is saved to the session using the node's name as a prefix. This means you can access any previous node's output by combining the node name with the variable name using dot notation.
The pattern: {{node_name.variable}}
Here's how each node type saves and exposes its data:
Question node → Variable
A Question node saves the customer's answer to a custom variable name that you specify.
| Setting | What it does |
|---|---|
| Save to variable | The variable name where the answer is stored |
If you set "Save to variable" to user_email, the customer's answer is saved as {{user_email}}.
Example flow:
Question: "What's your email?"
└── Save to variable: user_email
Message: "Thanks! We'll send updates to {{user_email}}"
HTTP Call node → Response data
An HTTP Call node saves the entire response using the node's name as a prefix. You access specific fields using dot notation.
If the node is named http_call_1 and the response is:
{
"status": 200,
"result": {
"order_id": "ORD-123",
"tracking_url": "https://track.example.com/123"
}
}
You access the data as:
| Variable | Value |
|---|---|
{{http_call_1.status}} | 200 |
{{http_call_1.result.order_id}} | ORD-123 |
{{http_call_1.result.tracking_url}} | https://track.example.com/123 |
Instead of using {{http_call_1.result.order_id}}, rename the node to something meaningful like fetch_order. Then you can write {{fetch_order.result.order_id}} — much easier to read!
Script node → Output variables
A Script node maps input variables from the session into the script, and output variables from the script back to the session. Outputs are saved with the node's name as a prefix.
If the node is named script_1 and the script returns:
return { finalPrice: 2950, taxAmount: 450 };
You access the output as:
| Variable | Value |
|---|---|
{{script_1.finalPrice}} | 2950 |
{{script_1.taxAmount}} | 450 |
Template Message → Parameter mapping
A Template Message node maps variables to template parameters. Each template parameter (like {{1}}, {{2}}) is mapped to a variable.
| Template parameter | Mapped to |
|---|---|
Header {{1}} | {{customer_name}} |
Body {{1}} | {{order_total}} |
Body {{2}} | {{delivery_date}} |
Button URL {{1}} | {{tracking_url}} |
Trigger node → Trigger data
The trigger node's data is available using the trigger's node name as a prefix. Each trigger type provides different variables — see Trigger Blocks for the complete list per trigger type.
WhatsApp Flow node → Form response data
A WhatsApp Flow node sends an interactive form and waits for the customer to submit it. When using the Data Exchange flow action, the submitted form data is mapped to session variables through the Response Mapping section.
If you map the form fields like this:
| Form field | Session variable |
|---|---|
full_name | customer_name |
email | customer_email |
preferred_date | appointment_date |
You access the data as:
| Variable | Value |
|---|---|
{{customer_name}} | Rahul Sharma |
{{customer_email}} | rahul@example.com |
{{appointment_date}} | 2025-02-20 |
Interactive Buttons / List Menu → Customer selection
When a customer taps a button or selects a list item, the flow continues along the connected path for that specific button/row. The button or list item ID is also saved and can be referenced in subsequent nodes.
Lead Management (Get Details) → Contact data
The Get Details action fetches contact information and saves it with a prefix (default: lead_).
| Variable | Value |
|---|---|
{{lead_name}} | Contact's name |
{{lead_email}} | Contact's email |
{{lead_companyName}} | Contact's company |
Nodes that wait for customer input
Some nodes pause the flow and wait for the customer to respond before continuing. Understanding this is important because the flow doesn't move to the next node until the customer takes action — and only then do the response variables become available.
Which nodes wait?
| Node | What it waits for | What gets saved |
|---|---|---|
| Question | Customer types a reply | Answer saved to the variable you specified |
| Interactive Buttons | Customer taps a button | Flow continues along the button's connected path |
| List Menu | Customer selects a list item | Flow continues along the row's connected path |
| WhatsApp Flow | Customer fills and submits the form | Form data saved to session variables via response mapping |
How waiting works
┌────────────────────────┐
│ WhatsApp Flow node │
│ "Fill booking form" │
└────────────┬───────────┘
│
Sends form to
customer
│
⏳ FLOW PAUSES ⏳
Waiting for the
customer to submit
│
Customer submits
the form
│
Response variables
become available
│
▼
┌────────────────────────┐
│ Next node can now │
│ use the form data │
│ {{customer_name}} │
│ {{appointment_date}} │
└────────────────────────┘
- The node sends the message/form to the customer
- The flow pauses — no further nodes execute
- The customer takes action (types a reply, taps a button, or submits a form)
- The response is saved as variables in the session
- The flow continues to the next connected node
- The next node (and all subsequent nodes) can now use those variables
Using waiting node responses in the Expression Builder
After a waiting node saves its response, the variables become available in the Expression Builder for all subsequent nodes.
2. Configure the WhatsApp Flow with response mapping (e.g., full_name → customer_name)
3. Click on the Message node and open the Expression Builder on the message text field
4. Go to the Variables tab and show the mapped variables from the WhatsApp Flow appearing in the list
5. Capture the Expression Builder showing the available variables
Save to:
static/img/screenshots/chatbot-flows/variables/waiting-node-response-in-builder.pngTo use a waiting node's response in the next node:
- Add your waiting node (e.g., WhatsApp Flow) and configure it
- Add the next node (e.g., a Message or Condition node) and connect it
- In the next node, click the code icon (
</>) on any text field to open the Expression Builder - Go to the Variables tab — you'll see the variables from the waiting node listed under Scenario Variables
- Click on a variable to insert it (e.g.,
{{customer_name}})
Alternatively, go to the Response tab to browse the full response structure from any previous node and click the specific field you want.
Complete example: WhatsApp Flow → Confirmation message
Here's a complete example showing how a WhatsApp Flow form response flows into a confirmation message:
[WhatsApp Flow: "Booking Form"] → booking_form
Flow action: Data Exchange
Response mapping:
full_name → customer_name
email → customer_email
preferred_date → booking_date
service_type → service
⏳ Waits for customer to submit the form...
Customer fills in:
full_name: "Rahul Sharma"
email: "rahul@example.com"
preferred_date: "2025-02-20"
service_type: "Consultation"
Session variables now available:
{{customer_name}} = "Rahul Sharma"
{{customer_email}} = "rahul@example.com"
{{booking_date}} = "2025-02-20"
{{service}} = "Consultation"
↓
[Message: Confirmation]
"Thanks {{customer_name}}! Your {{service}} is booked
for {{booking_date}}. We'll send details to
{{customer_email}}."
Customer sees:
"Thanks Rahul Sharma! Your Consultation is booked
for 2025-02-20. We'll send details to
rahul@example.com."
The same pattern works for Question nodes — the flow waits for the customer to type a reply, saves it to a variable, and subsequent nodes can use that variable via the Expression Builder.
Complete data flow example
Here's a 4-node flow that shows how data moves from node to node:
[Trigger: keyword] → trigger_1
Customer sends "order"
System variable: {{customer_phone}} = "+919876543210"
↓
[Question: "What's your order number?"] → question_1
Customer replies: "ORD-78456"
Saved as: {{order_number}} = "ORD-78456"
↓
[HTTP Call: GET /api/orders/{{order_number}}] → fetch_order
Response saved as:
{{fetch_order.status}} = "shipped"
{{fetch_order.tracking_url}} = "https://track.example.com/78456"
{{fetch_order.estimated_delivery}} = "14 Feb 2025"
↓
[Message]
"Your order {{order_number}} is {{fetch_order.status}}.
Track it here: {{fetch_order.tracking_url}}
Expected delivery: {{fetch_order.estimated_delivery}}"
Expression Builder
The Expression Builder is a visual tool that helps you insert variables, build conditions, and write expressions without typing everything manually. It opens as a panel when you click the code icon (</>) on any text field that supports variables.
2. Click the code icon (</>) on the right side of the text field
3. Capture the full Expression Builder panel showing the expression area and tabs
Save to:
static/img/screenshots/chatbot-flows/variables/expression-builder-panel.pngHow to use it
- Click the code icon on any text field (message body, condition, URL, header, etc.)
- The Expression Builder opens as an overlay panel
- Use the tabs at the bottom to browse variables, functions, and operators
- Click any item to insert it at the cursor position in the expression editor
- Click Apply to insert the expression into the original text field
Expression editor
At the top of the panel, there's a text area where you build your expression. You can type directly or click items from the tabs below to insert them.
The editor shows real-time validation — errors appear in red and warnings in yellow below the editor.
Tabs
The Expression Builder has 5 tabs:
Variables tab
Shows all available variables grouped into sections:
| Section | What it contains |
|---|---|
| System Variables | Built-in variables like {{customer_name}}, {{customer_phone}}, {{initial_message}}, {{whatsapp_message_id}} |
| Scenario Variables | Variables created by your flow's nodes — Question answers, HTTP Call response mappings, etc. |
Click any variable chip to insert it at the cursor position in the expression editor.
Response tab
Shows the output of each node in your flow as a browsable tree. This is where you map data from a previous node's response to the current node.
2. Click the Response tab
3. Capture the tree view showing node names with expandable response data
Save to:
static/img/screenshots/chatbot-flows/variables/expression-builder-response-tab.pngHow it works:
- Each node in your flow is listed by its node name (e.g.,
http_call_1,question_1) - Click the + icon next to a node to add a sample response (paste a JSON example of what the node returns)
- The system parses the JSON and shows all fields as a tree
- Click any leaf field to insert it as
{{node_name.field}}in your expression
Adding a sample response:
- Click the + or edit icon next to any node
- Paste a sample JSON response (supports relaxed format — single quotes and unquoted keys work)
- Click Format JSON to validate and pretty-print
- Click Save
- The tree view now shows all available fields from that node
For HTTP Call nodes, paste an example of the API response. For Script nodes, paste an example of the return object. This makes it easy to pick the right variable path without memorizing it.
Functions tab
Provides built-in functions you can use in expressions:
| Category | Functions | Example |
|---|---|---|
| Math | sum, avg, min, max, round, floor, ceil, abs | {{sum({{price}}, {{tax}})}} |
| String | concat, toUpperCase, toLowerCase, trim, length | {{toUpperCase({{city}})}} |
| Conditional | if, ifEmpty, coalesce | {{if({{age}} >= 18, 'Adult', 'Minor')}} |
Each function shows its syntax, description, and an example. Toggle between compact view (chips only) and detailed view (with descriptions) using the list icon.
Operators tab
Provides operators for building conditions:
| Category | Operators |
|---|---|
| Arithmetic | + (add), - (subtract), * (multiply), / (divide), % (modulo) |
| Comparison | == (equals), != (not equals), >, <, >=, <= |
| Logical | && (AND), || (OR), ! (NOT) |
Example: {{{{order_total}} * 1.18}} calculates the total with 18% tax.
Text tab
Provides keywords for use in comparisons:
| Keyword | Usage |
|---|---|
| true / false | Boolean comparisons |
| null | Check for empty values |
Syntax guide
The Expression Builder includes a syntax guide at the top of the editor. Click the help icon for detailed examples covering:
- Simple variables:
{{customer_name}} - Nested variables:
{{fetch_order.result.tracking_url}} - Arithmetic:
{{{{price}} + 100}},{{{{price}} * 1.18}} - Comparisons:
{{{{age}} >= 18}},{{{{status}} === 'active'}} - Functions:
{{sum(100, 20)}},{{toUpperCase({{name}})}} - Logical operations:
{{{{age}} >= 18 && {{status}} === 'active'}}
Using variables in messages
You can insert variables in any message node. Just type {{variable_name}} where you want the value to appear, or use the Expression Builder to insert them.
Example message:
Hi
{{customer_name}}, your order{{order_number}}is{{fetch_order.status}}. Expected delivery:{{fetch_order.estimated_delivery}}.
What the customer sees:
Hi Rahul, your order ORD-78456 is Shipped. Expected delivery: 14 Feb 2025.
Variables work in message body text, headers, footers, button URLs, HTTP Call URLs, HTTP Call request bodies, script input variables, and template parameters — basically everywhere you type text.
Using variables in conditions
Variables are essential in Condition and Router nodes for making decisions.
Example condition: "Is the order total greater than 5000?"
- Variable:
{{order_total}} - Operator: greater than
- Value: 5000
Comparison operators
When building conditions in Router nodes, you can use these operators:
| Operator | What it checks | Example |
|---|---|---|
| equals | Exact match | {{status}} equals "active" |
| not equals | Does not match | {{status}} not equals "cancelled" |
| contains | Text includes value (case-insensitive) | {{message}} contains "help" |
| not contains | Text does not include value | {{message}} not contains "cancel" |
| starts with | Text begins with value | {{phone}} starts with "+91" |
| ends with | Text ends with value | {{email}} ends with "@gmail.com" |
| greater than | Number is larger | {{total}} greater than 1000 |
| less than | Number is smaller | {{age}} less than 18 |
| greater or equal | Number is equal or larger | {{score}} greater or equal 80 |
| less or equal | Number is equal or smaller | {{quantity}} less or equal 100 |
| is empty | Variable has no value | {{email}} is empty |
| is not empty | Variable has a value | {{phone}} is not empty |
Logical operators
In Router nodes, you can combine multiple rules using:
| Operator | Meaning | Example |
|---|---|---|
| AND | All rules must be true | City is "Mumbai" AND Budget > 50000 |
| OR | Any rule can be true | Status is "VIP" OR Purchases > 10 |
Variable naming rules
| Rule | Details |
|---|---|
| Allowed characters | Letters, numbers, underscores |
| Case sensitive | {{Name}} and {{name}} are different variables |
| No spaces | Use underscores: {{customer_name}} not {{customer name}} |
| Descriptive names | Use meaningful names like {{order_total}} instead of {{x}} |
Variable scope
Variables are scoped to a single flow execution (one conversation). They are not shared between different customers or different flow runs.
| What's shared | What's not shared |
|---|---|
| Variables within one flow run | Variables between different customers |
| Variables across all nodes in the flow | Variables between separate flow runs |
| Variables from triggers to end | Variables from one flow to another flow |
What happens when a variable is empty?
If you use a variable that hasn't been set yet, it appears as an empty string in messages. For critical variables, use a Condition node to check if the variable has a value before using it:
- Add a Condition node
- Check:
{{customer_email}}is not empty - TRUE path → Continue with the email
- FALSE path → Ask for the email
Common patterns
| Pattern | How it works |
|---|---|
| Collect then use | Question → saves {{name}} → Message uses {{name}} |
| Fetch then route | HTTP Call (fetch_order) → Condition checks {{fetch_order.status}} |
| Collect then send | Question → saves {{budget}} → HTTP Call sends {{budget}} to CRM |
| Fetch then display | Get Details → saves {{lead_email}} → Message shows {{lead_email}} |
| Calculate then show | Script (calc_price) → Message shows {{calc_price.final_total}} |
| Trigger then personalize | Ad Click trigger (trigger_1) → Message uses {{trigger_1.ad.headline}} |
| Chain node outputs | HTTP Call (get_customer) → Script uses {{get_customer.result.id}} → Message uses {{script_1.discount}} |