Building Agents
Journey Builder
Logic & Flow Nodes

Logic & Flow Nodes

Logic nodes control how the conversation flows -- branching based on conditions, looping over data, composing sub-flows, managing variables, and introducing delays. They do not produce visible messages on their own but determine which path the conversation takes.

Condition

Type: condition

Branches the flow into two paths based on a variable comparison. The node evaluates the condition and routes to either the true or false output.

Properties

PropertyTypeDescription
variablestringThe variable name to evaluate
operatorequals | contains | greater | less | isEmptyComparison operator
valuestringThe value to compare against (not used with isEmpty)
trueNodeIdstringNode to route to when the condition is true
falseNodeIdstringNode to route to when the condition is false

Operators

  • equals -- Exact string or numeric match.
  • contains -- Checks if the variable value includes the comparison string (case-insensitive).
  • greater / less -- Numeric comparison. Values are parsed as numbers.
  • isEmpty -- True when the variable is undefined, null, or an empty string. Ignores the value property.

Use cases

  • Check if the user provided an email before sending a confirmation
  • Route VIP customers (score > 100) to a priority path
  • Skip a step when a variable is already populated

Set Variable

Type: set_variable

Stores a value in a flow variable. The variable becomes available to all downstream nodes.

Properties

PropertyTypeDescription
variablestringThe variable name to set
sourcestatic | from_last_message | ai_extract | expressionWhere the value comes from
valuestringThe static value (used when source is static)
expressionstringA JavaScript expression (used when source is expression)

Sources

  • static -- Sets the variable to a fixed value. Useful for flags, counters, or default values.
  • from_last_message -- Captures the user's most recent message text as the variable value.
  • ai_extract -- Uses the LLM to extract a specific piece of information from the conversation history (e.g., "extract the user's budget" or "extract the product name they mentioned").
  • expression -- Evaluates a JavaScript expression with access to all current variables. For example, variables.price * variables.quantity or variables.name.toUpperCase().

Use cases

  • Store a computed total: source expression, expression variables.price * variables.quantity
  • Capture raw user input for later processing: source from_last_message
  • Set a flag after a step completes: source static, value true

Loop

Type: loop

Iterates over an array variable or catalog records, executing the loop body once per item. The current item is available as a variable inside the loop body.

Properties

PropertyTypeDescription
loopSourcevariable | catalogWhether to iterate over a variable array or catalog records
loopVariableNamestringVariable name for the current item on each iteration
loopCatalogIdstringThe Data Catalog to iterate over (when source is catalog)
loopFilterFieldstringCatalog field to filter on
loopFilterOperatorequals | not_equals | greater_than | less_than | containsFilter comparison operator
loopFilterValuestringValue to filter against
loopLimitnumberMaximum records to fetch from catalog
loopMaxIterationsnumberHard cap on iterations (safety limit)
loopContinueOnErrorbooleanWhen true, errors in one iteration do not stop the loop

Outputs

The Loop node has two output handles:

  • Each Item -- Connects to the first node in the loop body. Executes once per item.
  • Complete -- Connects to the node that runs after all iterations finish.

Catalog filters

When loopSource is catalog, you can filter records before iterating. The filter applies server-side, so only matching records are fetched. Combine with loopLimit to cap the result set.

Use cases

  • Send a personalized message for each product in a recommendation list
  • Process each row in a data table and call an API per record
  • Iterate over survey responses and classify each one

Loop End

Type: loop_end

Marks the end of a loop body. Every Loop node needs a corresponding Loop End node to define where the loop body ends and iteration continues.

Properties

PropertyTypeDescription
loopNodeIdstringThe Loop node this end marker belongs to
breakConditionVariablestringVariable to evaluate for an early exit
breakConditionOperatorequals | not_empty | is_trueHow to evaluate the break condition
breakConditionValuestringValue to compare against (used with equals)

Break conditions

By default, the loop runs through every item. To exit early, configure a break condition:

  • equals -- Break when the variable matches the specified value.
  • not_empty -- Break when the variable has any non-empty value.
  • is_true -- Break when the variable is truthy.

When the break condition is met, the loop stops and execution continues from the Loop node's Complete output.

Use cases

  • Stop iterating once a matching product is found
  • Exit a retry loop when an API call succeeds
  • Limit processing to the first item that meets a threshold

Sub-Flow

Type: sub_flow

Routes execution to another flow on the same agent. Sub-flows let you break complex journeys into modular, reusable pieces.

Properties

PropertyTypeDescription
subFlowIdstringID of the target flow
subFlowNamestringDisplay name of the target flow (for readability in the editor)
shareVariablesbooleanWhen true, the sub-flow has full read/write access to the parent's variables
inputMappingobjectMaps parent variables to sub-flow input variables
outputMappingobjectMaps sub-flow output variables back to parent variables

Variable passing

There are two approaches:

  1. Explicit mappings -- Use inputMapping and outputMapping to pass specific variables in and out. This is the safer option because it makes data flow explicit and prevents unintended side effects.
  2. Share variables -- Enable shareVariables to give the sub-flow direct access to the parent's full variable scope. Changes made by the sub-flow are visible in the parent immediately. Use this when the sub-flow needs broad context and you want to avoid mapping many variables individually.

When both are configured, explicit mappings take precedence for the mapped variables, and shareVariables provides access to everything else.

Use cases

  • A main greeting flow that routes to "Product Recommendations", "Support", or "FAQ" sub-flows based on user intent
  • A reusable "Collect Shipping Address" sub-flow shared across multiple checkout journeys
  • A modular lead qualification flow that can be dropped into any sales agent

Converge

Type: converge

Merges multiple branches back into a single path. Place a Converge node after a Condition or AI Categorizer to rejoin divergent paths before continuing the flow.

Properties

PropertyTypeDescription
awaitAllbooleanWhen true, waits for all incoming branches to complete before continuing

Behavior

Without a Converge node, each branch continues independently until it reaches a terminal node. A Converge node collects branches and funnels them into a single downstream path.

When awaitAll is false (default), execution continues as soon as the first branch reaches the Converge node. When awaitAll is true, the node waits until every connected branch has completed before proceeding.

Use cases

  • Rejoin true/false branches after a Condition so both paths lead to the same follow-up message
  • Merge categorized paths back together before a shared closing sequence
  • Synchronize parallel branches that must all complete before the next step

Delay

Type: delay

Pauses the conversation for a specified duration. Useful for simulating natural typing cadence or introducing timed gaps between messages.

Properties

PropertyTypeDescription
delayDurationnumberPause duration in milliseconds
delayMessagestringOptional message shown to the user during the pause (e.g., "One moment...")

Behavior

During the delay, the conversation appears paused. If delayMessage is set, the user sees that message (often with a typing indicator) until the delay completes. After the delay, execution continues to the next connected node.

Use cases

  • Add a 1-2 second pause between messages for a more natural conversational rhythm
  • Show "Looking that up for you..." before an API call that may take time
  • Introduce a deliberate wait before revealing a result for dramatic effect

Wait

Type: wait

Pauses execution until a condition is met. Unlike Delay (which pauses for a fixed time), Wait can pause indefinitely until an external event occurs, a specific time arrives, or a duration elapses.

Properties

PropertyTypeDescription
waitModeduration | until_time | webhookWhat the node waits for
waitDurationSecondsnumberSeconds to wait (used with duration mode)
waitUntilTimestringISO 8601 timestamp to wait until (used with until_time mode)
waitMaxSecondsnumberMaximum wait time before timeout (applies to all modes)
waitTimeoutActionstop | continue | error_branch | fallback_messageWhat happens when the wait times out
waitTimeoutMessagestringMessage shown on timeout (used with fallback_message action)

Wait modes

  • duration -- Pauses for a fixed number of seconds. Similar to Delay but measured in seconds and with timeout handling.
  • until_time -- Pauses until a specific date and time. Useful for scheduled follow-ups (e.g., "resume this conversation tomorrow at 9 AM").
  • webhook -- Pauses until an external system sends a webhook to resume the flow. The flow instance ID is included in the webhook URL so the correct conversation is resumed.

Timeout handling

If waitMaxSeconds elapses before the wait condition is met, the waitTimeoutAction determines what happens:

  • stop -- End the flow.
  • continue -- Proceed to the next node as if the wait completed normally.
  • error_branch -- Route to the error handling path.
  • fallback_message -- Show waitTimeoutMessage to the user and continue.

Use cases

  • Wait for an external approval before proceeding with an order
  • Schedule a follow-up message for a specific time ("We'll check back with you tomorrow at 10 AM")
  • Pause until a payment webhook confirms a transaction

Login

Type: login

Authenticates the visitor within the conversation. Presents a login interface with configurable authentication methods and maps the authenticated user's data to flow variables.

Properties

PropertyTypeDescription
loginTitlestringHeading text for the login prompt (e.g., "Sign in to continue")
loginSubtitlestringSecondary text below the title
loginMethodsobjectWhich authentication methods to enable: { emailOtp, phoneOtp, googleOAuth }
skipIfAuthenticatedbooleanWhen true, skips the login step if the user is already authenticated
loginRequiredbooleanWhen true, the user cannot proceed without authenticating
loginVariableMappingobjectMaps authenticated user fields to flow variables (e.g., email, name, phone, customerId)

Authentication methods

  • Email OTP -- Sends a one-time password to the user's email address.
  • Phone OTP -- Sends a one-time password via SMS to the user's phone number.
  • Google OAuth -- Redirects to Google for authentication.

You can enable any combination. At least one method must be enabled.

Variable mapping

After successful authentication, the node populates flow variables based on loginVariableMapping. For example:

  • Map email to user_email
  • Map name to user_name
  • Map phone to user_phone
  • Map customerId to customer_id

These variables are then available to all downstream nodes for personalization, lookups, or API calls.

Use cases

  • Gate a support flow behind authentication so the agent can pull up the user's order history
  • Identify returning customers to personalize product recommendations
  • Collect verified contact information before processing a high-value request

Filter Items

Type: filter_items

Filters, sorts, and limits an array of items stored in a flow variable. The filtered results are written to a new variable.

Properties

PropertyTypeDescription
inputVariablestringThe variable containing the array to filter
outputVariablestringThe variable to store the filtered results
conditionsarrayFilter conditions, each with field, operator, and value
conditionLogicAND | ORHow multiple conditions are combined
sortBystringField name to sort results by
sortOrderasc | descSort direction
limitnumberMaximum number of items to return
countVariablestringOptional variable to store the count of filtered results

Condition logic

When multiple conditions are specified:

  • AND -- All conditions must be true for an item to be included.
  • OR -- At least one condition must be true for an item to be included.

Each condition specifies a field (property name on each item), an operator (equals, not_equals, greater_than, less_than, contains, not_contains, is_empty, is_not_empty), and a value to compare against.

Use cases

  • Filter a product list to only items under $50: condition price less_than 50
  • Sort leads by score descending and take the top 10: sortBy score, sortOrder desc, limit 10
  • Narrow search results to a specific category and count the matches
  • Chain with a Loop node to iterate over filtered results