Quick Start
Liquid uses simple syntax to output dynamic values:Where You Can Use Liquid
Liquid is supported throughout Conversion:| Location | Supported Fields |
|---|---|
| Emails | Subject line and body content |
| Workflow nodes | Slack messages, internal email alerts, webhook URLs and bodies, Salesforce task creation |
| Change Field node | The value being set |
| Webhooks | URL and request body |
Liquid Basics
Liquid consists of three core components:Objects
Objects output dynamic values using double curly braces:Tags
Tags create logic and control flow using curly braces with percent signs:Filters
Filters modify output using the pipe character:Data Objects
All Liquid in Conversion is written from the contact’s perspective. This provides a consistent mental model: you’re always asking “what data does this contact have access to?”Contact
Access any field on the contact:Company
Access fields from the contact’s associated company:Opportunities
Access opportunities through two paths, depending on the relationship:- Company Opportunities
- Contact Opportunity Roles
Access opportunities associated with the contact’s company. Returns the 10 most recently created opportunities.Use Iterate over all opportunities:Access the contact’s role on a company opportunity:If the contact has an Opportunity Contact Role (OCR) on an opportunity:
.first and .last as shortcuts:Custom Objects
Access custom objects related to the contact. Each custom object type returns the 10 most recently created objects.| Field | Description |
|---|---|
id | Unique identifier |
type | The custom object type name |
created_at | When the object was created |
updated_at | When the object was last updated |
Tokens
Access token values set in your campaigns:Current Date and Time
Usenow to get the current UTC datetime:
Trigger Context
When a workflow runs, contextual data about what triggered it is available through thetrigger object. Use trigger.type to identify what triggered the workflow.
Form Submissions
| Field | Description |
|---|---|
trigger.form_submission.form_name | Name of the form |
trigger.form_submission.form_id | Unique identifier of the form |
trigger.form_submission.page_url | URL where the form was submitted |
trigger.form_submission.submitted_at | Timestamp of submission |
trigger.form_submission.fields.<field> | Any submitted field value |
Page Visits
| Field | Description |
|---|---|
trigger.page_visit.page_url | URL of the visited page |
trigger.page_visit.referrer | Referring URL |
trigger.page_visit.utm_source | UTM source parameter |
trigger.page_visit.utm_medium | UTM medium parameter |
trigger.page_visit.utm_campaign | UTM campaign parameter |
trigger.page_visit.visited_at | Timestamp of visit |
Email Events
All email triggers share common metadata:| Field | Description |
|---|---|
trigger.email.id | Email asset ID |
trigger.email.name | Name of the email in Conversion |
trigger.email.sent_at | Timestamp when email was sent |
Field Changes
Access previous values when a contact or company field changes:Audience Changes
Opportunity Events
Custom Events
API Triggers
For a complete list of trigger types and their available fields, see Trigger Context Reference.
Conditional Logic
Use Liquid tags to add logic to your content:If/Else Statements
Case Statements
Checking for Empty Values
Filters
Filters transform values. Chain multiple filters with pipes:Common Filters
upcase
upcase
Converts text to uppercase.Output:
HELLOdowncase
downcase
Converts text to lowercase.Output:
hellocapitalize
capitalize
Capitalizes the first character.Output:
Hellodefault
default
Provides a fallback value when the input is empty or nil.Output:
N/A (if middle_name is empty)date
date
Formats a date using strftime syntax.Output:
January 15, 2025Common format codes:%Y— 4-digit year (2025)%m— Month as number (01–12)%B— Full month name (January)%d— Day of month (01–31)%H— Hour in 24-hour format (00–23)%M— Minute (00–59)
size
size
Returns the number of items in an array or characters in a string.Output:
3 (if there are 3 opportunities)first / last
first / last
Returns the first or last item of an array.
split
split
Fallback Values
Use thedefault filter to provide fallback values when data is missing:
Handling Missing Data
When Liquid syntax is valid but data isn’t available at runtime (for example, a form field wasn’t submitted), the expression evaluates to an empty string. This is not treated as an error.-
Use fallbacks for values that might be empty:
-
Use conditionals to show or hide entire sections:
-
Combine both for maximum flexibility:
Validation and Errors
Conversion validates Liquid syntax in real-time as you write. Common validation errors include:| Error Type | Example | Message |
|---|---|---|
| Invalid field | contact.unknown_field | ”unknown_field” is not a valid contact field |
| Invalid object type | objects.unknown_type | ”unknown_type” is not a valid custom object type |
| Invalid index | company._opportunities[15] | Index must be 0–9 |
| Invalid token | tokens.unknown | ”unknown” is not a valid token |
| Syntax error | Missing closing braces | Missing closing braces |
Validation by Context
| Context | What Happens When Validation Fails |
|---|---|
| Email cannot be sent; marked as incomplete in workflows | |
| Workflow node | Node marked as “not set up”; workflow cannot be activated |
| Webhook | Webhook cannot be saved |
Validation catches syntax and configuration errors before runtime. Missing data at runtime (like an empty field) is handled gracefully and won’t cause errors.
Examples
Personalized Welcome Email
Form Submission Follow-up
Opportunity Stage Change Notification
Quick Reference
Object Syntax
| Object | Description | Example |
|---|---|---|
contact | Contact fields | contact.first_name |
company | Company fields | company.name |
company._opportunities | Company’s opportunities | company._opportunities.first.name |
opportunity_roles | Contact’s opportunity roles | opportunity_roles.first.role |
objects.<type> | Custom objects by type | objects.product[0].name |
tokens | Global tokens | tokens.promo_code |
trigger | Trigger context | trigger.type |
now | Current UTC datetime | now (use with date filter) |
Naming Conventions
| Pattern | Meaning | Example |
|---|---|---|
object.field | Direct field access | contact.email |
object._relationship | Related object | company._opportunities |
object[n] | Array index (0–9) | opportunity_roles[0] |
object.first / .last | First or last item | company._opportunities.first |
trigger.<type> | Trigger-specific data | trigger.form_submission.form_name |
trigger.object._previous | Previous value | trigger.opportunity._previous.stage |
trigger.object._changed | Changed field flags | trigger.opportunity._changed.stage |
Frequently Asked Questions
Why do some objects start with an underscore?
Why do some objects start with an underscore?
The underscore prefix (
_) indicates a related object rather than a direct field. For example, company._opportunities accesses opportunities related to the company, while company.name accesses the company’s name field directly.What's the difference between company._opportunities and opportunity_roles?
What's the difference between company._opportunities and opportunity_roles?
company._opportunities returns all opportunities associated with the contact’s company. opportunity_roles returns only opportunities where this specific contact has an Opportunity Contact Role (OCR). A contact might have access to company opportunities they’re not directly involved with.How many items can I access in arrays?
How many items can I access in arrays?
Arrays like
company._opportunities, opportunity_roles, and objects.<type> return up to 10 items, accessible via indexes 0–9.What happens if I reference a field that doesn't exist?
What happens if I reference a field that doesn't exist?
Conversion validates your Liquid in real-time. If you reference a field that doesn’t exist (like a typo or deleted field), you’ll see a validation error and won’t be able to save or send until it’s fixed.
What if a field exists but has no value?
What if a field exists but has no value?
If the field exists but is empty for a particular contact, the expression evaluates to an empty string. Use the
default filter to provide a fallback value.Can I use Liquid in email subject lines?
Can I use Liquid in email subject lines?
Yes! Liquid is supported in both email subject lines and body content. This is a great way to personalize subject lines for better open rates.