Templates
Server-side rendered email templates with immutable versions and {{ variable }} substitution.
Templates are stored, versioned, and rendered server-side: your app sends an alias plus a model, emitd produces the HTML. The active version is immutable — promote a new version when you want to change what's live.
Manage templates in the console or through the API:
/v1/templates.
Sending with a template
{
"from": "you@yourdomain.com",
"to": ["ada@lovelace.io"],
"template_alias": "receipt",
"template_model": { "name": "Ada", "total": "$48.00" }
}When template_alias is set, the template supplies the subject and body
before validation runs — you don't need subject/html_body in the request
(an unknown alias fails with template_not_found).
Substitution syntax
Templates use {{ variable }} tokens filled from the top-level keys of
template_model:
<h1>Hi {{ name }},</h1>
<p>Your total is {{ total }}.</p>- Logic-free by design — no conditionals or loops; compose the model in your code.
- Top-level keys only —
{{ name }}readsmodel.name. Flatten nested data into the model before sending. - HTML-escaped in HTML bodies — interpolated values can't inject markup.
subjectandtext_bodyrender raw. - Unknown variables render as empty strings, so a missing key silently
blanks rather than leaking
{{ key }}into the mail.
Versions
| Endpoint | Purpose |
|---|---|
POST /v1/templates | Create the template shell (alias + name) |
GET /v1/templates | List all templates, newest first (not paginated) |
GET /v1/templates/{alias} | Fetch the template with every version |
POST /v1/templates/{alias}/versions | Publish a new immutable version (subject + body; activate: true by default) |
Rendering always uses the single active version — publishing with
activate (default true) deactivates the others first. Conflicting creates
return alias_exists (409); a shell without content returns
alias_and_name_required (422).
Templates vs. inline bodies
Inline html_body wins for one-off transactional mail. Templates shine
when marketing or support edits content without a deploy, or when the same
skeleton serves many sends.