What a merge tag actually does#
A merge tag is a placeholder you drop into your email subject or body that AcelleMail replaces — per recipient, at send time — with that subscriber's actual value.
Subject Hey {{ subscriber.first_name }}, your invoice for July becomes Hey Maria, your invoice for July for Maria, Hey Tobias, your invoice for July for Tobias.
The values come from list fields — every list has at least email + first_name + last_name, and you can add unlimited custom fields like city, signup_plan, last_purchase_total.
Insert a merge tag from the campaign builder#
1. Start typing in the subject line#
In any campaign, the Subject field accepts merge tags inline. Click the field and start typing — AcelleMail shows a hint about merge-tag insertion:

You can paste a tag directly ({{ subscriber.first_name }}) OR open the picker for the full list.
2. The merge-tag picker (autosuggest)#
Type {{ in the subject — or open the body builder's right-side panel — and the autosuggest dropdown lists every available tag, scoped to this list's actual fields:

Click a tag to insert it. The picker scopes to:
- Subscriber fields — every column on your list (
email, first_name, custom fields)
- System tags —
{{ unsubscribe_url }}, {{ web_view_url }}, {{ campaign.name }}, {{ send_date }}
- Conditional helpers —
{% if %} ... {% endif %} (Twig syntax — see Advanced)
3. Manage the list's custom fields#
The picker only shows fields that exist on the list. To add a new field, Audience → [list] → Fields:

For each field, set:
- Tag (the key) — e.g.
city becomes {{ subscriber.city }} in emails
- Type — text / number / date / dropdown / multi-select
- Required at signup — appears on the signup form, blocks if blank
- Default value — fallback for existing subscribers without this field set
After adding a field, re-run an import (or update via API) to back-fill values for existing subscribers — they won't be back-filled automatically.
Common UI patterns that work#
| What you want |
How to write it |
| First name with a fallback if unknown |
Hi {{ subscriber.first_name | default('there') }} |
| Full name (joined) |
{{ subscriber.first_name }} {{ subscriber.last_name }} |
| Date formatting |
{{ subscriber.signup_date | date('F j, Y') }} |
| Uppercase a value |
{{ subscriber.city | upper }} |
| Truncate a string |
{{ subscriber.bio | truncate(80) }} |
| Numeric formatting |
${{ subscriber.lifetime_value | number_format(2) }} |
These filters use Twig syntax — the AcelleMail builder renders them at send time. You can test any tag by clicking Preview in the campaign builder and toggling the Use sample subscriber dropdown:

Common pitfalls + UI fixes#
| Symptom |
Likely cause |
UI fix |
Email shows literal {{ subscriber.city }} instead of "Berlin" |
Field doesn't exist on this list, OR typo in tag name |
Open Audience → [list] → Fields — confirm the tag matches exactly |
| First name field empty for half the list |
Imported CSV had no first_name column |
Use | default('friend') filter, OR re-export source + re-import with field mapping |
| Picker doesn't show a field you added |
Page cached pre-add |
Hard refresh (Cmd-Shift-R / Ctrl-F5), or close + reopen the builder |
| Subject renders blank for some recipients |
The field is empty for those subscribers + no default filter |
Add | default('something') to the merge tag |
Advanced: Twig conditionals, loops, and computed merge tags
AcelleMail's body and subject support the full Twig templating language — including conditionals and loops — for cases the autosuggest picker doesn't cover.
Conditional content blocks:
{% if subscriber.signup_plan == 'enterprise' %}
<p>Your Enterprise account manager is Sarah — book a call here.</p>
{% elseif subscriber.signup_plan == 'pro' %}
<p>Pro users get priority support — reply to this email anytime.</p>
{% else %}
<p>Get faster response times by upgrading.</p>
{% endif %}
Tag-based blocks (using the multi-value tags field):
{% if 'vip' in subscriber.tags %}
<p>VIP early access: <a href="...">claim your slot</a></p>
{% endif %}
Loops over array fields (when a custom field is JSON-encoded list):
<ul>
{% for product in subscriber.recent_purchases %}
<li>{{ product.name }} — ${{ product.price }}</li>
{% endfor %}
</ul>
Computed values inline:
{% set discount = subscriber.lifetime_value > 500 ? 20 : 10 %}
Your loyalty discount: {{ discount }}%
Default filter chains for safety:
Hi {{ (subscriber.first_name | default(subscriber.email | split('@') | first)) | capitalize }}
This says: try first_name, fall back to the part of the email before @, then capitalize. Bullet-proof against missing fields.
Per-campaign override fields — if you need a value computed at send time (e.g. discount code unique per recipient), use the AcelleMail API to populate a custom field just before launching the campaign, OR set up an automation that sets the field when the trigger fires.
For a deeper Twig reference, the upstream syntax docs at twig.symfony.com apply directly — AcelleMail uses Twig 3.x.
Related articles#