Matrix: M22
Open in panel — /app/sending
Sending

Email Templates

Templates let you define reusable email designs with server-side personalisation using Handlebars expressions. Variables are resolved at send time, enabling per-recipient customisation without client-side HTML manipulation.

Create a Template

POST to /v1/templates to create a new template. Once created, you can reference it by ID when sending messages.

{create_template}

Template fields

FieldTypeRequiredDescription
namestringYesUnique name within the workspace. Lowercase, hyphens allowed.
descriptionstringNoHuman-readable description for the template.
subjectstringYesEmail subject. Supports Handlebars expressions.
htmlstringYes*HTML body. (*or text must be provided.)
textstringNoPlain-text body. Recommended forplain-text MUAs.
editorstringNoCurrently only handlebars. Defaults to handlebars.
variantsarrayNoA/B test variant definitions (see A/B section).

List Templates

{list_templates}

Returns paginated results with id, name, description, version, created_at, and updated_at for each template.

Handlebars Syntax

Templates use Handlebars as the templating engine. All variable substitutions use double-curly braces {{varname}}. HTML in variable values is automatically escaped unless you use triple-braces {{{varname}}}.

Variable Substitution

<p>Hi {{first_name}}, welcome to {{company_name}}!</p>
<p>Order #{{order_id}} is {{status}}.</p>

Conditionals with #if / #unless / #else

{conditional_handlebars}

Block helpers: {{#if condition}}, {{#unless condition}} (inverse of if), {{#else}}, {{#each items}}, {{#with object}}. All block helpers must be closed with {{/if}}, {{/unless}}, etc.

Per-Recipient Personalisation

When sending using a template, pass template_vars per recipient in the send request. Each recipient can have a different set of variable values.

{render_send}

Variables defined in template_vars at the message level are merged with per-recipient vars; per-recipient values take precedence.

Fallback Content for Missing Variables

By default, if a Handlebars variable is not provided at send time, the literal placeholder is left in the rendered output. To provide a fallback, use Handlebarsdot-notation defaults:

<p>Hi {{first_name "Valued Customer"}}!</p>
<p>Your plan: {{plan "free"}}</p>

If first_name is missing, the output becomes Hi Valued Customer!. Fallback strings are specified after the variable name inside the expression.

You can also validate required variables before send by calling the preview endpoint:

{fallback_demo}

The preview response shows the rendered HTML and lists any variables that were substituted vs left unresolved.

Template Preview API

The preview endpoint renders a template with the given substitution data without sending an email:

{preview_template}

Response:

{
  "template_id":  "tpl_01HXWELC001",
  "rendered": {
    "subject": "Welcome to Acme Corp, Alice!",
    "html":    "<h1>Hi Alice,</h1><p>Thanks for joining Acme Corp...</p>",
    "text":    "Hi Alice,\\n\\nThanks for joining Acme Corp..."
  },
  "unresolved_vars": [],
  "recipient": "alice@example.com"
}

Version History and Revision Control

Every PUT update to a template creates a new version. Versions are immutable snapshots. You can retrieve the full version history:

{version_history}

Response:

{
  "template_id": "tpl_01HXWELC001",
  "versions": [
    { "version": 3, "created_at": "2026-07-18T11:00:00Z", "created_by": "key_01HX..." },
    { "version": 2, "created_at": "2026-07-10T09:30:00Z", "created_by": "key_01HX..." },
    { "version": 1, "created_at": "2026-06-01T08:00:00Z", "created_by": "key_01HX..." }
  ]
}

Rollback to a Previous Version

Restore any previous version as the active (current) version. A rollback creates a new version that is a copy of the target version:

{rollback_version}

After rollback, version 4 becomes the new active version and references version 2's content.

A/B Variant Support

Define multiple variants when creating the template. PostMTA randomly assigns each recipient to a variant based on the specified weight. You must provide all variables used by any variant in your template_vars at send time.

{ab_variant}
Analytics: Campaign analytics are broken down by variant_id in delivery, open, click, and bounce reports. Use this to measure which variant performs better.

Update a Template

Update any field via PUT /v1/templates/:id. This creates a new version automatically:

{update_template}

Only changed fields are required in the request body. Fields not provided retain their current values.