Skip to main content
Templates are how you author the actual content Spotzee sends. Every template belongs to a campaign and targets a single channel. Each template has a locale, so a campaign can carry multiple variants of the same channel for different audiences.
Templates live inside the campaign that uses them, not as a separate top-level catalogue. Editing a campaign’s templates requires the project editor role or higher. Fields that support variables can use contact attributes and supplied event data.

The template model

Two attributes shape every template: its channel type and its locale.
  • Channel type decides which fields the template carries. An email template has from, subject, and html. A push template has title, body, and url. The two types share no fields.
  • Locale lets you author variants of the same template for different audiences. A campaign sending in English and German would carry one email template per locale.
When Spotzee dispatches a campaign send, it picks the template whose channel matches the channel the user is enrolled on, then picks the locale variant whose locale matches the user’s locale (with fallback to the project default locale).

Channel field reference

Compose email templates with the visual builder, WYSIWYG editor, HTML code or plain text.The subject, preheader, from, from.name, from.address, reply_to, cc, bcc, text, html and custom-header values support variables before sending.

Template variables

Use double braces to insert a value, such as {{user.email}}. The available variable families are: Use helpers and blocks for formatting and conditional content:
For a contact with firstName set to Sam, signup_at set to 2026-09-15T00:00:00Z and lifetime_value set to the number 1250, these examples produce Sam, Sep 15, 2026, Hello Sam and $1,250.00. Double braces escape HTML-sensitive characters. For example, A&B becomes A&B. Use triple braces, such as {{{user.sender_group}}}, only when you intend unescaped output. Missing properties normally produce an empty string; use an if block to supply a fallback. The same expression syntax works in subject lines, preheaders, plain-text and HTML email bodies, custom email-header values, SMS bodies, push titles, push bodies, push URLs, push custom maps, webhook endpoints, webhook headers and webhook bodies.

Locale variants

Multi-locale projects rely on per-template locales. The pattern is straightforward:
  1. Set a project default locale in SettingsGeneralRegional defaults.
  2. Create the default-locale template inside your campaign.
  3. Add per-locale variants for each additional audience (en-US, de-DE, es-MX, and so on).
When Spotzee dispatches a send, it picks the variant whose locale matches the user’s locale. If no exact match exists, Spotzee falls back to the project default locale’s variant. A user with no locale set falls through to the default too.

Email editor modes

Email templates carry an editor field that decides which authoring surface you see:
  • code drops you into raw HTML. You write or paste HTML directly. Good for templates moved over from another platform or built externally.
  • visual uses the Visual builder with drag-and-drop blocks. It generates the HTML that Spotzee sends when you save.
  • wysiwyg uses the WYSIWYG editor for rich content. It preserves your editable design and generates the HTML that Spotzee sends when you save.
  • plain is plain-text only. The text field is required and the html field is ignored. Use this for transactional notifications, agent-style communications, or audiences where HTML is unwelcome.
Review the content after switching editor modes, then save and reopen the template to confirm the result. All four modes support the same custom email-header rows.

Custom email headers

Use template headers for metadata that varies by contact or campaign. They apply to campaign emails, journey emails and proofs. Configure any routing rules at your provider separately.
1

Open the template's header settings

In the campaign wizard, open the email template’s advanced settings. You can also edit headers in the template details form.
2

Add a header row

Select Add header. Enter a literal name in Header name and an expression or fixed value in Header value. For example, use X-Delivery-Group with {{user.sender_group}} if your provider uses that header for routing.
3

Save and verify

Correct any inline validation error, then save. Reopen the template to confirm the rows, send a proof to a controlled contact and inspect the outgoing message headers.
The field names appear inside empty inputs. Use the minus button in the third column to remove a row. Remove every row to clear template headers. Keep a row with an empty value when you want to suppress its matching provider header.

Provider precedence

Template names override matching provider headers without regard to case. Unrelated provider headers remain present. Each message renders its values from that contact’s context, including company references used only in a header. An empty or whitespace-only rendered value suppresses the matching provider header and adds nothing in its place. Previews omit that empty header. Removing the template row restores the provider’s default on later sends.

Save and send errors

Invalid names, reserved names, duplicate names and malformed rows prevent saving and identify the affected row or name. Correct or remove the row and save again. The wizard keeps the form open after a failed save. If you edit while navigation is waiting for a save, check the latest edit and select the destination again. If WYSIWYG content fails validation, the previously saved content and header rows remain unchanged. Correct the content and save again. An invalid header expression follows the same error-reporting path as an invalid subject expression. Unsafe rendered control characters also stop the send before provider submission. Check the failed send, journey error or proof error, correct the expression or source data, then test again.

Routing from a journey

For a provider that routes on X-Delivery-Group, set its template value to {{user.sender_group}}. In a journey, configure User Update with {"sender_group":"grp_b"}, followed by Delay and the email send. Confirm the property is saved during the delay, then inspect the outgoing message after the journey resumes for X-Delivery-Group: grp_b. A proof checks the supplied rendering context. A resumed journey checks that the send uses the saved contact update. Two project-level switches change what Spotzee does to template content at send time:
  • Track opens (email). When on, Spotzee injects a 1×1 tracking pixel into HTML emails so you can report opens. Plain-text emails (editor: plain) never get a tracking pixel.
  • Wrap links (email and push). When on, Spotzee rewrites every link through your tracking domain so you can report click-throughs. The link wrapping respects your custom domain configuration if one is set.
Both switches default to on for email. Push link wrapping is off by default. Toggle them under SettingsGeneralEmail tracking and Push and SMS.

Reference

Template header data

The optional data.customHeaders field contains an array of objects with string name and value fields. An empty array clears every template header. Existing templates need no migration. Duplication and WYSIWYG saves preserve header rows, including literal empty values. For example, this value defines one dynamic header and suppresses a provider’s X-Optional default:

Header names

A name must contain one or more printable ASCII characters, excluding whitespace and :. Names are literal and do not support expressions. Duplicate names are rejected without regard to case. These exact names are reserved, without regard to case:
  • From, Sender, Reply-To, To, Cc, Bcc, Subject, Date, Message-ID.
  • In-Reply-To, References, Return-Path, Received, Delivered-To, Errors-To.
  • MIME-Version, DKIM-Signature, Authentication-Results, Received-SPF, SPF, DMARC.
  • List-Unsubscribe, List-Unsubscribe-Post, X-Campaign-Id, X-Subscription-Id, X-Test-Email.
Names starting with Content-, Resent- or ARC- are also reserved, without regard to case. These restrictions protect addressing, message structure, authentication, tracking, unsubscribe and proof headers.

Header values

Spotzee stores values unchanged, including expressions and empty strings. Template headers do not inherit provider header-count or value-length limits; provider configuration keeps its existing validation rules. After rendering, a value containing a carriage return, line feed or another ASCII control character fails compilation. Horizontal tab is allowed; DEL is rejected. The error identifies the header without including its rendered value. Non-empty values are not silently trimmed or sanitised.

Next steps

Concepts

Brush up on Users, Journeys, Segments, Channels, and Providers.

Trigger a campaign

Send a one-shot campaign through the API.

Set up a project

Configure your default locale and tracking switches.

Provider catalogue

See which providers handle each channel type.