Templates are HTML files with {{ variable }} placeholders that Vlozi replaces with real values at send time. The syntax is Mustache-style — whitespace inside the braces is tolerated, so {{name}}, {{ name }}, and {{ name }} all work.
Variable reference
Subscriber variables
Resolved from the recipient's subscriber record.
| Variable | Example value | Notes |
|---|---|---|
{{ subscriber.name }} |
Alice |
Falls back to "there" when the subscriber has no name set |
{{ subscriber.email }} |
alice@example.com |
The subscriber's email address |
{{ subscriber.tags }} |
newsletter, vip |
All tags as a comma-separated string |
{{ subscriber.metadata.KEY }} |
(depends on your data) | Any key from the subscriber's metadata object. Use dot notation: {{ subscriber.metadata.plan }} |
Unsubscribe link
| Variable | Example value | Notes |
|---|---|---|
{{ unsubscribe_url }} |
https://api.vlozi.app/newsletter/public/unsubscribe?... |
HMAC-signed, unique per recipient. Always include in every template. |
IMPORTANT
Every template sent to subscribers must include {{ unsubscribe_url }}. It is a legal requirement in most jurisdictions (CAN-SPAM, GDPR) and the Vlozi platform will warn you if it is missing.
Campaign variables
| Variable | Example value | Notes |
|---|---|---|
{{ campaign.name }} |
June Newsletter |
The campaign's internal name |
{{ campaign.subject }} |
What's new in June |
The email subject line |
Brand variables
Pulled from your Comms sender settings. Set them in Settings → Email Sender.
| Variable | Example value | Notes |
|---|---|---|
{{ tenant.name }} |
My Company |
Your sender name |
{{ tenant.from_email }} |
hello@mycompany.com |
Your sender email address |
{{ brand.logo_url }} |
https://cdn.example.com/logo.png |
Your brand logo URL. Falls back to an empty string — keep <img src=""> in mind. |
{{ brand.primary_color }} |
#FF5436 |
Your brand's primary hex colour, including the # |
Date variables
| Variable | Example value | Notes |
|---|---|---|
{{ now.year }} |
2026 |
Current UTC year. Useful for footer copyright: © {{ now.year }} {{ tenant.name }} |
Blog post variables
Only available in campaigns triggered by a blog post publish. In manually created campaigns, these resolve to empty string.
| Variable | Example value | Notes |
|---|---|---|
{{ post.title }} |
How to get started with X |
The blog post title |
{{ post.excerpt }} |
A short intro... |
The post excerpt |
{{ post.slug }} |
how-to-get-started-with-x |
Use to build the post URL |
{{ post.cover_url }} |
https://cdn.example.com/cover.jpg |
Featured image URL; empty string when none |
{{ post.author_name }} |
Dipanshu Vishwakarma |
Author's display name |
Writing a minimal template
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /></head>
<body style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 24px;">
<p>Hi {{ subscriber.name }},</p>
<!-- Your email body here -->
<hr style="border: none; border-top: 1px solid #eee; margin: 32px 0;" />
<p style="color: #999; font-size: 12px; text-align: center;">
© {{ now.year }} {{ tenant.name }} ·
<a href="{{ unsubscribe_url }}" style="color: #999;">Unsubscribe</a>
</p>
</body>
</html>HTML escaping
User-controlled substitutions in the HTML body are HTML-escaped before insertion (&, <, >, ", '). This means:
- A subscriber name like
<script>alert(1)</script>renders as<script>alert(1)</script>— safe. - The
{{ unsubscribe_url }}is not escaped (it's a URL we built, not user input). - Plain text body (
textBody) substitutions are not escaped.
You do not need to escape variables yourself — the renderer does it for you.
Template snapshots
When you create a campaign and select a template, the template body is copied into the campaign at that moment. Changes to the template after that point do not affect the campaign. This is intentional:
- Scheduled campaigns are deterministic — the email that fires at 9 AM Tuesday is exactly the email you approved when you scheduled it
- Deleting a template does not break any campaign based on it
The dashboard shows a "Based on [Template Name]" attribution on the campaign, but the template is not referenced at send time.
Unknown variables
If your template contains a token that isn't in the list above — for example {{ user.first_name }} or {{ myCustomToken }} — Vlozi will:
- Pass it through unchanged in the email body (the literal text
{{ user.first_name }}appears) - Log a warning for each unknown token per send
The template editor warns you about unknown tokens when you save, but it won't prevent saving. This lets you build templates incrementally — just make sure to check the token list before you send.
Limitations in v1
- No conditionals —
{% if %}/{% else %}/{% endif %}blocks are not supported. The text is sent literally. - No loops —
{% for %}blocks are not supported. - No filters —
{{ name | upper }}style filters are not supported. - One level of metadata nesting —
{{ subscriber.metadata.plan.name }}resolvesplanonly, not.nameinside it.
These may be added in a future version.