Skip to main content
Two separate things share one page because they are easy to confuse:
  • Variables are what this conversation knows.
  • Identity is who the conversation belongs to.

Variables

Where They Come From

A variable name must be letters, digits and underscores, and must not start with a digit.

Using Them

Any authored text — a message, a button label, an API URL, a header, a body, a Set value, an AI card’s instructions — is templated:
An unknown name becomes an empty string rather than staying on screen as {{...}} — a visitor seeing template syntax is worse than seeing a gap.
Visitor answers are escaped, authored text is not. If you type **bold** into a card you mean it. A visitor who answered an Ask card with **free** did not — so their answer is escaped when it is substituted into your message. This is what stops anything a visitor types becoming live markup inside a message your account appears to have written.

Reaching Them From Code

Inside an AI card function, variables arrive as x_vars and the contact record as x_contact — see The AI card. Inside a Run code card they arrive as the variables argument:

Conversation vs Contact

A variable lives for one conversation. To keep something for next time, write it onto the contact with an Update contact card — then it is readable as {{contact.plan}} in any future conversation with the same person.

Identity

Passing It In

Two optional URL parameters, both worth adding if your app knows the answer.
Up to 40 variables, 64 characters per name, 500 per value. Strings, numbers and booleans only.

How The Contact Key Is Chosen

Every conversation gets a contact key — the thing your CRM sorts by. Three tiers, best first:
1

A phone number

From vars={"phone":"..."}, or collected by a phone Ask card. This wins over everything, because keying on the phone number is what merges this chat with the same person’s calls and WhatsApp.
2

Your uid, exactly as you sent it

Stored verbatim. If the uid is itself phone-shaped it is normalised to digits, so +91 98765 43210 and 9876543210 are one contact — and that contact is the same one the person’s calls are on.
3

A browser-minted visitor id

Generated by the page and kept in local storage. Only as durable as one browser’s storage, but it is the difference between an anonymous visitor being the same person next week and being a stranger every visit.
If a phone Ask card collects a number mid-conversation, everything already said is re-keyed onto that phone number — the transcript is not split in two.
uid is an unauthenticated claim. Anyone who can open the widget can put any value in the URL, including a phone number that is not theirs — and be handed that contact’s CRM record, which an AI card can see as x_contact.It is right for a widget embedded behind your own app’s login, which is what it is for. It must not gate anything the person should not see, and it must not be a value that is itself a secret. Signed tokens are not supported yet.

If You Pass Nothing

The visitor still gets a stable identity of their own, minted in the browser and kept — so an anonymous visitor is still the same person next week, on that device. Clearing site data, or a private window, makes them new again.
A visitor id is never exposed to your app and never leaves the browser it was made in.

Reading It Back

Open Contacts and filter the channel to Widget. Each contact shows the transcript, and the variables the flow collected alongside it — so an order id is readable without scrolling the conversation.

Next Steps

Install in your app

Where the URL parameters go

The AI card

x_vars, x_contact, x_secrets