Skip to main content
BeginnerEmail Engine

Email Templates

Build, version, and bind reusable email templates to sequence steps in NimbusOS, with variable substitution, schema markup injection, and A/B variant support.

9 min read
Updated April 23, 2026
1,950 words

A template in NimbusOS is not decoupled from the sequence it feeds. Every SequenceStep binds to an EmailTemplate version, which means edits to a template become step-scoped changes you can version, A/B test, and roll back without touching the marketplace copy. This article covers the template model, the variable system, the A/B variant workflow, and the rules for when a template edit takes effect on in-flight sends.

The Template Model

A template has three parts: a subject line, a body, and a variable schema. The subject and body are both text with variable placeholders. The variable schema is a list of named placeholders the template expects to resolve at render time.

Templates live in two places. The EmailTemplate table holds workspace scoped templates you create. The template marketplace holds pre built templates you can copy into your workspace. Marketplace templates are read only; copying creates an editable EmailTemplate under your workspace.

Every template has a version integer. Every edit increments the version. Sequence steps bind to a specific version, so a step rendered mid-sequence will continue to use the version it was created with until you explicitly upgrade it.

Variables

Variables use the double curly brace syntax, {{first_name}}. The render engine resolves them from three sources in priority order.

Contact fields. {{first_name}}, {{last_name}}, {{email}}, {{company}}, {{title}}, {{seniority}}, plus any custom fields defined on your workspace. These resolve from the Contact row at render time.

Personalization fields. {{personalized_first_line}}, {{compliment}}, {{hook}}. These resolve from the PersonalizedLine record generated by the hyper personalization engine, if one exists for the contact. If no PersonalizedLine exists, the field resolves to an empty string and a fallback clause in the template kicks in.

Campaign fields. {{sender_name}}, {{sender_company}}, {{unsubscribe_link}}. These resolve from the campaign and sending account context.

Variables can be conditional. The syntax {{#if personalized_first_line}}...{{/if}} renders the block only if the variable resolves. Use this to fall back gracefully when personalization is missing.

Writing a Template

A minimal cold outreach template has three parts: a subject, a greeting, and a call to action.

Subject: {{first_name}}, question about {{company}}

Hi {{first_name}},

{{#if personalized_first_line}}{{personalized_first_line}}{{/if}}

The reason I'm reaching out: we help RevOps teams at companies like yours stand up measurable outbound in 30 days.

If relevant, open to a 15-minute call next week?

Best,
{{sender_name}}

Three points worth calling out.

The subject uses {{first_name}} and {{company}}. Both are safe to use because almost every import includes them. Avoid subjects that depend on custom fields which may be missing; a blank subject is a spam signal.

The personalized first line uses the conditional block. If the hyper personalization engine has not yet produced a PersonalizedLine for the contact, the line is simply omitted rather than rendered as an empty line break.

The call to action is a single ask. NimbusOS copy standards enforce one ask per email. Multiple asks crater reply rates.

Binding to Sequence Steps

You bind a template to a step from the sequence builder. Click a step node in the visual editor and pick a template from the dropdown. The binding writes the template ID and the template version to the step.

When a contact enrolls in the sequence and reaches that step, the render pass uses the template version that was bound at enrollment time, not the current version. This matters: if you edit a template halfway through a campaign, contacts who enrolled before the edit continue to see the old version unless you explicitly upgrade the step binding.

To upgrade a step to the latest version, click the step and confirm the upgrade. The upgrade applies to all new enrollments from that point forward. Existing enrollments that have not yet reached the step also pick up the new version.

A/B Variants

A template can have multiple variants. The first variant is the canonical version. Additional variants are alternative subjects or bodies you want to test.

Create a variant from the template detail page. Each variant has its own content_version and shows up as a choice in the A/B testing interface. When you configure an ABTest for a campaign, you pick the variants to include.

Under the hood, ABTestVariant holds traffic allocation as a percentage. The sequence engine routes sends to each variant in proportion. The ABTestInsight model computes statistical significance and recommends a winner.

You do not need a full A/B test to use multiple variants. You can simply pick a different variant per campaign. This is how agencies use one template across several sub client campaigns with slight tone adjustments per client.

Schema Markup Injection

When a template is saved, NimbusOS runs a schema markup generation pass through sequences/schema_markup_service.py. The output is a JSON-LD snippet that the email engine injects into the body at send time for AI inbox placement scoring.

The snippet identifies the sender organization, the product, and the intent of the email. AI inbox filters at Gmail and Microsoft increasingly use these signals. Injection is transparent to the user; you do not author the JSON-LD. It is generated from your workspace's GTMFoundation, the campaign type, and the template content.

Template Marketplace

The marketplace holds pre built templates organized by category: cold outreach openers, follow ups, response handlers, case study reveals, event follow ups. Each template carries a category tag, a use case description, and success rate data from anonymized platform wide campaigns.

To use a marketplace template, click Copy to Workspace. The platform creates a workspace scoped EmailTemplate you can edit. Edits do not propagate back to the marketplace; the original stays pristine.

Marketplace templates are curated by the NimbusOS team. They follow the copy standards, the one ask rule, and the deliverability practices. If a template in the marketplace surfaces an issue over time (consistent low reply rate across many campaigns), it is flagged for review and may be removed.

Plain Text vs HTML

NimbusOS supports both. The default is plain text because plain text outperforms HTML on B2B cold outreach for inbox placement. HTML triggers more spam filters and signals a marketing email to ISPs.

If you need HTML, you write the HTML directly in the template body. The platform does not provide a visual editor because visual editors encourage the kind of branded markup that hurts cold outreach. Image embeds should be minimized; where used, they should have alt text and be hosted on a reputable CDN.

For transactional or nurture templates where branding matters, HTML is the right choice. For cold outreach, keep it text.

The Copy Standards Filter

Every saved template passes through the Copy Standards filter. The filter blocks banned phrases (the AI filler list), em dashes, exclamation points in subject lines, subject lines over 8 words, and multiple asks in one body.

The filter fires at save time, not at send time. You see the error inline with the specific phrase or issue highlighted. You cannot save a template that fails the filter. This is deliberate; the filter is how the platform keeps the quality bar consistent across a large team.

Edit Propagation Rules

Three rules govern how edits affect in-flight sends.

New enrollments pick up new versions. When you upgrade a step to a new template version, contacts who enroll after the upgrade see the new version.

Existing enrollments that have not reached the step pick up new versions. If a contact is in step 1 and you edit step 3's template, the contact sees the new step 3 when they reach it.

Existing enrollments that already rendered the step do not change. If a contact already received step 2 with version 3 of the template, editing to version 4 does not cause a resend. The contact is past that step.

Frequently Asked Questions

Can I preview a template with real contact data?

Yes. The template editor has a preview mode that resolves variables against a selected contact. This is the fastest way to catch a missing custom field or an unresolved conditional block.

Is there a character limit on subject or body?

Subject is hard capped at 78 characters (the RFC recommendation). Body has no hard limit but the copy filter flags any body over 200 words as likely to underperform.

What happens when a variable is missing?

By default, missing variables render as empty strings. You can configure fallback values per variable on the template detail page. For example, {{first_name}} can fall back to "there" so the template reads "Hi there," when the first name is blank.

Can I import a template from another tool?

Yes. Paste the subject and body into a new template. The variable syntax is standard Jinja-style double curly braces. If your source tool uses a different syntax, a simple find and replace converts.

Is there versioning history I can browse?

Yes. The template detail page shows every version with its save timestamp, the author, and a diff against the previous version. You can roll back to any prior version with one click.

Can I share a template across workspaces?

Not directly. Each template is workspace scoped. Agencies with multiple workspaces copy the template into each. For agencies on the managed services plan, the NimbusOS team can publish a template to a specific set of workspaces.

After building templates, the most useful next pages are Personalization Variables for the full variable system, A/B Testing for how to run template experiments, and Sequence Builder for binding templates to multi step flows.

Related articles

Still stuck?

Our team answers every support ticket. If the answer is not in the docs, open a ticket and we will write the missing page.