Variables & Data
Variables are the backbone of dynamic journeys. They store user answers, extracted data, API responses, and computed values -- then inject them into messages, prompts, conditions, and actions throughout the flow. This page covers variable syntax, sources, scoping, system variables, and how data catalogs integrate with your journeys.
Variable syntax
Reference any variable in message text, prompts, or configuration fields using double-brace syntax:
{{ variableName }}Variables are interpolated at runtime. If a variable has no value yet, the placeholder is replaced with an empty string. You can use variables in:
- Message and Greeting node text
- Question node prompts
- AI Response and AI Conversation context prompts
- Email subject and body fields
- API Call URL, headers, and body
- Condition node comparisons
- Document generation section instructions
Multiple variables can appear in the same string:
Hi {{ firstName }}, your order #{{ orderId }} shipped on {{ shipDate }}.Variable sources
Variables are populated by different node types throughout the journey. Here are all the ways a variable gets its value:
Question nodes
When a user answers a Question node, their response is stored in the variable specified by the node's variable property. For example, a Question node with variable set to "userEmail" stores the user's typed answer in {{ userEmail }}.
Data Collector nodes
Data Collector nodes use AI to extract structured information from the user's recent messages. Each extracted field is stored as a separate variable. For example, a Data Collector configured to extract name, company, and budget creates three variables from a single conversational exchange.
Set Variable nodes
Set Variable nodes assign a value to a variable directly. The value can come from four sources:
- Static -- A hardcoded string or number.
- From last message -- The text of the user's most recent message.
- AI extract -- The AI extracts a specific piece of information from the conversation.
- Expression -- A computed value based on other variables.
Use Set Variable to create derived data, set defaults, or transform values before passing them to downstream nodes.
API Call responses
When an API Call node receives a response, the response body is stored in the node's configured output variable. If the response is JSON, you can reference nested fields in subsequent nodes. This lets you pull in data from external systems -- order status, account details, inventory levels -- and use it in the conversation.
Trigger payloads (Action agents)
Action agents receive their initial data from trigger nodes (Schedule, Webhook, or Data Monitor). The trigger payload is available as variables in the flow. For example, a Webhook trigger receiving { "orderId": "12345", "status": "cancelled" } makes {{ orderId }} and {{ status }} available to all downstream nodes.
Loop iteration variables
Inside a Loop node body, the current item is available as a variable. The Loop node iterates over an array (typically from an API Call response or a data catalog query) and exposes each item to the nodes inside the loop body. After the loop completes, the iteration variable holds the last item.
Login node (authenticated user data)
When an agent is configured with login_required access mode and the user authenticates, their profile data becomes available as variables. Typical fields include the user's email, name, and any custom attributes passed through the authentication provider.
System variables
Every conversation has access to built-in system variables that are populated automatically. You do not need to create or assign these -- they are always available:
| Variable | Description |
|---|---|
visitor_id | Unique identifier for the current visitor session. |
current_time | The current date and time in ISO 8601 format. |
page_url | The URL of the page where the widget is embedded (widget deployments only). |
referrer | The referring URL that brought the visitor to the current page. |
utm_source | UTM source parameter from the page URL, if present. |
utm_medium | UTM medium parameter from the page URL, if present. |
utm_campaign | UTM campaign parameter from the page URL, if present. |
utm_term | UTM term parameter from the page URL, if present. |
utm_content | UTM content parameter from the page URL, if present. |
System variables are useful for personalizing messages based on context ("I see you came from our pricing page"), segmenting conversations by traffic source, or passing attribution data to API calls and webhooks.
Data catalogs
Data catalogs are structured datasets -- product catalogs, rate cards, audience segments, campaign data, or custom tables -- that your journeys can query and display. Catalogs are managed at the brand level under Knowledge > Data Tables and are available to all agents in the brand.
Catalog types
| Type | Description |
|---|---|
PRODUCT_CATALOG | Product listings with fields like name, price, image, description, and category. |
RATE_CARD | Pricing tiers, rate structures, or fee schedules. |
AUDIENCE_SEGMENTS | Predefined audience groups with targeting criteria. |
CAMPAIGN_DATA | Campaign metadata, performance metrics, or scheduling data. |
CUSTOM | Any structured data that does not fit the above categories. |
Catalog-connected nodes
Four node types interact with data catalogs:
Product Card -- Displays a rich card (image, title, price, description, CTA button) for a specific catalog item. Configure the node with a catalogId to connect it to a catalog. The card renders inline in the conversation.
Loop -- Iterates over catalog rows matching a filter. Use this to show multiple products, walk through rate card tiers, or process a list of audience segments. Each iteration exposes the current row as a variable accessible to nodes inside the loop body.
Write to Catalog -- Creates, updates, or upserts a row in a catalog. Use this to save user-provided data back to a catalog -- for example, capturing a lead's preferences into a custom table, or updating an order status after an API call.
Filter Items -- Queries a catalog with field-based filters and stores the matching rows in a variable. Downstream nodes can then loop over the results or display them.
Example: product recommendation flow
- A Question node asks "What's your budget range?"
- A Filter Items node queries the product catalog where
price <= {{ budget }}and stores the results inmatchedProducts. - A Loop node iterates over
{{ matchedProducts }}. - Inside the loop, a Product Card node displays each matching product.
- After the loop, a Message node says "Those are the best options in your range. Want to narrow it down?"
Variable scoping
By default, all variables are scoped to the conversation. Any node in the journey can read or write any variable, and values persist for the entire conversation session.
Sub-flow scoping
When you use a Sub-Flow node to call another journey, you can control variable visibility:
- Explicit mappings -- Define
inputMappingto pass specific variables into the sub-flow andoutputMappingto capture specific variables back. The sub-flow only sees the variables you explicitly pass in, and the parent flow only receives the variables you explicitly map out. This is the default and recommended approach for clean separation. - Shared scope -- Enable the
shareVariablesoption on the Sub-Flow node. The sub-flow reads and writes variables from the parent scope directly, with no mapping needed. This is convenient for tightly coupled flows but can make debugging harder as the sub-flow can modify any parent variable.
Best practices
- Give variables descriptive names (
customerEmail, noteorvar1). - Use Set Variable nodes to create clean, named variables from complex API responses before referencing them in messages.
- When building reusable sub-flows, prefer explicit input/output mappings over shared scope. This makes the sub-flow's data contract clear and prevents unexpected side effects.
- Use the
skipIfproperty on Question nodes to avoid re-asking for data that is already available in a variable.