6–10 min read
Expressions
Updated on: 22/12/2025
Quick setup checklist
Use a plain variable when you just want to insert a stored value into a message:
Hi @contact.first_name, you entered @results.age for age. Is this correct?
Use an expression when you want RapidPro.app to evaluate a formula (functions, math, formatting, conditions):
Hello @(upper(contact.first_name))
All expressions use this wrapper:
@( ... )
Examples:
@(now())
@(time_from_parts(9, 30, 0))
When you type @( in many editors, RapidPro.app shows an autocomplete/help panel with available functions.
[CAPTURE: Editor showing typing @( and the autocomplete function list.]
Inside @(...), you typically reference values without the @ prefix (for example: contact, results, fields, globals).
Common examples:
@(contact.first_name)@(results.age)@(fields.district)@(globals.support_email)@(input.text)
If you only need to insert a value (no calculation), keep the plain variable form:
@contact.first_name@results.age@fields.district
@(contact.first_name), not @("contact.first_name").[CAPTURE: Message editor showing correct variable insertion and an expression example.]
Functions are called inside expressions. Function names are not case-sensitive (e.g., upper = UPPER).
Text formatting example:
Hello @(upper(contact.first_name))
Date formatting example:
Year: @(format_date(now(), "YYYY"))
Conditional-style pattern example (keep outputs strict when routing):
@(if(results.score >= 4, "urgent", "normal"))
[CAPTURE: Flow node showing a Send Message using @(upper(…)) and @(format_date(…)).]
Supported arithmetic operators:
- Add:
+ - Subtract:
- - Multiply:
* - Divide:
/ - Exponent:
^
Example (nested parentheses):
Result is @(1 + (2 - 3) * 4 / 5 ^ 6)
Example (computed age from birth year):
You are @(format_date(now(), "YYYY") - results.year_born) years old
To join strings inside an expression, use & and wrap the full expression in @(...).
Example (full name):
@(contact.first_name & " " & contact.last_name)
Example (build a short label):
@("ID: " & results.case_id)
[CAPTURE: Send Message showing a concatenated expression producing a combined string.]
- Open the flow and run it in the Simulator.
- Test realistic inputs (valid + invalid).
- Open the Context Explorer to inspect available values (contact, fields, results, input, globals).
- Copy the exact variable/expression from the explorer to avoid typos.
[CAPTURE: Simulator showing the @ icon (Context Explorer) and expanded variables.]
Common Issues
My expression prints as text instead of evaluating
Fixes:
- Confirm it starts with
@(and ends with). - Check for missing or extra parentheses inside nested functions.
- Remove quotes around variable names (use
contact.first_name, not"contact.first_name").
The expression ends too early (nesting breaks)
Fixes:
- Only close the final
)after the entire formula is complete. - Count parentheses when nesting multiple functions.
My concatenation doesn’t work
Fixes:
- Use
&(not+) to join text. - Wrap the whole concatenation inside
@(...). - Use quotes only for literal text (e.g.,
" "), not for variables.
Variables are blank inside an expression
Fixes:
- Confirm the value exists at runtime (e.g., the contact reached the node that creates
@results.*). - Verify the exact variable name using the Simulator’s Context Explorer.
- If it’s a contact field, confirm it was saved before you reference it.
A function call fails or behaves unexpectedly
Fixes:
- Check the function signature in your Function Reference.
- Verify input types (number vs text vs date) and convert/format if needed.
- Test with a short debug message (print the intermediate value) before using it in routing.
