Email Builder: design, personalize, and send
Mass ships a full drag-and-drop email builder backed by a structured schema, with AI woven into the writing, a sequence drafter that turns a goal into a multi-step drip, merge-field personalization, A/B testing, and a send pipeline that tracks every open and click back into the CRM. This guide explains how an email goes from blank canvas to a tracked, personalized send.
18 min read · The complete email builder guide
The drag-and-drop canvas
Build an email by stacking structure and content blocks — no HTML required.
The editor is a visual canvas with an element panel on one side and a properties panel on the other. You assemble an email from two families of blocks: structure blocks that lay out the page, and content blocks that hold what your reader sees. Drag a block in, select it to edit its content and style, and the canvas renders exactly what will be sent.
Structure comes from sections, rows, and columns — a section is a full-width container, a row is a horizontal band, and a column splits a row so you can place content side by side. Content blocks live inside that structure: headings, text, images (with links), buttons, dividers, and spacers, each with its own style controls in the properties panel.
- Structure blocks — section (full-width container), row (horizontal band), and column (vertical split) define the layout.
- Content blocks — heading, text, image, button, divider, and spacer are the pieces a reader actually sees.
- Direct manipulation — drag to place, click to select, and edit content and style in the properties panel — the canvas is WYSIWYG.
- Templates to start — pre-built templates (welcome, sales, newsletter, transactional, announcement, event, re-engagement) seed a design so you're never staring at a blank page.
EmailSchema: the structured source of truth
Every design is a versioned JSON document, not a blob of HTML.
Behind the canvas, an email is stored as an EmailSchema — a versioned JSON document with meta (title, preview text), settings (background color, content width, font family and size, text and link colors, an unsubscribe toggle), and an ordered list of sections, each holding its elements. Because the design is structured data, the renderer can produce byte-stable HTML from it, and the same schema can be re-opened, AI-edited, or templated without ever round-tripping through raw markup.
Campaign steps can carry either a legacy Markdown body or a modern EmailSchema body, discriminated by a body_format field so older rows keep sending unchanged. A cached HTML field lets a step render fast, and the schema is what the embedded editor opens when you want to make a visual edit to a step inside a sequence.
- Versioned JSON — meta + settings + sections[] with elements — a structured document, not opaque HTML.
- Byte-stable render — the renderer turns the schema into deterministic HTML, so previews match sends.
- Markdown or schema — campaign steps carry body_format so legacy Markdown and modern schema bodies coexist.
- Re-openable — the same schema powers the canvas, the embedded step editor, AI edits, and templates.
AI writing: /write, /subject, /improve
AI sits inside the editor as slash commands scoped to what you've selected.
The email builder has a built-in AI chat with slash commands that act on the canvas. /write generates text content for the selected element, /subject generates a compelling subject line, and /improve enhances and polishes existing copy. Each command is element-aware — it knows which block you've selected and the surrounding context — and is gated behind a feature flag (email_ai_edit_text, email_ai_generate_subject) so capabilities can be rolled out per tenant.
You choose the model per request from a range spanning fast, low-cost options to frontier models; the credit cost scales with the model and the action. AI image generation is available too: the copywriter can embed [IMAGE: description] placeholders that a companion image route fans out into real generated images and swaps back into the body.
- /write — generates text for the selected element from a topic or instructions.
- /subject — generates a subject line from an angle or topic.
- /improve — polishes existing content with a specific focus.
- Model & cost aware — pick a model per request; credits scale with the model multiplier and the action's base cost.
- Inline images — [IMAGE: ...] placeholders fan out to generated images and are swapped into the body.
AI drip sequences with an approval gate
Turn a goal into a multi-step sequence — but AI copy never auto-sends.
Beyond single emails, the builder can draft an entire drip sequence. You give it a high-level goal, a trigger, an audience, and a step count, and it returns a list of fully-formed steps — each with a subject, preview text, a step kind (welcome, value, story, cta, social proof, reminder), a delay, and a complete EmailSchema body. The model only writes the copy; the system wraps that copy into a deterministic schema so each step opens cleanly in the editor.
Every AI-generated step is marked as a draft. This is a hard policy: the sending worker refuses to dispatch a draft step until an admin clears the flag. AI can accelerate the writing, but a human approves before a single subscriber receives it. A per-email archetype catalog (welcome, nurture-story, value-bomb, social-proof, objection-crusher, sales-direct, urgency-scarcity, cart-abandon, re-engage, launch-announcement) gives each step a clear strategic job.
- Goal → steps — a goal, trigger, audience, and step count become a list of subject/preview/body steps with delays.
- Copy only, schema wrapped — the model writes copy; the system wraps it into a deterministic EmailSchema.
- ai_draft gate — every AI step is a draft the worker won't send until an admin approves it — AI copy never auto-sends.
- Archetypes — a per-email archetype catalog gives each step a defined intent, framework, and tone.
Personalization & merge fields
Drop a contact's data into any block with merge tags.
Emails personalize through merge tags — tokens like {{contact.first_name}} that a variable injector resolves against each recipient at send time. A merge-tag dropdown in the editor lets you insert the right token without memorizing names, so a single design greets every reader by name and can reflect any field you capture. The same injector powers subject lines and preview text, not just the body.
Links can be wrapped with UTM parameters via the built-in UTM builder and managed through a link manager, so every click is attributable in your analytics. Because personalization is resolved at send, one campaign serves a fully personalized message to each contact from the same schema.
- Merge tags — {{contact.*}} tokens resolve per recipient in the body, subject, and preview text.
- Merge-tag dropdown — insert the correct token from the editor without memorizing field names.
- UTM builder & link manager — tag and manage outbound links so every click is attributable.
- One design, many readers — personalization resolves at send, so a single schema serves a tailored email to each contact.
A/B testing
Define variants and let the winner reach the rest of your list.
A campaign can be flagged as an A/B test, in which case it carries multiple variants instead of a single body. You define the variants you want to compare — most commonly subject lines, but the variant model is part of the schema so the differences travel with the campaign — and the send pipeline splits delivery across them.
Because tracking is wired into every send, opens and clicks per variant are what determine performance, and the winning variant can be sent to the remainder of the audience. A/B testing is exposed through a dedicated panel in the editor so you set it up in the same place you build the email.
- Variant-aware campaigns — an is_ab_test flag turns a campaign into a multi-variant test instead of a single body.
- Compare what matters — subject lines and body variants travel with the campaign as structured data.
- Winner to the rest — per-variant opens and clicks decide the winner, which can be sent to the remaining audience.
- In-editor panel — set tests up from a dedicated A/B panel beside the canvas.
Scheduling & the send pipeline
Render, personalize, track, then deliver — in that order.
When a campaign sends, each recipient's email goes through a deterministic pipeline: the EmailSchema is rendered to HTML (with a plain-text alternative generated alongside), merge fields are injected for that recipient, full tracking is added to the markup, and the message is handed to the send service for delivery. You can send immediately or schedule for later through the schedule panel.
Sequence steps run on the same pipeline but on a delay clock: the first step's delay is measured from enrollment, and each later step's delay is measured from the previous step's send time. The approval gate sits in this worker — a draft step pauses the sequence until it's cleared.
- Deterministic pipeline — render → inject merge fields → add tracking → send, with a plain-text alternative generated for every email.
- Send now or schedule — dispatch immediately or pick a time from the schedule panel.
- Sequence timing — step 0's delay is from enrollment; later steps are relative to the previous send.
- Approval in the worker — the worker refuses to dispatch ai_draft steps, so AI sequences wait for human sign-off.
Tracking that feeds the CRM
Opens and clicks aren't just metrics — they become contact history.
Every sent email carries tracking, so opens and clicks are recorded per message and per recipient. Those events don't sit in an isolated email dashboard — they flow into the CRM as part of each contact's message history, alongside pixel events and other touches, which is what powers the timeline and the next-best-action context the CRM's AI reasons over.
That closed loop is the point: an email send becomes engagement data, engagement data becomes contact intelligence, and contact intelligence drives the next campaign or automation. The email builder is one node in the same data graph as the pixel, the CRM, and automations.
- Per-message tracking — opens and clicks are recorded for each recipient on each send.
- Into the timeline — email events join pixel and message history on the contact record.
- Feeds AI — engagement history is part of the context the CRM's next-best-action AI reads.
- One graph — email, pixel, CRM, and automations share the same contact data, not separate silos.