Personalisation tokens: 6 ESP syntaxes and how they fail

TL;DR

Six syntaxes cover almost every newsletter ESP - Mailchimp's *|FNAME|*, Klaviyo / Liquid {{first_name}}, Iterable / Customer.io {{first_name}}, ActiveCampaign %FIRSTNAME%, Salesforce {!Contact.First}, and generic Liquid with default filters. Three failure modes account for almost every personalisation incident: typos in the token name, missing fallbacks, and mismatched syntax.

Personalisation works when it works and is catastrophically embarrassing when it does not. "Hi !" or "Hi {{first_name}}!" sent to 50,000 recipients is the canonical newsletter horror story, and it is preventable with five minutes of checking before send. Here is how each major syntax works and how each one fails.

The six syntaxes

Mailchimp

Hi *|FNAME|*,
*|IFNOT:FNAME|*Hi there,*|END:IF|*

Pipe-delimited tokens between asterisks. Fallback uses the IFNOT/END:IF block - awkward but functional.

Klaviyo / Liquid (Klaviyo's syntax mirrors Liquid)

Hi {{ first_name|default: 'there' }},

Curly-brace tokens with optional Liquid filters. The default: filter sets the fallback inline. Cleaner than Mailchimp.

Iterable / Customer.io

Hi {{first_name}},
Hi {{customer.first_name|default: "there"}}

Same Liquid family. Iterable nests under customer. by convention; Customer.io often uses flat field names.

ActiveCampaign

Hi %FIRSTNAME%,

Percent-delimited tokens, ALL CAPS. Fallbacks set in the field's "default" property in AC's UI rather than inline.

Salesforce Marketing Cloud / Account Engagement (Pardot)

Hi %%FirstName%%,
Hi {!Contact.FirstName},

Two flavours. The %% form is older Marketing Cloud; {!Object.Field} is Pardot/AmpScript-style.

HubSpot

Hi {{ contact.firstname }},

Liquid-style with the contact. namespace. HubSpot's lower-case firstname (no underscore) catches new users out.

The three failure modes

1. Typos in the token name

The most common failure. {{first_nme}} instead of {{first_name}}. The ESP looks up first_nme, finds nothing, and renders the literal text {{first_nme}} to the reader. Detection: Levenshtein distance from every token to the canonical list. Distance 1-2 from a known token but not a perfect match flags as likely typo.

The Newsletrix personalisation validator catches these automatically.

2. Missing fallbacks

The token exists; the recipient's record is missing the field. Without a fallback, the email renders as "Hi !" (Mailchimp swallows the whole token) or "Hi {{first_name}}" (Liquid renders the literal). Either way it ships.

The fix is to always set a fallback inline. In Liquid: {{ first_name|default: 'there' }}. In Mailchimp: the IFNOT block. In Salesforce: the field default. The five-second time investment pays for itself the first time you avoid sending "Hi !" to 50,000 readers.

3. Mismatched syntax

You wrote the email in Mailchimp using *|FNAME|* tokens. You exported the HTML and re-imported into Klaviyo. Klaviyo's renderer only knows Liquid; it ignores the Mailchimp tokens and ships them literally. Or you wrote a Klaviyo template and pasted into ActiveCampaign expecting %FIRSTNAME%.

The fix when you migrate ESPs: re-tokenise everything to the new syntax. Search-and-replace through every template before the first send.

Personalisation in the subject line

First-name personalisation in the subject line lifts open rate 8-12 percent in our corpus, but with two important caveats. First, only when paired with a strong action verb. "Hi {{first_name}}, click here" scores worse than the un-personalised "Save 30 minutes today." Second, always set a subject-line fallback - "Hi !" is the worst inbox impression in the entire industry.

Most ESPs have a separate subject-line fallback field. Use it. If yours does not, set the fallback inline in the token itself: {{ first_name|default: "there" }}.

Beyond first name

The boring application of personalisation is first-name substitution. The interesting one is dynamic content based on recipient attributes - region, plan tier, last-purchase category, signup source. Most modern ESPs support this through conditional blocks:

{% if customer.plan == "pro" %}
  Your Pro features include...
{% else %}
  Upgrade to Pro and get...
{% endif %}

The validator does not currently lint conditional blocks - that is on the roadmap. For now, render-test conditional templates by sending to internal accounts representing every branch.

Validate your tokens before send

The personalisation token validator scans your email body for tokens across all six syntaxes, flags missing fallbacks, and detects typos. Run it on every template you change. The footer checker covers the related compliance pieces.

Open the token validator →

Frequently asked questions

What is a personalisation token?

A placeholder in your email that the ESP replaces with a recipient-specific value at send time.

What is a fallback?

A default value used when the field is missing. Without it, you send "Hi !" or "Hi {{first_name}}".

Most common typo?

{{first_nme}} instead of {{first_name}}. Detect with Levenshtein distance to the canonical list.

Can I mix syntaxes?

No. Each ESP only processes its own. Pick one syntax per template.

Personalise the subject line?

Yes - 8-12% open-rate lift, but only with a strong verb and always with a fallback.

Related reading

Get started

Stop guessing. Start winning.

Join newsletter creators using AI-powered competitor intelligence to ship better content, faster.

No credit card required  ·  Cancel anytime  ·  All features on every plan