Campaign Template Expressions
This reference explains all supported expression features in campaign message templates.
Quick Start
- Use
{{ ... }}to evaluate an expression. - Simple variable:
{{ first_name }}
- Dot access:
{{ webhook.raw_data.deal.stage }}
- Function:
{{ capitalize(first_name) }}
- Conditional (ternary):
{{ gender == "Male" ? "Mr." : "Ms." }}
Where It Works
- Main message body (
template_body) - A/B variant B message body (
ab_variant_b_body)
Slash Commands (/)
- Typing
/in the editor shows functions only. - Example: typing
/capsuggestscapitalize(...). - Variables are inserted with variable chips/buttons, not slash commands.
Supported Syntax
1) Variables
- Basic:
{{ name }}
- Dot notation:
{{ contact.first_name }}
2) Literals
- Strings:
{{ "hello" }}{{ 'hello' }}
- Numbers:
{{ 42 }}
- Booleans / null:
{{ true }}{{ false }}{{ null }}
3) Operators
- Equality:
==,!=
- Logical:
&&,||,!
- Ternary:
condition ? whenTrue : whenFalse
Examples:
{{ status == "vip" }}{{ has_email && has_phone }}{{ !opted_out }}{{ first_name ? first_name : "there" }}
4) Indexing
You can index arrays and strings:
{{ split(email, "@")[0] }}{{ "hello"[1] }}
Supported Helper Functions
All helper names are case-sensitive.
Sample data used in helper results:
{
"first_name": "jANE",
"email": "sophie.martin@gmail.com",
"language": "fr-FR",
"company": "ACME CORP",
"country_code": "fr",
"full_name": " Sophie Martin ",
"tags": "vip,priority,new",
"phone_number": "+14155550123"
}lower(value)
Converts text to lowercase.
- Variables:
company = "ACME CORP" - Expression:
{{ lower(company) }} - Output:
acme corp
upper(value)
Converts text to uppercase.
- Variables:
country_code = "fr" - Expression:
{{ upper(country_code) }} - Output:
FR
capitalize(value)
Uppercases first character and lowercases the rest.
- Variables:
first_name = "jANE" - Expression:
{{ capitalize(first_name) }} - Output:
Jane
trim(value)
Removes leading/trailing whitespace.
- Variables:
full_name = " Sophie Martin " - Expression:
{{ trim(full_name) }} - Output:
Sophie Martin
split(value, separator)
Splits a string into an array.
- Variables:
email = "sophie.martin@gmail.com" - Expression:
{{ split(email, "@")[0] }} - Output:
sophie.martin
join(value, separator)
Joins an array into a string.
- Variables:
tags = "vip,priority,new" - Expression:
{{ join(split(tags, ","), " | ") }} - Output:
vip | priority | new
default(value, fallback)
Returns fallback if value is null, undefined, or empty string.
- Variables:
first_name = "jANE" - Expression:
{{ default(first_name, "customer") }} - Output:
jANE - Variables:
first_name = "" - Expression:
{{ default(first_name, "customer") }} - Output:
customer
contains(value, substring)
Checks whether text contains a substring.
- Variables:
email = "sophie.martin@gmail.com" - Expression:
{{ contains(email, "@gmail.com") }} - Output:
true
startsWith(value, prefix)
Checks whether text starts with a prefix.
- Variables:
phone_number = "+14155550123" - Expression:
{{ startsWith(phone_number, "+1") }} - Output:
true
endsWith(value, suffix)
Checks whether text ends with a suffix.
- Variables:
email = "sophie.martin@gmail.com" - Expression:
{{ endsWith(email, ".fr") }} - Output:
false
Cumulative (Composed) Expressions
You can combine multiple helpers and operators in a single expression.
- Normalize + fallback + capitalize
- Expression:
{{ capitalize(default(trim(first_name), "customer")) }} - Result:
Jane
- Expression:
- Parse + transform + branch
- Expression:
{{ endsWith(lower(split(email, "@")[1]), ".fr") ? "FR lead" : "Non-FR lead" }} - Result:
Non-FR lead
- Expression:
- Split + join + uppercase
- Expression:
{{ upper(join(split(tags, ","), " | ")) }} - Result:
VIP | PRIORITY | NEW
- Expression:
- Multi-condition decision
- Expression:
{{ startsWith(phone_number, "+1") && contains(language, "fr") ? "NA-FR segment" : "other segment" }} - Result:
NA-FR segment
- Expression:
Composed Full Message Example
Template
{{ contains(language, "fr") ? "Bonjour" : "Hello" }} {{ capitalize(default(trim(first_name), "customer")) }}, segment: {{ startsWith(phone_number, "+1") && contains(language, "fr") ? "NA-FR" : "other" }}.
Result
Bonjour Jane, segment: NA-FR.
Copy/Paste Examples
- Salutation:
{{ gender == "Male" ? "Mr." : "Ms." }}
- First-name fallback:
{{ capitalize(default(first_name, "customer")) }}
- Company lowercase:
{{ lower(company) }}
- Username from email:
{{ split(email, "@")[0] }}
- Conditional default greeting:
{{ contains(language, "fr") ? "Bonjour" : "Hello" }}
Notes and Limitations
- Unknown function names are not executed.
- Invalid expressions are left as-is (placeholder text remains).
- No arbitrary JavaScript execution is allowed.
- For WhatsApp template parameter extraction, only simple variable names are treated as "simple variables"; complex expressions are still evaluated at send/render time.