ZevSend Docs
Sign up

Getting Started

Templates

Pre-approved message content with declared variables. Optional for email; required for SMS and WhatsApp.

A template is pre-approved message content with declared variables. You reference it by id (tpl_…) when you send; we render the body against the variables you pass.

Templates aren’t required for every channel:

ChannelTemplatesWhy
EmailOptionalYou can also send a raw HTML or text body directly.
SMSRequiredCarrier networks require pre-registered content for transactional traffic.
WhatsAppRequiredWhatsApp’s network only delivers approved templates outside the 24h window.

When you do use a template, you get three things that direct sends can’t offer:

  • Editable copy. Your support team can tweak wording in the dashboard without a code deploy.
  • Server-injected brand. Variables like {{brand.name}} and {{brand.support_email}} are filled in from your verified domain at send time. A leaked API key can’t impersonate another brand on your team.
  • Variable validation. Required keys, type checks, and missing-variable errors run before the message is dispatched.

What’s in a template

Each template has:

  • A name for humans (e.g. “Order confirmation”).
  • A channel — email, sms, or whatsapp.
  • A content body with {{handlebars}} placeholders.
  • A variable manifest — the declared list of variables the template accepts, with type and required/optional metadata.

When you call POST /v1/{channel}, we validate the variables you pass against the manifest and reject mismatches before the send leaves the API.

Authoring templates

Templates are authored in the dashboard under Templates → New template. Pick the channel, write the body, and declare variables as you go. The dashboard previews the rendered output side-by-side using sample values.

For email, the body is HTML with a plain-text fallback. For SMS, the body is plain text capped at 1600 characters once rendered. For WhatsApp, the body matches a pre-registered template body on the WhatsApp network — only the variable values you pass travel over the wire; the body itself is rendered by the provider from the pre-registered version.

Variable manifest

Each declared variable has:

FieldMeaning
keyThe placeholder name, used as {{customer.key}}.
labelA human label shown in the dashboard preview.
requiredWhen true, omitting it returns 422 missing_variable.
typeOne of string, number, email, phone, url, code.

The order of variables matters for WhatsApp: it’s the order of the positional placeholders ({{1}}, {{2}}, …) in the pre-registered template body. The dashboard makes the ordering visible so you can’t get it wrong.

Send-time substitution

Variables you send live in the customer.* namespace and the brand fields live in brand.*. So a template body like:

Hi {{customer.first_name}}, your {{brand.name}} verification
code is {{customer.code}}. Reply STOP to opt out.
For help, email {{brand.support_email}}.

With this request:

{
  "to": "+2348012345678",
  "template_id": "tpl_…",
  "variables": {
    "first_name": "Ada",
    "code": "847291"
  }
}

Renders as:

Hi Ada, your Acme verification code is 847291.
Reply STOP to opt out. For help, email support@acme.com.

You never pass brand.* values from your code — they’re filled in from your domain’s brand profile on the server side.

Re-using templates across teams

Templates are scoped to your team. If you have a staging team and a production team, author the templates in each one (you can copy-paste). Keeping them separate means a draft template can’t accidentally go live before you mean it to.

Updated at, Thursday, October 1, 2026