Skip to main content

Template Variables

Personalize messages, notifications, and other content with dynamic variables.

Basic Syntax

Use double curly braces: {{variable.property}}

Hello {{member.first_name}}, welcome! I'm {{assistant.name}}.

Available Variables

Member

VariableExample
{{member.first_name}}"Jane"
{{member.name}}"Jane Smith"
{{member.email}}"jane@example.com"
{{member.phone}}"+1 555 123-4567"
{{member.date_of_birth}}"1980-06-15"
{{member.age}}45

Member Form Data

Access data type fields by slug and field name:

{{member.data.contact_info.emergency_contact}}
{{member.data.profile.company_name}}

Member Collections

Access collection data types with count, latest record, and recent records:

{{member.collections.patient_visits.count}}
{{member.collections.patient_visits.latest.data.diagnosis}}
{{member.collections.patient_visits.latest.created_at}}
{{member.collections.lab_results.latest.data.result}}

Loop through recent records (up to 50 per type):

{% for visit in member.collections.patient_visits.recent %}
- {{visit.data.diagnosis}} ({{visit.created_at}})
{% endfor %}

Filter by field value across recent records:

{% for visit in member.collections.patient_visits.recent | selectattr("data.status", "equalto", "completed") %}
- {{visit.data.diagnosis}} ({{visit.created_at}})
{% endfor %}

Performance: .recent loads up to 50 records per collection type (newest first). Use .recent | selectattr(...) when you need to filter by a field value.

Tip: {{member.data.<collection>.<field>}} also works for collections but returns a non-deterministic record when multiple exist. Use member.collections for reliable, structured access.

Assistant

The assistant variable refers to the assistant snapshot owned by the current Workflow revision (or an explicit per-Chat override). It does not read a live Agent record.

VariableExample
{{assistant.name}}"Support Bot"
{{assistant.first_name}}"Support"

Task

VariableExample
{{task.name}}"Customer Onboarding"
{{task.description}}"Complete setup"

Chat

VariableExample
{{chat.id}}"cht_987654321"

Phone number (in phone-voice / phone-sms chats)

The workspace phone number the current chat arrived on. Only populated for chats with a linked workspace phone number — typically phone-voice and phone-sms. Renders empty for web-chat and other channels.

VariableExample
{{phone_number.number}}"+15551234567"
{{phone_number.name}}"Reception"
{{phone_number.brand_name}}"Acme Health"

Example template:

You can reach us back at {{phone_number.number}} ({{phone_number.brand_name}}).

Call (in call:completed events)

Only available on call:completed event rules. Lets you branch on how the call actually ended.

VariableExample
{{call.disposition}}"busy", "no-answer", "completed", "failed", or "canceled"

Example CEL condition on a call:completed rule:

call.disposition == "busy"

Example template:

Sorry we missed you — the line was {{call.disposition}} when we called.

Record (in data record events)

VariableExample
{{record.id}}"12345"
{{record.data.field_slug}}Field value
{{record.owner.name}}"Jane Smith"

Snippets

Workspace-scoped reusable text fragments. Reference them anywhere a template is supported.

{{snippets.tone.professional}}
{{snippets.address.hq}}

Snippets can reference other snippets (up to 3 levels deep), so you can compose longer templates from smaller reusable pieces.

Date & Time

Always available as {{datetime.*}}. Common keys:

VariableExample
{{datetime.today}}"2026-04-28"
{{datetime.now}}"2026-04-28T14:32:00Z"
{{datetime.start_of_week}}"2026-04-27"

Filters

Gravity Rail templates are rendered with Jinja2, so every standard Jinja2 filter is available — upper, lower, title, capitalize, trim, default, length, join, replace, truncate, int, float, round, sum, min, max, urlencode, and more. Use them with the pipe (|) syntax: {{ value | filter }}.

On top of those, Gravity Rail adds a few custom filters tailored for member data.

oxford_join — format a list with Oxford commas

Turns a list of values into a grammatically natural English phrase.

InputOutput
['apple']apple
['apple', 'pear']apple and pear
['apple', 'pear', 'plum']apple, pear, and plum
Today we discussed {{ member.data.visit.topics | oxford_join }}.

date — format dates and timestamps

Reformats a date, time, or datetime value. Default output is YYYY-MM-DD; pass any strftime format string to customize.

{{ record.created_at | date }}                    → 2026-04-15
{{ record.created_at | date('%d/%m/%Y') }} → 15/04/2026
{{ record.created_at | date('%B %d, %Y') }} → April 15, 2026
{{ member.date_of_birth | date('%b %d') }} → Apr 15

If the input can't be parsed as a date, the original value is returned unchanged. Empty or missing values render as "".

enum_label — show the readable label of a select-field value

Form fields of type Select and Multi-select store values as short slugs (e.g. high, follow_up_needed). Use enum_label to render the human-readable label the field was configured with instead of the slug.

{{ member.data.call_log.call_reason | enum_label('call_reason', 'call_log') }}
→ "Appointment follow-up"

{{ record.data.status | enum_label('status') }}
→ "Awaiting Response"

How to use it:

  • First argument: the field slug inside the data type.
  • Second argument (optional): the data type slug. You can omit it when the template is rendered in the context of a record of that data type (event rules on records, record-scoped actions).

Behavior:

  • Works with member.data.*, member.collections.*.latest.data.*, record.data.*, and any other enum value.
  • Falls back to the raw value if the field, option, or data type can't be resolved — it never errors.
  • Respects workspace permissions — if the template executes under a role that can't read the referenced data type, the filter falls back to the raw value instead of leaking the label.

Examples

Simple greeting

Hi {{member.first_name}}, thanks for reaching out!

With form data

Your order for {{member.data.order.product_name}} is confirmed.
Shipping to: {{member.data.shipping.address}}

Conditional content

{% if member.data.profile.company %}
Company: {{member.data.profile.company}}
{% endif %}

Readable enum values in reminders

Your {{ record.data.appointment_type | enum_label('appointment_type') }}
is on {{ record.data.visit_date | date('%A, %B %d') }}.

Composing snippets + filters

{{ snippets.tone.professional }}

You mentioned {{ member.data.intake.concerns | oxford_join }}.
Our next step is {{ record.data.next_step | enum_label('next_step', 'intake') }}.

Title-cased greeting with formatted date

Hi {{ member.first_name | title }}, thanks for reaching out!
Your visit is scheduled for {{ record.data.visit_date | date('%B %d') }}.

Tips

  • Test first - Preview templates before using in production
  • Handle missing data - Use {% if %} for optional fields
  • Use snake_case - All variable names use snake_case format
  • Actions — Use template variables in automated notifications
  • CEL Expressions — Write dynamic conditions using similar variables
  • Forms — Define the data types that template variables access