Skip to content

Sending Email from the CMS

The admin has an Email page for sending a message to any recipient from the CMS. It uses the deployment’s configured provider, so email must be configured first. Without a provider, sending returns a 400.

  • Who: the Editor role and above.
  • Body: a rich-text editor. A plain-text version is generated automatically.
  • From: the deployment’s sender, or the sender name and address an Admin sets on Profile → Email sender (see Your account and security).
  • Reply-To: defaults to that configured sender address, otherwise your own address. You can set it explicitly per message.
  • Attachments: PDF, DOCX or image files (verified by their bytes), and items from the Media Library.
  • Design HTML (Admin and Owner only): paste a finished HTML email template, for example one exported from a design tool. Its table layout, inline styles and https images are kept. Scripts, forms, <style> blocks, relative links and data: images are removed, and the page shows a sandboxed preview of exactly what will be sent.
  • Limit: 10 sends per 60 seconds per staff user (keyed by user, not IP). This also covers replies to form submissions.

Email subjects containing line breaks are rejected.

For replying to a specific form submission, see Forms.

Email Templates (Admin and Owner only, linked from the Email page) controls the subject, HTML and plain-text for the CMS’s own transactional emails — email verification and password reset. Nothing is hardcoded: every deployment starts with a real, ready-to-send default and can customize it without touching code.

The open email is kept in the page address, so a reload lands on the same one, and leaving with unsaved edits asks first. Editing its custom HTML is offered only when Developer experience is on in Settings → API (there is no separate switch on this page); an email already saved as custom HTML keeps its toggle either way. Branding overrides (logo, color, footer) are edited as a draft and saved together with Save branding.

There are four templates:

Template Sent when
Email verification (website account) A visitor registers on your public site (a Commerce customer, a form-gated area, or any other website account)
Email verification (CMS staff) A new or existing staff account needs to verify their email before signing in to the admin
Password reset Anyone — staff or website account — requests a password reset
Request update (website account) Staff change the stage of a submission that belongs to a website account, on a form with an Account page URL. Variables include form.name, stage and submissionUrl. See Forms

For each template you can edit:

  • Subject and Body HTML — plain HTML with {{variable}} placeholders (see below). There’s no drag-and-drop builder; edit the HTML directly, with a live preview alongside it.
  • Plain-text version — optional. Left off, it’s generated automatically from the HTML on every send.
  • Enabled — turning a template off doesn’t stop the email from sending; it falls back to the built-in default content instead. There’s no way to actually disable a verification or reset email, since authentication depends on it.

Every template can be restored to its default at any time (this resets the subject/HTML/plain-text but leaves Enabled as you set it) and supports Send test email, which delivers the current saved template to an address you choose using sample data — never a real user’s verification or reset link.

A {{variable}} is a plain, safe substitution — never code, never an expression. An unrecognized {{typo}} is left as literal text in the output, which is how a mistake shows up in the preview before you save. Every value is HTML-escaped, so a user’s own name or a configured site name can never inject markup into the email.

Each template’s editor lists exactly which variables it supports. Every template also gets these automatically:

  • site.name, site.url, support.email
  • design.brandColor, design.pageBackground, design.contentBackground, design.textColor, design.mutedTextColor, design.buttonTextColor, design.borderColor, design.fontStack, design.contentWidth, design.footerText

The design.* variables come from an emailBranding module (the same Structured Settings mechanism as Contact/Social/SEO), so changing a color there updates every template at once instead of editing each one’s HTML by hand. Unset, every deployment gets a built-in dark/indigo default look. There’s no dedicated settings screen for this yet — set PUT /api/v1/admin/structured-settings/emailBranding directly, or override a color inline in a specific template’s own HTML if you only want to change one.

A template that’s missing, disabled, or fails to render for any reason never blocks the actual email — verification and password reset always fall back to the built-in default content automatically. The failure is logged (visible via wrangler tail), so a broken save is never a silent, invisible outage.