Email Template System — operator guide
Vetrix ships nine operator-editable email templates plus a full admin UI for customising, previewing, publishing, exporting, and monitoring them. This guide covers the everyday flows.
Contents
- Quickstart: customising the password-reset email
- Merge-field reference
- Import / export bundle format
- One-click unsubscribe flow
- Email-queue (AMQP) operator guide
- DMARC / SPF / DKIM checklist
- Admin email API (deliveries health + test send)
- Troubleshooting
Quickstart: customising the password-reset email
1. Open the template list
Navigate to /admin/email/templates. You'll see every seeded template with its current status:
| Status | Meaning |
|---|---|
Active |
A published version exists and is used on every send. |
Draft pending |
An unpublished draft sits on top of the active version. |
Unpublished |
No published version yet — outbound sends for this slug fail. |
2. Edit the body
Click Edit on the password_reset row. The editor has three
tabs:
- Subject — single-line Monaco editor.
- Plaintext — always-required canonical body.
- HTML — optional HTML body; triggers a multipart send when set.
The right rail shows the merge-field picker — clicking a leaf
inserts {{ .Path.To.Leaf }} at the cursor.
3. Lint as you type
Every edit triggers a 250 ms-debounced server-side lint. Errors
appear both as Monaco markers on the affected section and as a
summary panel above the tab strip. An undeclared-namespace
reference (e.g. {{ .Company.Name }} when Company isn't in the
slug's required_namespaces) is the most common source of lint
failures.
4. Preview before publishing
Click Preview to open the preview page. Three context sources:
- Synthetic fixture — safe default; uses canonical sample values per namespace.
- Recent delivery — grabs a real
context_snapshotfrom theemail_deliveriestable so you can debug a bug against the exact input that hit production. Picking a real delivery prompts for PII confirmation. - Hand-edited JSON — type arbitrary JSON into the right panel; warnings surface for undeclared namespaces.
Use Send test email to me to route a real send through the
Deliverer. The email lands in the configured admin's mailbox and
creates a regular email_deliveries row you can inspect.
5. Publish
Back in the editor, click Save draft. Once the draft is saved,
Publish latest draft promotes it: the previous published version
is archived, the new draft becomes published, and
email_template_definitions.active_version_id is flipped
atomically.
6. Verify
Open a private browser window → forgot-password → receive the new
email in the configured mailbox. The email_deliveries log at
/admin/email/deliveries records every send with
status, attempts, smtp_message_id, and the stored context
snapshot.
Permissions
Four RBAC permissions gate every endpoint:
| Permission | Allows |
|---|---|
email_template:read |
List + get + preview |
email_template:write |
Save drafts + import + send preview |
email_template:publish |
Publish drafts + export bundles |
email_template:delete_deliveries |
Purge email_deliveries rows |
Instance admins hold all four. Org owners hold read + write but not publish or delete_deliveries.
Related admin surfaces
- /admin/email/deliveries — audit log with retry + delete.
- /admin/email/export — signed bundle export.
- /admin/email/import — bundle import (dry-run + apply).
- /admin/email/metrics — per-slug performance data.