Skip to main content
ConveYour uses Liquid — the same templating family popularized by Shopify and many CMSs — almost anywhere you personalize a contact’s experience: SMS, email, lesson content, automations, smart links, and more. One mental model, many surfaces.

Why Liquid

  • Logic + data, not just tokens — Conditionals, filters, defaults, and composable snippets. Not a fixed mail-merge grid.
  • Composable content — Pull in shared blocks, nest them, and keep long programs maintainable.
  • Scheduling-aware — Booking and reschedule links can surface directly in copy when someone has an appointment on file.
  • Integration-friendly — Pass your own structured data into templates when you compile content via the API so your stack and ConveYour share one language.

Contact fields

Job to be done: Greet someone by name, branch on whether a field exists, or fall back gracefully. Where: SMS bodies, email bodies and subjects, lesson text, form acknowledgements, campaign messages — anywhere merge tags are supported.
Many org-defined fields are available on contact and often at the root of the template too, so first_name and contact.first_name can both work — handy when migrating old copy.

SMS

Job to be done: Send a punchy text that still feels 1:1. Where: SMS campaigns, automated SMS steps, alerts.

Email

Job to be done: Match subject lines to body copy; keep both on-brand. Where: Email campaigns, triggered emails, invite and system mail that supports Liquid. Subject line:
Body:

Lessons

Job to be done: Make lesson content feel like it was written for this learner — not a static PDF. Where: Lesson item fields — rich text bodies, poll questions, open-ended prompts, challenge text, and similar fields depending on the block type. Poll / question:
Instructional body:
Scheduling URL field — the URL itself can be templated:

Snippets

Job to be done: One canonical disclaimer, footer, or compliance block — embedded in SMS, email, and lessons without copy-paste drift. Where: Any Liquid-enabled text. Reference a saved Snippet by its shortcut using function-style syntax.
Snippets nest: a snippet can call another snippet, and each one is itself compiled (so a nested snippet’s own Liquid runs too).
The limit is a total of 6 snippet expansions per compile, not a nesting depth. The counter is shared across the whole template, so six side-by-side snippets exhaust it just as fast as six nested ones. Expansions beyond the sixth resolve to an empty string — silently, with no error.If a footer or disclaimer mysteriously renders blank, count the snippet(...) calls in the whole message, including any inside other snippets.
The shortcut is a bare name of word characters, dots, and underscores (e.g. snippet(program.intro)), and surrounding whitespace inside the parentheses is allowed. Snippets resolve after Liquid renders.
Job to be done: Confirmations and reminders that include action links tied to the learner’s latest booking. Where: SMS, email, or lesson copy when referencing booking data for a specific contact field (e.g. the field used for “interview” or “onboarding session”).
Replace interview with the contact field name your org uses for that booking. If there is no booking, pair with default or an {% if %} check.

Custom Object Relations

Job to be done: Traverse relationships between custom object records inside Liquid, so templates can pull nested fields without extra API work. Where: Anywhere Liquid is supported (SMS, email, lessons, snippets, triggered messages), as long as your org has added Relation fields to custom object schemas. Path shape:
Example — division → region → name:
Dotted paths that cross a Relation field may resolve to actual related-record data instead of raw IDs. Be intentional about which fields you expose in outbound messages.

Query custom object records

Job to be done: Pull a filtered, sorted set of custom object records straight into a template — no extra API call. Where: Anywhere Liquid runs, when your org has a Custom Object defined. Start from customObject (by the object’s name), narrow with where + a comparison, optionally sort, then get to execute:
The chain is built from these filters: Use your schema field names in where and sort — the engine maps them to storage paths automatically. An unknown object name yields an empty result set, so templates degrade gracefully.

Contact variables

Job to be done: Read and manipulate small structured values stored on the contact — scores, flags, JSON blobs — without dumping raw JSON in the message. Where: Advanced templates across channels. Read a stored value with grab:
Write or remove one with store and drop:
contact.vars resolves to a per-contact pointer, so these filters read and write values scoped to that single contact.

Bring your own data (API compile)

Job to be done: Your app already knows something ConveYour does not store — order ID, cohort, external case number — and you want it inside the template at send time. Where: Flows that call ConveYour’s content compile capability. Pass a template string plus a JSON inputs object. Your keys show up on the template root as inputs.
You also get context about the authenticated user where the platform provides it:

Filters

Default when empty

Passwords / one-time tokens

generatePassword ignores whatever is piped into it — pipe an empty string and pass the length:
The argument is the length (defaults to 8 if omitted).

Time and timezone

tz converts a datetime to a timezone (returning an ISO-8601 string); formatTime renders any datetime with a PHP date() format string. Chain them to localize and format in one pass:
Pass the special format "unix" to get a timestamp back: {{ contact.schedule_date | formatTime: "unix" }}. Two convenience filters build on the same date handling:
dayOfWeek returns the weekday name (Monday); dayOfMonth returns the day with its ordinal (3rd). Replace schedule_date with your org’s field name throughout.

Extract a list

list pulls one key out of each item in an array (or a comma-separated string) and joins the values with commas. Defaults to the id key:

Signed tokens (JWT)

jwtToken mints an org-signed JWT — the first argument is the expiration, followed by key/value pairs to embed in the payload:
jwtToken only produces a token when your org has its own JWT secret key configured (otherwise it returns an empty string) — it’s meant for signing links your own systems will verify. Ask your ConveYour team if this is set up for you.

Validate and normalize data

Job to be done: Clean up messy contact data, check validity, and branch in the template — or collect a list of errors before sending a payload to an integration. Each field passed through format returns an object with three properties: Single field example:
Discover available formats:

Supported formats

Pre-flight validation

Validate several fields at once and output either valid or a list of failures — ideal before pushing data to an external system:
When everything passes, output is simply valid. When something fails:
format is a structure and sanity check — it catches typos, wrong lengths, and invalid patterns. It does not verify that a bank account is open, that an SSN belongs to the contact, or that an email inbox exists. For integrations requiring proof of account ownership, pair template validation with your provider’s verification flow.

Plugin extras

Some capabilities are add-ons or plugins. When enabled, you get additional Liquid filters — same template language, more superpowers. Magic links (personalized short links into flows):
Waiting rooms (JWT-backed room URLs):
Ask your ConveYour team what is enabled for your workspace — each plugin can register its own filters, and some orgs have bespoke ones built for their workflow.

Standard Liquid is available too

Everything above is ConveYour’s custom filters. The full standard Liquid vocabulary works alongside them — the tags you’ve seen in these examples (assign, capture, if/unless, for, case) plus cycle, tablerow, paginate, increment/decrement, raw, and comment, as well as standard filters like upcase, downcase, date, size, and join.
ConveYour does not add custom tags — only custom filters (and the snippet(...) shortcut). So if a capability isn’t a standard Liquid tag, it’s a custom filter — the common ones are documented above.

Design principles

  1. Templates travel — Skills you build for SMS transfer to lessons and email.
  2. Composition beats duplication — Snippets and filters exist so programs scale past a handful of campaigns.
  3. Integration-friendly — Liquid is widely understood; pairing it with inputs from your systems keeps ConveYour from becoming a walled garden.

What to do next

  • Prototype a lesson block with {{ contact.first_name }} and a snippet(...) call — then reuse that snippet in an SMS.
  • If you integrate with the ConveYour APIs, exercise compile with inputs and confirm your keys resolve in Liquid.
  • Ask your org admin which plugins (magic links, waiting rooms, etc.) are live — those unlock extra filters.