NevarMail

Create and reuse email templates

Write a template once, fill it with variables at send time, and keep a version history you can roll back.

NevarMail templates let you create reusable email content with variable placeholders. Templates support versioning, validation, and preview rendering.

All /api/templates* endpoints on this page require a signed-in browser session -- API keys get a 403 SESSION_ONLY error. The API-key surface is /api/v1/templates/* (see API-key access below), which uses the standard {data, requestId} v1 envelope and has additional endpoints not covered by the session routes below.

Create a template

POST /api/templates
{
  "name": "Welcome Email",
  "subject": "Welcome, {{user.name}}!",
  "htmlTemplate": "<h1>Hello {{user.name}}</h1><p>Welcome to {{company.name}}.</p>",
  "textTemplate": "Hello {{user.name}}. Welcome to {{company.name}}.",
  "variables": [
    { "name": "user.name", "type": "string", "required": true },
    { "name": "company.name", "type": "string", "required": true }
  ],
  "category": "onboarding"
}

Template fields

FieldTypeRequiredDescription
namestringYesTemplate name
subjectstringYesSubject line (supports {{variables}})
htmlTemplatestringOne of the twoHTML body (supports {{variables}})
textTemplatestringOne of the twoPlain text body (supports {{variables}})
variablesarrayNoVariable declarations
categorystringNoTemplate category for organization

A template needs at least one body. A request with neither htmlTemplate nor textTemplate is rejected with 400 VALIDATION_ERROR, because a template with no body cannot be sent.

Variable declarations

Each variable in the variables array has:

FieldTypeRequiredDescription
namestringYesVariable name (e.g., user.name)
typestringYesVariable type (string, number, etc.)
requiredbooleanNoWhether the variable must be provided
defaultanyNoDefault value if not provided

List templates

GET /api/templates

Query parameters

ParameterTypeDescription
categorystringFilter by category
isActivestring"true" or "false" to filter by status
searchstringSearch templates by name

Get a template

GET /api/templates/:id

Update a template

PUT /api/templates/:id
{
  "subject": "Welcome aboard, {{user.name}}!",
  "htmlTemplate": "<h1>Welcome aboard, {{user.name}}</h1>"
}

Updates that change at least one field automatically increment the template version number. A PATCH with no actual field changes leaves version unchanged.

Delete a template

DELETE /api/templates/:id

Returns { "deleted": true } on success.

Validate a template

Check a template for variable declaration mismatches before sending.

POST /api/templates/:id/validate
{
  "valid": true,
  "errors": [],
  "warnings": ["Variable \"foo\" is declared but never used in template"],
  "variables": ["user.name", "company.name"]
}
  • Errors: A {{variable}} is used in the template but not declared
  • Warnings: A variable is declared but never referenced in the template

Render a template

Preview a template with variable values without sending an email.

POST /api/templates/:id/render
{
  "variables": {
    "user": { "name": "Jane" },
    "company": { "name": "Acme" }
  }
}
{
  "html": "<h1>Hello Jane</h1><p>Welcome to Acme.</p>",
  "text": "Hello Jane. Welcome to Acme.",
  "subject": "Welcome, Jane!"
}

API-key access

API keys use a separate route tree, /api/v1/templates/*, scoped to templates:read / templates:write. Every response uses the v1 envelope { "data": ..., "requestId": "..." } (list endpoints also add pagination), unlike the session routes above.

MethodPathDescription
GET/api/v1/templatesPaginated list (page, perPage query params)
POST/api/v1/templatesCreate a template
GET/api/v1/templates/:idGet a template
PATCH/api/v1/templates/:idPartial update
DELETE/api/v1/templates/:idDelete a template
GET/api/v1/templates/:id/versionsRevision history, newest first -- every create, edit, provider import, or restore appends one entry
POST/api/v1/templates/:id/versions/:version/restoreRoll back to an earlier revision. The rollback is written forward as a new revision, so history stays append-only
POST/api/v1/templates/importAdopt templates that already exist at the org's connected provider. Idempotent -- re-running refreshes content on already-imported templates

Variable syntax

Templates use double-brace syntax for variable interpolation: {{variable.name}}. Variables support dot notation for nested values:

  • {{user.name}} -- resolves to the name property of the user context
  • {{company.address.city}} -- resolves to a deeply nested value

See Sending Email for how to send templated emails with variable values.

On this page