Templates

Named message bodies, rendered with variables at send time.

A template is a saved html and/or text body with a name and a subject. You render it by referencing its id when sending, rather than by copying the markup into every request.

POST/templatesAPI key or session

Creating one

FieldTypeNotes
namestringRequired. How you refer to it in the dashboard.
subjectstringRequired. Used as the subject when the send omits one.
htmlstringHTML body. At least one of html or text is required.
textstringPlain-text body.

Variables

Placeholders are written {{name}} — two braces, the variable name, two braces — and are replaced with the values you pass in variables at send time.

curl -X POST https://api.rovela.dev/templates \
  -H "Authorization: Bearer <session token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Welcome",
    "subject": "Welcome aboard, {{name}}",
    "html": "<h1>Hi {{name}}</h1><p>Your plan is {{plan}}.</p>"
  }'
Substitution is textual and exact. A variable you do not pass is left in the output as the literal {{name}} rather than being replaced with an empty string — so a message that reads "Hi {{name}}" is a missing key in your variables object, not a template problem. There is no conditional or looping syntax: for anything that needs logic, render the HTML on your side and send it as html.

Sending with a template

curl -X POST https://api.rovela.dev/emails \
  -H "Authorization: Bearer re_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@yourdomain.com>",
    "to": "alice@example.com",
    "template": {
      "id": "<template_uuid>",
      "variables": {"name": "Alice", "plan": "Pro"}
    }
  }'

template is mutually exclusive with html and text. The template's subject is used unless the send supplies its own.

Templates cannot be used through POST /emails/batch. That endpoint rejects template outright rather than ignoring it — a batch entry that silently lost its body would send an empty message, and you would find out from a recipient.

Draft and published

Templates have a published state, and publishing is a separate call:

POST/templates/:id/publishAPI key or session

Publishing is idempotent — publishing an already-published template leaves the original timestamp alone, so it records when the template first went live rather than when someone last clicked the button.

Managing templates

  • GET /templates — list, with ids for use in sends.
  • GET /templates/:id — one template, including its body and variables.
  • PATCH /templates/:id — update name, subject, html or text. Any field you omit is left unchanged.
  • POST /templates/:id/duplicate — copy, for when you want a variant rather than an edit to a template that is already sending.
  • DELETE /templates/:id — remove it. Messages already sent keep their rendered content; a send still referencing the id afterwards fails.

These take a session token rather than an API key, like the other dashboard endpoints.

A note on editing a live template

Editing a template changes what the next send renders. Anything already queued or scheduled keeps the values it was rendered with, so an edit cannot retroactively change a message that has already gone out — but a scheduled send that has not fired yet will use the new body. Duplicate first if that matters.