Skip to main content
Templates let you store your email content in Helo, then reference it by ID when you send. Instead of including the subject, HTML, and text in every request, you pass a template ID and the data to fill it with. Templates can include dynamic content. Use placeholders like {{ firstName }} to insert values from your data, and logic like conditionals and loops to vary the content for each recipient. Helo fills in the template each time you send. See Template syntax for details. Templates are a good fit when:
  • The same email is sent many times with different data (password resets, receipts, newsletters)
  • You want to update email content without deploying code changes
  • You’d like to author emails in MJML and have Helo compile them to HTML

Build templates in the dashboard

You can create and edit templates in the Templates section of your Helo dashboard. The template builder gives you everything you need to design an email without writing API requests:
  • Starter templates — Start from a pre-built template for common email scenarios, then customize it to match your brand.
  • Live preview — See the rendered email as you edit. Add sample data to fill in your variables and check how each recipient’s version will look.
  • MJML support — Write responsive emails in MJML and Helo compiles them to HTML for you on the fly, allowing you to see the output before you send.
Templates you create in the dashboard are the same as templates created via the API.

Template content

Every template has a name and a subject, plus at least one of html, mjml, or text: HTML compiled from MJML must also be within the html limit.

Authoring with MJML

If you supply mjml, Helo compiles it to HTML when you create or update the template. Invalid MJML is rejected at that point, so you find out about markup errors before you send. The compiled output is returned in the template’s html field. A template is authored either in MJML or in plain HTML — not both:
  • You can’t supply html and mjml in the same request.
  • Updating a template’s html clears its stored mjml, switching it back to plain HTML authoring.
  • Removing a template’s mjml (by setting it to null) keeps the HTML already compiled from it.

Template syntax

Templates use Liquid syntax. The subject, HTML, and text all support it. Inline templates in send requests support it too. Output a variable with double curly braces:
Use tags for logic, such as conditionals and loops:
Filters transform values:
Variable values are output as-is, without HTML escaping. If your data might contain user-supplied content, escape it in the template with the escape filter: {{ comment | escape }}.
Helo’s own placeholders, such as {{{ helo: unsubscribe }}} for unsubscribe links, are left untouched by the template engine.

Rendering limits

To keep sending fast and reliable, each render is limited in how much work it can do: These limits are far above what real emails need. A render that exceeds one fails with a templating_error.

Create a template

Example request
command-line
Response

Send with a template

To send a stored template, pass its ID in the template object along with the data to fill it with. This works for transactional messages, broadcasts, and single broadcast messages.
command-line
When you reference a template by id, don’t include subject, html, or text in the template object. If the template doesn’t exist, or isn’t available to the sending channel, the request fails with errorCode: "template_not_found". For broadcasts, the template’s content is captured when the broadcast is accepted. Editing the template afterwards doesn’t affect a broadcast that’s already been submitted.

Preview a template

You can render a template with sample data to check the output before you send. Rendering never sends or saves anything.
Renders a saved template.
Renders content you supply in the request (subject, plus html or mjml, and text) without saving it. This is useful for live previews while you edit a template. Example request
command-line
Response
By default, CSS is inlined into the rendered HTML, just as it would be for a send. Set inlineStyles to false to see the HTML without inlining.

Update a template

Only the fields you provide are changed. Omitted fields keep their existing values.
  • Set html, mjml, or text to null to remove it. Blank values are rejected.
  • An update can’t leave a template with no HTML or text content.
  • name and subject can be changed but not cleared.

Avoid overwriting concurrent edits

Every template has a version that changes on each update. To make an update conditional, pass the version from your last read of the template:
If the template was modified since that version, the update is rejected with HTTP 409. Fetch the latest template and try again. Without version, the last write wins.

Restrict a template to specific channels

By default, a template is available to every Channel in your account. To restrict it, set channelIds when you create or update the template. Only those channels can then send it. To remove the restriction, update the template with channelIds set to null or an empty array. You can also filter the template list by channel with the channelIds query parameter on GET /templates.

Manage templates via the Templates API

All template functionality is available via the API. You can:
  • List/search templates or retrieve a template’s details
  • Create, update, and delete templates
  • Render a saved template, or ad-hoc content, with sample data
Check out the Templates API reference