Skip to main content

Templates

A template is reusable content with variables. Sending with template_id keeps the copy out of your codebase, so it can be changed without a deploy.

The part worth understanding is versioning, because it is what stops an edit from changing mail that is already in flight.

Drafts and versions​

Every template has two things:

  • A draft. Mutable. This is what PATCH /v1/templates/{id} writes and what the dashboard editor saves. Nothing sends from the draft.
  • Versions. Immutable snapshots, numbered from 1. One of them is the published version, and that is what a send uses.

Editing a template is therefore safe by construction. You can rewrite the draft as often as you like and production keeps sending the published version until you say otherwise.

Create one​

curl https://api.epostix.com/v1/templates \
-H "Authorization: Bearer $EPOSTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "welcome",
"subject": "Welcome {{ name }}",
"html": "<h1>Hi {{ name }}</h1>"
}'

That creates the template and publishes version 1 in one call. Pass "publish": false to create a draft without publishing anything.

Send with it​

{
"from": "[email protected]",
"to": ["[email protected]"],
"template_id": "cabca13e-...",
"template_data": {"name": "Alex"}
}

template_id is mutually exclusive with html and text. Sending both is a validation_error, because there would be no way to know which you meant.

The response carries the template_version that was used, so a message can always be traced back to the exact content it was rendered from.

Publish a change​

# 1. edit the draft, which does not affect sending
curl -X PATCH https://api.epostix.com/v1/templates/{id} \
-H "Authorization: Bearer $EPOSTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Welcome aboard, {{ name }}</h1>"}'

# 2. freeze it as a new version and publish it
curl -X POST https://api.epostix.com/v1/templates/{id}/versions \
-H "Authorization: Bearer $EPOSTIX_API_KEY"

Pass {"publish": false} on step 2 to record the version without switching sends to it. That is how you stage content ahead of a release.

Roll back​

curl -X POST https://api.epostix.com/v1/templates/{id}/publish \
-H "Authorization: Bearer $EPOSTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"version": 1}'

Instant, and it changes nothing about the content. Versions are immutable, so rolling forward again is another publish.

Pin a version for a safe deploy​

{"template_id": "...", "template_version": 3, "template_data": {...}}

Pinning is how you decouple a content change from a code change. Your release names the version it was tested against, so publishing a new one cannot alter what that release sends.

A template with no published version returns template_render_failed rather than silently falling back to the newest one.

Check a template before you send​

curl https://api.epostix.com/v1/templates/render \
-H "Authorization: Bearer $EPOSTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template_id": "...", "data": {"name": "Alex"}}'

This renders and returns the result without sending anything. missing_variables lists the variables the template uses that have no default and were not supplied, which is the fastest way to find a {{ name }} that will render blank.

Archiving​

DELETE archives rather than destroys. Past messages stay explicable, and the template can no longer be sent with.