Templates
Save reusable, branded email once and render it at send time. Keeps your markup out of your application code, and lets you change wording without a deploy.
Requires the templates scope.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/templates | create a template |
GET | /v1/templates | list your templates |
GET | /v1/templates/:id | fetch one |
PUT | /v1/templates/:id | replace one |
DELETE | /v1/templates/:id | delete one |
Template ids
A templateId is a lowercase slug: letters, digits, dots, underscores and hyphens, up to 64 characters. welcome, order-receipt and password.reset are all valid. Choose ids you will still understand in a year — they appear in your sending code.
Locales
A template's subject, html and text are maps of locale to string, not plain strings:
{
"templateId": "welcome",
"subject": { "en": "Welcome to {{business}}", "fr": "Bienvenue chez {{business}}" },
"html": { "en": "<p>Hello {{name}}.</p>", "fr": "<p>Bonjour {{name}}.</p>" },
"text": { "en": "Hello {{name}}.", "fr": "Bonjour {{name}}." }
}At send time, locale on the send request picks the language. Omit it and en is used.
A regional tag falls back to its base language: en-AU uses the en entry when there is no en-AU. If neither exists, the template's default locale is used — so a missing translation sends the wrong language, never a blank email.
Variables
{{variable}} placeholders are filled from the data object on the send:
{
"from": "Your Business <hello@yourbusiness.com.au>",
"to": "customer@example.com",
"subject": "ignored when the template has one",
"templateId": "welcome",
"category": "transactional",
"data": { "name": "Alex", "business": "Your Business" }
}Rendering happens on our side. The values in data are never written to our logs — treat that as the reason you can safely put a customer's name in it.
Variable names may contain letters, digits and underscores only — {{first_name}} works, {{first-name}} and {{user.name}} do not, and are left in the email as literal text. Flatten nested data before you send it.
Values are converted like this:
data value | Renders as |
|---|---|
| a string | itself |
a finite number, true, false | its text form |
missing key, null, an object, an array | empty |
So a variable with no matching key renders empty rather than printing {{name}} at your customer, and an object never renders as [object Object]. Check your data keys when an email arrives with a gap where a name should be.
Values in html are HTML-escaped. A customer whose name is <script>alert(1)</script> renders as text, not as markup — you cannot create an injection by passing user input through data. Subject lines are not HTML-escaped, because a subject is not HTML; control characters and line separators are stripped from them instead, so a value can never forge an extra header.
Plain text
Provide text as well as html. Some clients prefer it, some recipients require it, and a missing plain-text part is a spam signal. It is the cheapest deliverability improvement available to you.