Skip to content

Variables and Tags ​

TL;DR:

  • Variables store dynamic user data like names, scores, or preferences for personalization and logic.
  • Tags are simple labels used to group and segment users (e.g., "leads", "customers").
  • Use the Actions and Formula nodes to manage data, and Condition nodes to branch your flow based on it.

What it does ​

Variables and tags let your bot remember information about each user and make decisions based on that data. Without them, every conversation starts from scratch. With them, your bot can personalize messages, segment users, and build complex logic flows.

When to use it ​

  • ✅ Personalizing messages — Insert a user's name, email, or saved answer into any message.
  • ✅ Branching logic — Route users differently based on tags, scores, or data they provided earlier.
  • ✅ Segmenting users — Tag users as "lead", "customer", or "VIP" and target them with different flows.
  • ✅ Passing data between nodes — Store a quiz score in one node and check it in the next.

When NOT to use it ​

  • ❌ Hardcoding static text — If the text never changes, just type it directly in the Message node.
  • ❌ Storing sensitive data — Do not store passwords or API keys in variables. Use workspace globals for shared secrets (headers only in Sync HTTP).

Variable syntax in messages ​

When you want to display a variable value inside a Message node, you use a specific syntax depending on the variable type:

SyntaxTypeWhat it resolves toExampleMissing behavior
{%key%}System / Field / UTMBuilt-in user field, custom field, or UTM parameter{%first_name%}, {%utm_source%}Blank (removed from text)
{@key@}GlobalWorkspace-wide shared variable{@support_phone@}Blank (removed from text)
{{var.key}} or {{var.key+}}Scenario variableFormula, Question, or Sync HTTP-set var.* value (session or persist tier){{var.score}}, {{var.score+}}, {{var.level}}Blank (removed from text)

TIP

All three syntaxes remove the placeholder when the value is missing. To show the literal placeholder text for debugging or documentation purposes, add ! after the opening brace: {{!var.score}} renders as the literal string {{var.score}}.

What goes where ​

Where are you?Use this syntax
Message node text (cards, questions, reminders){%first_name%}, {%calendar.date%}, {@support_phone@}, {{var.score}}
Formula node expressionsvar.score, {%first_name%}, {@my_global@}, {*local1*} — written directly, no double braces
Condition node rulesSelected from dropdowns or typed — no manual syntax needed
Actions node targetsSelected from dropdowns — no manual syntax needed
Sync HTTP body, headers, URLs{%first_name%}, {%utm_source%}, {@api_token@} — no {{var.*}}

Variable types ​

System fields ​

Built-in user profile fields. Read-only — you cannot assign to them in Actions or Formula.

KeyNameData typeAuto-populated?
first_nameFirst nametextYes — from Telegram
full_nameFull nametextYes — from Telegram
usernameUsernametextYes — from Telegram
refReferral codetextYes — from start parameter
language_codeLanguage codetextYes — from Telegram
current_dateCurrent datetextYes — auto (UTC)
current_timeCurrent timetextYes — auto (UTC)
telegram_user_idTelegram user IDtextYes — from Telegram
nameNametextNo — ask via Question card or set via Actions
emailEmailtextNo — ask via Question card or set via Actions
phonePhonetextNo — ask via Question card or set via Actions
ai_last_answerLast AI answertextSet by AI Agent node

Use in messages: {%first_name%}, {%email%}, {%ref%}

Context fields (set by nodes) ​

These are set automatically by specific nodes during the conversation. They are read-only after being set.

KeyNameData typeSet by
ai_last_answerLast AI answertextAI Agent node
calendar.dateBooked datetextCalendar Slot Picker
calendar.timeBooked timetextCalendar Slot Picker
calendar.has_bookingHas active bookingtextCalendar Slot Picker
calendar.datetime_utcBooking start (UTC)textCalendar Slot Picker
calendar.end_datetime_utcBooking end (UTC)textCalendar Slot Picker
calendar.event_idCalendar event IDtextCalendar Slot Picker
calendar.event_linkCalendar event linktextCalendar Slot Picker
location.latitudeShared latitudenumberLocation button
location.longitudeShared longitudenumberLocation button

Use in messages: {%calendar.date%}, {%ai_last_answer%}, {%location.latitude%}

UTM parameters ​

Captured from entry links. Writable — you can update UTM values in Actions and Formula nodes.

KeyName
utm_sourceUTM Source
utm_mediumUTM Medium
utm_campaignUTM Campaign
utm_contentUTM Content
utm_termUTM Term

Use in messages: {%utm_source%}, {%utm_campaign%}

Custom fields (F_*) ​

Organization-defined CRM fields. Each bot can have different custom fields. Writable from Actions and Formula.

Use in messages: {%F_customer_id%} (field key format)

Scenario variables (var.* and var.*+) ​

Per-user variables set by Formula, Question, Condition, AI Agent, or Sync HTTP nodes. The most common way to store custom data during a conversation. They come in two tiers:

SyntaxStorage tierSurvives /start?Synced to CRM?Lifetime
var.scoreSession — lives for the current conversation❌ No❌ NoUntil the next /start
var.score+Persist — stored in a dedicated Redis key per user✅ Yes❌ NoConfigurable per bot (default: 90 days, sliding window)

Session vars (var.score) are reset each time the user starts the bot with /start. Use them for intermediate calculations, quiz answers, or temporary counters within a single flow.

Persist vars (var.score+) survive restarts and /start commands. Use them for long-lived user state like loyalty points, completed levels, or preferences that should be remembered across multiple sessions.

The lifetime of persist vars is configurable per bot in Bot Settings → Customization → Persist Variable Lifetime (default: 90 days). The timer is a sliding window — it resets on every interaction, so active users never lose their data. Users who go silent for longer than the configured period have their persist vars cleared automatically. Set it to Never expire for data that must survive indefinitely regardless of inactivity.

Use in messages: {{var.my_score}} or {{var.my_score+}} — both render the same value (the + suffix is stripped during render and the system reads from the persist store first).

TIP

{{var.key}} and {{var.key+}} are identical in a message — both show the current value regardless of which store holds it. The + suffix only matters when writing (Formula, Question card, Sync HTTP mapping). When reading, the engine always checks var.key+ (persist) first, then falls back to var.key (session).

Global variables (G_*) ​

Workspace-wide shared values. Not user-specific. Set in Workspace Settings → Variables. Can be read from any bot in the workspace.

Use in messages: {@support_phone@}

Tags ​

Tags are simple binary on/off labels attached to a user profile. A user either has a tag or they don't. The platform supports two categories of tags:

  1. Built-in Tags (Presets): Pre-configured lifecycle, support, and billing tags (e.g., T_lead, T_customer, T_needs_human_support) available in every workspace by default.
  2. Custom Tags: User-defined tags created in Workspace Settings → Catalog → Tags with custom labels, colors, and system-generated keys (e.g., T_TKUDfCwp).

Common uses:

  • T_lead (Built-in) — Mark users who submitted their contact info.
  • T_customer (Built-in) — Mark users who completed a purchase.
  • T_vip (Built-in) — Mark premium users for special treatment.
  • T_5tWRHwEe (Custom, labeled "Onboarding Complete") — Track who finished custom bot onboarding.

Tags are managed in the Actions node (Add Tag / Remove Tag) and checked in the Condition node (Has tag / Does not have tag). Refer to Tags Management for the full list of built-in presets and how to create custom tags.

How to use variables in each node ​

NodeRead var.*Write var.*Write var.*+ (persist)
Message (text cards)✅ {{var.score}} in message text❌❌
Message (Question card)✅ for overwrite checks✅ toggle "var.*" in save target✅ add + to the key, e.g. score+
Formula✅ var.score in expressions✅ var.score = …✅ var.score+ = …
Condition✅ via "var.*" rule kind❌❌
Actions✅ limited (set/increment/clear)✅❌
Sync HTTP (response mapping)❌✅ map to var.key✅ map to var.key+
AI Agent (input)✅ read from var.* or var.*+❌❌
AI Agent (system prompt)✅ all var.* values injected automatically❌❌

In the UI ​

Data management happens in two main areas:

  • Scenario Editor: Where you define how data is collected and used.
    • Actions Node: Add "Add Tag" or "Set Variable" steps here.
    • Formula Node: Perform complex calculations and logic assignments.
    • Condition Node: Create branches based on tags or variable values.
  • CRM (User Detail): Where you see the actual data for a specific user.
    • Location: Bot Dashboard → CRM → [Click User] → Variables/Tags tab.

Examples ​

Example 1 — Personalized greeting ​

Goal: Use the user's name (if known) to provide a warmer welcome.
Setup:

  1. Use a Question Card in a Message Node to ask for the user's name and save it to first_name.
  2. In the next Message Node, write: "Thanks, {%first_name%}! How can I help you today?"
    Result: The bot displays the user's actual name. If the name is not set yet, the placeholder is simply removed and the message reads "Thanks, !".

Example 2 — VIP segmentation ​

Goal: Offer a special discount only to users who have completed a purchase.
Setup:

  1. When a purchase is confirmed, use an Actions Node to add the tag customer.
  2. Later, use a Condition Node to check if the user has the customer tag.
  3. If True, send a message with a 20% discount code. If False, send a standard promotion.
    Result: Your bot provides targeted offers based on the user's previous behavior.

Example 3 — Display a calculated score ​

Goal: Show the user their quiz score after calculating it.
Setup:

  1. Use a Formula Node to calculate var.final_score = {%score%} * 100 / {%max_score%}.
  2. In the next Message Node, write: "Your score: {{var.final_score}} points."
    Result: The calculated value is displayed. If the formula has not run yet, the placeholder is removed and the message reads "Your score: points." — no raw macro text is shown. To display the literal placeholder for debugging, write {{!var.final_score}}.

Common pitfalls ​

  • The message shows nothing where a variable should be → The variable hasn't been set yet — it renders as blank. Fix: Make sure a Formula, Question, or Sync HTTP node sets var.score earlier in the flow. To verify what is stored, check the CRM for that user.

  • Variable not showing expected value → The variable might not have been saved yet, or the macro name is misspelled. Fix: Check the spelling (system fields use {%first_name%}, scenario variables use {{var.name}}). Check the CRM for that user to see what is actually stored.

  • Condition based on tag not working → The tag might be spelled differently in the Actions Node vs. the Condition Node (e.g., VIP vs vip). Tags are case-sensitive. Fix: Use consistent casing — lowercase is recommended.

  • Tag added but not triggering logic → The Condition Node might be checking "All tags" when you intended "Any tag", or the user hasn't reached the condition node yet. Fix: Verify the match mode (Match any vs all) and check that the link from the Actions node to the Condition node is drawn correctly.

  • {%field%} shows nothing in a message → System fields like first_name are populated automatically from Telegram, but email and phone are empty by default. Fix: Ask for these values via a Question card with email/phone validation before displaying them.

  • Persist variable is suddenly empty for a returning user → The bot's Persist Variable Lifetime may have expired due to inactivity. The timer resets on every interaction, but if the user went silent for longer than the configured period, the data is cleared automatically. Fix: Open Bot Settings → Customization → Persist Variable Lifetime and increase the duration, or set it to Never expire for data that must survive indefinitely. Always design flows that handle a missing persist var gracefully (use a Condition node to check if the variable is set before using it).

FAQ ​

  • Q: What is the difference between {%first_name%} and {{var.first_name}}?
    A: {%first_name%} resolves a system field (profile data from Telegram or CRM). {{var.first_name}} resolves a scenario variable set by Formula, Question, or Sync HTTP. Both remove the placeholder when the value is missing — the user sees blank, not raw macro text. The key difference is where the value comes from, not how missing values behave. To intentionally display the literal syntax in a message, prefix with !: {{!var.score}}.

  • Q: Do variables persist between sessions?
    A: It depends on the variable type. CRM fields (F_*), system fields, globals, and UTM parameters are tied to the user's profile and persist indefinitely. Session vars (var.key) are reset when the user sends /start. Persist vars (var.key+) survive /start and are kept until explicitly cleared, overwritten, or until the bot's Persist Variable Lifetime elapses. The default lifetime is 90 days of inactivity (sliding window — resets on every interaction). You can adjust this per bot in Bot Settings → Customization, or set it to Never expire.

  • Q: Can I delete a tag?
    A: You can remove a tag from a specific user using an Actions Node. To delete a tag from the entire system, manage them in Workspace Settings.

  • Q: Can one user have multiple tags?
    A: Yes. A user can have an unlimited number of tags. The platform ensures tags are unique, so adding the same tag twice won't create duplicates.

  • Q: What happens when {%first_name%} is empty?
    A: The macro is removed from the text. If your message is "Hello, {%first_name%}!" and the name is not set, the user sees "Hello, !" — not "Hello, {%first_name%}!". If you want to check first, use a Condition node to test whether first_name is set, and branch to a message that asks for the name first.

  • Q: Can I use {%calendar.date%} outside a Message node?
    A: Yes, in Condition rules, Formula expressions, and Sync HTTP request bodies. The value is available as long as the user has an active booking.

  • Message Node — Display variables in text, question, and reminder cards.
  • Condition Node — Branch the flow based on variable values and tags.
  • Actions Node — Set, increment, and clear variables; add and remove tags.
  • Formula Node — Calculate, transform, and assign values using expressions.
  • AI Agent Node — Produces {%ai_last_answer%} for display in Message nodes.
  • Calendar Slot Picker — Produces {%calendar.*%} variables after booking.
  • Bot Customization — Configure the Persist Variable Lifetime for your bot.

TeleGo.io Docs