Getting Started
Variables
How the customer and brand variable namespaces work.
Templates use Handlebars-style
placeholders. Each placeholder belongs to one of two namespaces:
customer.* (values from your API request) and brand.* (values
filled in by us from the verified domain you send from).
customer.* — values from your API call
Anything you pass in variables lives under customer.*. The
template references them as {{customer.<key>}}. The variable
manifest on the template controls which keys are required and
what types they accept.
{
"to": "ada@example.com",
"template_id": "tpl_…",
"variables": {
"first_name": "Ada",
"amount": "₦12,500"
}
}
Inside the template:
Hi {{customer.first_name}}, your transfer of
{{customer.amount}} was successful.
If you pass a key the template doesn’t declare, the API returns
422 unknown_variable. If you skip a required key, it returns
422 missing_variable. Both errors name the offending key in
extensions.param so your client can highlight the field.
brand.* — values from your verified domain
The brand namespace is never passed in the API request.
We fill it in on the server side using the brand profile of the
verified domain the send is using. The keys are fixed:
| Key | Source |
|---|---|
brand.name | Brand name on the domain profile. |
brand.support_email | Support email on the domain profile. |
brand.support_url | Support URL on the domain profile. |
brand.legal_name | Legal name on the domain profile. |
Use them anywhere you would have hardcoded your brand in the template body:
For help, contact {{brand.support_email}} or
visit {{brand.support_url}}.
This is why a leaked API key cannot impersonate someone else’s
brand: the API key authenticates a team, but the brand.*
values come from a domain that team owns. If you’ve pinned the
API key to one specific domain, even another domain on the same
team is out of reach.
Sandbox renders
In sandbox mode, the team isn’t tied to a verified domain yet,
so brand.* resolves to a sandbox stub:
| Key | Sandbox value |
|---|---|
brand.name | Your team name + ” (sandbox)“ |
brand.support_email | support@sandbox.zevsend.com |
brand.support_url | https://sandbox.zevsend.com |
brand.legal_name | Your team name |
It’s there so previews render and template wording is realistic during development — your live messages always use your real brand profile.
Variable types
The variable manifest accepts these types:
| Type | What it validates |
|---|---|
string | Any value, coerced to string. |
number | A numeric value or a string that parses as one. |
email | Looks like an email address. |
phone | A phone number, normalised to E.164 where possible. |
url | A valid http(s) URL. |
code | A short alphanumeric token. Useful for OTPs. |
Type validation runs before we hand the message off, so a
malformed value returns 422 invalid_variable and the message
is never charged.
Updated at, Thursday, October 1, 2026