# Merge Tags and Conditionals

Merge tags are placeholders that Envoke fills in for each contact when an email is sent. This page lists the tags you can use in your own HTML, how their values are written into the email, and what happens when a tag is misspelled or has no value.

---

## How Merge Tags Work

There are two kinds of tag:

| Kind | Looks like | Filled in with |
|---|---|---|
| Contact field | `{fname}` | A field of the contact's record |
| Envoke tag | `{@brand-address}`, `{@customfield-member_level}` | A custom field, or a value from the message or your account |

- Tags are replaced when each email is sent, not when the HTML is saved. The stored HTML keeps the tags.
- Tags work in the message body and in the subject line.
- Write tags exactly as shown on this page, in lower case. Contact-field names must match exactly; Envoke tags are matched without regard to case, but some checks, such as whether your HTML contains an unsubscribe link, look for the lower-case form.
- Contact-field and custom-field values are HTML-escaped, so a value containing `<` or `&` shows as typed and cannot break your markup.

---

## Contact Fields

| Tag | Contact API field | Value |
|---|---|---|
| `{fname}` | `first_name` | First name, or your account's fallback (see below) |
| `{lname}` | `last_name` | Last name |
| `{fullname}` | — | First and last name, or your account's fallback if there is no first name |
| `{email}` | `email` | Email address |
| `{title}` | `title` | Title |
| `{company}` | `company` | Company or organisation |
| `{phone}` | `phone` | Phone number |
| `{addr1}` | `address_1` | Address, line 1 |
| `{addr2}` | `address_2` | Address, line 2 |
| `{city}` | `city` | City |
| `{province}` | `province` | Province or state |
| `{postal}` | `postal_code` | Postal or ZIP code |
| `{country}` | `country` | Country code, such as `CA` |
| `{website}` | `website` | Website |
| `{language}` | `language` | The language's name, such as `English` or `French` |
| `{remote_id}` | `remote_id` | Your own identifier for the contact |
| `{eid}` | `external_id` | The contact's external ID, for use in links to your own systems |

The fields are described in the [Contact API](https://envoke-developers.pages.dev/v1/contacts/fields/#fields).

- **First-name fallback.** When a contact has no first name, `{fname}` and `{fullname}` are replaced with the text in your account's **If first name is missing use** setting (Account settings, **Email campaigns** tab). No other field has a fallback: an empty field is replaced with nothing.
- **Line breaks** in a field's value become `<br>` in the email.
- **Send API messages** can use fewer contact fields; see [Send API Messages](#send-api-messages).

---

## Custom Fields

```html
<p>Your member level: {@customfield-member_level}</p>
```

| Form | Example |
|---|---|
| `{@customfield-NAME}` | `{@customfield-member_level}` |
| `{@my-NAME}` | `{@my-member_level}`, the form the editor's merge-field menu inserts |
| `{@customfield-ID}` | `{@customfield-17}`, using the custom field's ID |

`NAME` is the custom field's [`name`](https://envoke-developers.pages.dev/v2/customfields/fields/#name), with the same capitalisation. If the field does not exist, or the contact has no value for it, the tag is replaced with nothing.

| Option | Effect |
|---|---|
| (none) | The value, HTML-escaped |
| `\|html` | The value, HTML-escaped, with line breaks turned into `<br>`. Use for multi-line note fields. |
| `\|url` | The value, URL-encoded, for use inside a query string: `https://www.example.com/renew?level={@customfield-member_level\|url}` |

A custom field holding a full URL can be a link: `<a href="{@customfield-renewal_link}">Renew</a>`.

---

## Message and Account Tags

| Tag | Replaced with |
|---|---|
| `{@msg-subject}` | The message's subject, with its own merge tags filled in |
| `{@msg-url}` | The link to view the message online, personalised for the contact |
| `{@msg-url\|noeid}` | The view-online link without the contact's identifier, for sharing |
| `{@msg-subscription}` | The name of the subscription the message is sent to, in the message's language, or nothing |
| `{@msg-mandatory_reason}` | For a mandatory message, its stated reason for being sent; otherwise nothing (see [Mandatory Messages](https://envoke-developers.pages.dev/email-html/unsubscribe-and-footer/#mandatory-messages)) |
| `{@brand-company}` | Your account's name |
| `{@brand-url}` | Your account's website |
| `{@brand-address}` | Your account's postal address, with line breaks (see [Your Postal Address](https://envoke-developers.pages.dev/email-html/unsubscribe-and-footer/#your-postal-address)) |
| `{@brand-logo}` | Your account's logo as an image, linked to your website if one is set |
| `{@pref-0}` | The link to the contact's email preferences page, where they can unsubscribe (see [Your Unsubscribe Link](https://envoke-developers.pages.dev/email-html/unsubscribe-and-footer/#your-unsubscribe-link)) |
| `{@social-NETWORK\|url}` | The link to your profile on that network, from the **Social media** tab of Account settings. `NETWORK` is one of `facebook`, `twitter`, `linkedin`, `instagram`, `pinterest`, `youtube`, `vimeo`, `rss`, `tripadvisor`, `tiktok`, `bluesky`, `threads`. Without `\|url` the tag is replaced with nothing. |

The account name, website, and postal address come from the **Account** tab of Account settings, and the logo from the **Branding** tab. For French messages, the account name, website, and logo are the French versions where your account has them.

---

## Tags in Links

Write a link tag as the whole `href`, with no `https://` in front:

```html
<a href="{@pref-0}">Unsubscribe</a>
<a href="{@msg-url}">View this email in your browser</a>
<a href="{@social-linkedin|url}">Follow us on LinkedIn</a>
```

When click tracking is on, links whose `href` is a merge tag are tracked like any other link. Contact fields and custom fields can also go inside a link, for example in its query string: `https://www.example.com/profile?id={eid}`.

---

## Conditionals

A conditional shows content only when a tag has a value:

```html
<p>
{%if @msg-subscription}
  You are receiving this email because you subscribed to {@msg-subscription}.
{%else}
  You are receiving this email from {@brand-company}.
{%endif}
</p>
```

- The syntax is `{%if @TAG}`, an optional `{%else}`, and `{%endif}`, where `TAG` is a message or account tag from the table above without its braces and `@`, such as `msg-subscription` or `brand-logo`.
- The condition is true when the tag's value is not empty and not `0`. There are no comparisons, no "not", and no "else if"; nest a second `{%if}` inside `{%else}` instead.
- Options such as `|lang:fr` are not allowed inside `{%if}`.
- Put a conditional inside an element, such as a `<p>` or a table cell, never between table tags: browsers, the editor, and Envoke's send process move text found between table tags out of the table.
- Write the keywords exactly: `{%if`, with no space between `{` and `%`.

---

## Send API Messages

Messages sent through the [Send API](https://envoke-developers.pages.dev/v1/send/fields/#tracking-and-merge-fields) fill in fewer tags, depending on `enable_merge_fields`:

| `enable_merge_fields` | Filled in | Left in the email as written |
|---|---|---|
| `false` (the default) | `{@pref-0}`, `{fname}`, `{lname}`, `{eid}` | Every other tag, including `{@brand-address}` |
| `true` | Every Envoke tag on this page, and the contact fields `{fname}`, `{lname}`, `{fullname}`, `{email}`, `{eid}`, and `{remote_id}` | Nothing; other contact fields are replaced with nothing |

- Turn `enable_merge_fields` on whenever your HTML uses any tag other than `{@pref-0}`, `{fname}`, `{lname}`, and `{eid}`. In particular, with it off, `{@brand-address}` appears in the email as the literal text `{@brand-address}`.
- With it off, the first-name fallback still applies to `{fname}`.
- Each recipient's `replace` values are substituted before the tags are filled in, so with `enable_merge_fields` on, tags inside a `replace` value are filled in too.

---

## When a Tag Is Wrong

Nothing checks your tags when the HTML is saved or the message is launched. Send a test to check them (see [Test Checklist](https://envoke-developers.pages.dev/email-html/testing-and-accessibility/#test-checklist)).

| In the HTML | In the email |
|---|---|
| An unknown or misspelled Envoke tag, such as `{@brand-adress}` | Shown as written |
| An Envoke tag with an option containing other characters than letters, numbers, `_`, `:`, `,`, `.`, `-`, and spaces | Shown as written |
| Any other word in single braces, such as `{FNAME}`, `{first_name}`, or a placeholder such as `{SHOW_TITLE}` | Removed: it is looked up as a contact field and, if there is no such field, replaced with nothing |
| Double braces, such as `{{name}}` | `{}` |
| `{%if}` with a tag Envoke does not recognise | The whole block, including the `{%if}`, `{%else}`, and `{%endif}`, shown as written; only contact fields inside it are filled in |
| `{%if}` with an option, a space after `{`, or no closing `{%endif}` | The tags shown as text, and the content of both branches shown |

---

*Full reference, OpenAPI description, and Postman collection: [developers.envoke.com](https://developers.envoke.com).*
