Skip to main content
Every flow execution maintains data in four organized namespaces. This data flows between nodes, gets updated by user interactions, and drives flow logic.

Data structure

vars namespace - User-defined variables
  • Read/write access
  • Store custom data, user responses, API results
  • Persists throughout flow execution
system namespace - System-managed data
  • Read-only access
  • Flow metadata, timing, execution details
  • Automatically maintained by the platform
context namespace - Contextual information
  • Mostly read-only (set at flow start)
  • Channel info, user details, trigger context
  • Provides execution environment details
metadata namespace - Request metadata
  • Read-only access
  • API request details, timestamps, caller info
  • Available for API-triggered flows

Initial data

WhatsApp trigger flow starts with:
# System variables
{{system.trigger_type}}                # "inbound_message"
{{system.flow_id}}                     # Flow UUID
{{system.started_at}}                  # ISO timestamp

# WhatsApp config data
{{system.whatsapp_config.id}}          # WhatsApp config ID
{{system.whatsapp_config.phone_number_id}}  # Meta phone number ID
{{system.whatsapp_config.display_phone_number}}  # Host phone number (formatted)
{{system.whatsapp_config.display_phone_number_normalized}}  # Host phone (normalized)
{{system.whatsapp_config.business_account_id}}  # WhatsApp Business Account ID
{{system.whatsapp_config.name}}        # Config name
{{system.whatsapp_config.kind}}        # "production" or "sandbox"

# Context variables
{{context.phone_number}}               # User's phone number "+1234567890"
{{context.channel}}                    # "whatsapp"
{{context.conversation_id}}            # WhatsApp conversation ID

# Contact data
{{context.contact.id}}                 # Contact UUID (when known)
{{context.contact.wa_id}}              # Normalized WhatsApp ID
{{context.contact.name}}               # Contact name (or phone number fallback)
{{context.contact.profile_name}}       # WhatsApp profile name (may be null)
{{context.contact.display_name}}       # Display name (may be null)

# Flow variables
{{last_user_input}}                    # Initial message content
API trigger flow starts with:
# System variables
{{system.trigger_type}}                     # "api_call"
{{system.tracking_id}}                      # Unique execution ID
{{system.api_key_id}}                       # API key used
{{system.trigger_whatsapp_config_id}}       # WhatsApp config ID (if provided in request)

# Context variables
{{context.phone_number}}                    # From request (normalized)
{{context.channel}}                         # "api"

# Custom variables (from API request)
{{your_variable}}                           # From variables object
{{another_variable}}                        # From variables object

# Metadata
{{metadata.request_ip}}                     # Caller IP
{{metadata.request_timestamp}}              # Request time
When whatsapp_config_id is provided in the API request:
  • Automatically stored in {{system.trigger_whatsapp_config_id}}
  • Phone number normalized and stored in {{context.phone_number}}
  • Guarantees all messages use the same WhatsApp configuration

Accessing variables

In messages and templates:
# Direct access (looks in vars namespace)
SendTextNode(message="Hello {{customer_name}}")

# Explicit namespace access
SendTextNode(message="Your number is {{context.phone_number}}")
SendTextNode(message="Flow started at {{system.started_at}}")
In AI fields:
# Use same pattern in AI prompts
SendTextNode(
    message=AIField(prompt=
        "Generate greeting for {{customer_name}} who ordered {{product_name}}"
    )
)
In agent nodes:
# Agents can read all variables through context
# Use get_variable and save_variable tools

Modifying variables

Wait for response node:
# Automatically sets last_user_input when user responds
WaitForResponseNode(id="get_name")
# After user responds: {{last_user_input}} contains their message
Function node:
# Save function response to variable
FunctionNode(
    id="calculate_score",
    function_id="score_calculator",
    save_response_to="user_score"  # Sets {{user_score}}
)

# Function can also return vars object to set multiple variables
# Function returns: {"vars": {"score": 85, "tier": "gold"}}
# Sets: {{score}} and {{tier}}
Webhook node:
# Save API response to variable
WebhookNode(
    id="get_user_data",
    url="https://api.example.com/users/{{user_id}}",
    save_response_to="user_profile"  # Sets {{user_profile}}
)
Agent node:
# Agent can read and write variables using tools
AgentNode(
    id="data_collector",
    system_prompt="Collect user information and save it using save_variable tool"
)
# Agent uses: save_variable(key="user_age", value="25")
# Sets: {{user_age}}

Data flow between nodes

Send nodes (SendTextNode, SendTemplateNode, SendInteractiveNode)
  • Read: All variables for message content and parameters
  • Write: Nothing
Wait for response node
  • Read: Nothing (just waits)
  • Write: Sets {{last_user_input}} when user responds
Decide node
  • Read: All variables to evaluate conditions
  • Write: Nothing (just routes flow)
Function node
  • Read: Sends entire execution context to function
  • Write: Can set variables via save_response_to or function return
Agent node
  • Read: Full access to all variables via get_variable tool
  • Write: Can set any variable via save_variable tool
Handoff node
  • Read: Nothing
  • Write: Nothing (just stops execution)

Examples

Using contact data:
# Personalize messages with contact name
SendTextNode(
    id="greeting",
    message="Hi {{context.contact.name}}! How can I help you today?"
)

# Access WhatsApp profile information
SendTextNode(
    id="profile_check",
    message="Your WhatsApp profile name: {{context.contact.profile_name}}"
)

# Use contact ID for lookups
FunctionNode(
    id="get_user_history",
    function_id="lookup_contact",
    # Function receives context.contact.id for database queries
)
Accessing WhatsApp config data:
# Use host phone number in messages
SendTextNode(
    id="welcome",
    message="Welcome! You're chatting with {{system.whatsapp_config.display_phone_number}}"
)

# Reference business name
SendTextNode(
    id="business_info",
    message="This is {{system.whatsapp_config.name}} support. How can I help?"
)

# Check if production or sandbox
DecideNode(
    id="check_environment",
    conditions=[
        Condition(
            label="production", 
            description="{{system.whatsapp_config.kind}} equals production"
        ),
        Condition(
            label="sandbox",
            description="{{system.whatsapp_config.kind}} equals sandbox"
        )
    ]
)
Collecting user information:
# Ask for name
SendTextNode(id="ask_name", message="What's your name?")
WaitForResponseNode(id="get_name")
# Now {{last_user_input}} contains the name

# Ask for age  
SendTextNode(id="ask_age", message="Thanks {{last_user_input}}! What's your age?")
WaitForResponseNode(id="get_age") 
# Agent could save this as {{user_age}}
Processing and using data:
# Function processes user input
FunctionNode(
    id="validate_age",
    function_id="age_validator", 
    save_response_to="validation_result"
)

# Conditional response based on result
DecideNode(
    id="check_valid",
    conditions=[
        Condition(label="valid", description="Age is valid"),
        Condition(label="invalid", description="Age is invalid")
    ]
)

# Different responses
SendTextNode(
    id="valid_response",
    message="Great! You're {{last_user_input}} years old."
)

SendTextNode(
    id="invalid_response", 
    message="That doesn't look like a valid age. Please try again."
)
Using API data:
# API trigger provides order_id
# {{order_id}} available from start

# Get order details
FunctionNode(
    id="get_order",
    function_id="order_lookup",
    save_response_to="order_details"
)

# Send confirmation with order data
SendTextNode(
    id="confirmation",
    message="Order {{order_id}} for ${{order_details.total}} has been confirmed!"
)
API-triggered execution context:
# Example execution context when triggered via API with whatsapp_config_id
{
  "execution_context": {
    "system": {
      "trigger_type": "api_call",
      "tracking_id": "track-abc123",
      "trigger_whatsapp_config_id": "config-xyz789",
      "flow_id": "flow-456def"
    },
    "context": {
      "phone_number": "1234567890",  # Normalized (no + sign)
      "channel": "api"
    }
  },
  "variables": {
    # Custom variables from API request
    "customer_name": "Alice Smith",
    "order_total": 149.99
  }
}

Variable naming

  • Use lowercase with underscores: user_name, order_total
  • Be descriptive: last_user_input not input
  • Avoid system reserved names: flow_id, started_at
I