Chat
Variable Substitution
Variables let one prompt serve every customer. Instead of writing a chat agent that asks who it is talking to, you hand it what you already know and let it start three turns ahead.
The double-brace syntax
Anywhere you write copy โ system prompt, greeting, Say node, tool inputs, SMS templates โ a name in double braces is replaced before the model sees the text. Substitution happens server-side at turn construction.
You are the support assistant for {{business_name}}.
The customer is {{customer.first_name}} on the {{customer.plan}} plan.
Their most recent order is {{order.number}}, placed {{order.placed_at | date}},
currently {{order.status}}.
Never ask for information already present above.Where variables come from
| Source | How it is set | Typical fields |
|---|---|---|
| Workspace | Settings โ Workspace | business_name, support_hours, timezone |
| Identify call | Katexs.identify() in the widget | customer.* |
| Page context | data-context attributes or context push | page.url, cart.total |
| Tool results | Written automatically by Tool nodes | order.*, ticket.* |
| Collected in-conversation | Collect nodes and extraction rules | anything you name |
Katexs.push(["context", {
customer: { first_name: "Dana", plan: "pro", lifetime_value: 2840 },
order: { number: "40128", status: "shipped", placed_at: "2026-07-28" },
page: { url: location.href, product_sku: "KX-220" }
}]);Filters
A pipe applies a formatter. Filters run after lookup, so they are safe on missing values โ a filter on an empty variable returns an empty string rather than throwing.
| Filter | Input | Output |
|---|---|---|
| date | 2026-07-28 | July 28, 2026 |
| relative_date | 2026-07-28 | five days ago |
| currency | 2840 | $2,840.00 |
| title | dana whitfield | Dana Whitfield |
| phone | +15555550142 | (555) 555-0142 |
| truncate:80 | long text | first 80 characters plus an ellipsis |
Defaults and missing values
An unresolved variable renders as an empty string, which produces awkward sentences. Always supply a default for anything not guaranteed to exist.
Hi {{customer.first_name | default:"there"}} โ I can see
{{order.number ? "your order " + order.number : "your account"}} here.Safety rules
- Values are data, never instructions โ Substituted content is escaped and fenced so a customer-supplied name cannot rewrite the prompt.
- Verify before you personalise โ Only inject account data when identity is verified; otherwise anyone who guesses an email sees another customer's order.
- Keep secrets out โ Never place API keys or internal-only notes in variables. Anything in the prompt can be surfaced by a determined caller.
- Redact in logs โ Mark fields sensitive in Creator and they are masked in transcripts, exports, and webhook payloads.
Testing substitution
The Creator preview has a variable panel: fill it with a realistic record and the rendered prompt appears exactly as the model will receive it. Testing Lab scenarios carry their own variable fixtures, so you can regression-test the personalised and anonymous paths separately.
