Documentation
Sign inGet started

Email templates

A template stores a reusable subject and body once, so a send only has to supply the data that changes. You author content with {{ variable }} placeholders, publish it as an immutable version, and then send it by a stable handle instead of inlining the markup on every call. Templates are workspace-owned; the full create, read, update, publish, and version contract lives in the API reference.

Creating a template

POST /v1/email/templates creates a template and its editable draft. You set the template's name, its content category (transactional or marketing), the authoring source format, and the draft's initial subject, html, and text:
Exemple de code
curl -X POST https://us1.platform.bird.com/v1/email/templates \
  -H "Authorization: Bearer bk_us1_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Welcome email",
    "alias": "welcome-email",
    "category": "transactional",
    "source": "liquid",
    "subject": "Welcome to Acme, {{ first_name }}!",
    "html": "<h1>Hi {{ first_name }} 👋</h1><p>Thanks for joining.</p>"
  }'
name must be unique in the workspace — a collision returns 409. alias is an optional workspace-unique slug (lowercase letters, numbers, and hyphens) that gives the template a stable, human-readable handle for sending; it is separate from the display name and can be changed later. category and source are fixed at creation.
source is the authoring format, and it decides how the body is rendered:
  • html — finished HTML, sent as-is.
  • handlebars — Handlebars markup, rendered at send.
  • liquid — Liquid markup. Today liquid supports variable substitution only ({{ first_name }}, {{ contact.city }}); filters, tags, and control flow (for example {{ name | upcase }} or {% if %}) are not yet supported and are rejected when you publish. Fuller Liquid support is coming.

Drafts and published versions

Every template has exactly one draft — the working copy you edit — plus any number of published versions, which are immutable and numbered (1, 2, 3, …).
  • Editing (PATCH /v1/email/templates/{id}) changes the draft in place. It's optimistic-locked: send the revision you last read, and a stale value returns 409 so you can reload rather than clobber a concurrent edit.
  • Publishing (POST /v1/email/templates/{id}/publish) snapshots the current draft into the next numbered version and makes it the live version. The draft stays editable for the next round. Publishing a draft with no subject or body is rejected with a 422.
The rule that matters for sending: a send always resolves the template's current published version, and drafts are never sent. So you can edit the draft freely while a stable version keeps going out, then publish when the change is ready. Publishing a new version changes what subsequent sends render; already-accepted sends are unaffected.
List every version — the draft plus all published versions, newest first — with GET /v1/email/templates/{id}/versions, each carrying its number, status, and publish time.

Personalizing with variables

Placeholders in the subject and body are filled at send time from the send's parameters object — the same for both templated and inline sends:
Exemple de code
{
  "template": "welcome-email",
  "parameters": { "first_name": "Jane" }
}
parameters is shared across all recipients of the send (capped at 16 KB serialized), and a placeholder with no matching key renders empty rather than erroring. Per-recipient personalization is not yet available.

Sending with a template

Set the send's template field to the template's ID (emt_…) or its alias and omit subject/html/text — the template supplies them. Both resolve the template's current published version; the alias is a readable handle you can change, while the ID is the template's permanent identity. An unknown template, or one with no published version, is rejected with a 404. The full send-side contract — including that template and inline content are mutually exclusive — is in sending with a template.

Next steps

  • Sending email — the full send payload, and how templated sends fit it
  • Categories — how a template's category drives suppression policy
  • API reference — the full template create, publish, and version contract