Appearance
Templates
Templates define the message content for each event and channel. Use Handlebars-style syntax (with a few Sendivent helpers) for dynamic content.
Variables
Use {{...}} to insert values.
| You write | Gets sent |
|---|---|
Hi {{contact.name}} | Hi Alice |
Order #{{order_id}} | Order #12345 |
Data sources
Contact data — from the to field (recipient info):
{{contact.name}},{{contact.email}}{{contact.firstName}},{{contact.lastName}}(auto-extracted fromname){{contact.meta.plan}}(custom fields)
Payload data — from the payload field (notification-specific):
{{order_id}},{{reset_link}},{{amount}}
Example request:
bash
curl -X POST https://api.sendivent.com/v1/send/order-shipped \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {
"email": "alice@example.com",
"name": "Alice Johnson"
},
"payload": {
"order_id": "12345",
"tracking_url": "https://track.example.com/12345"
}
}'Fallback values
Use the pipe | to provide a fallback when a value is missing:
| Template | Has name | No name |
|---|---|---|
Hi {{contact.name}} | Hi Alice | Hi |
Hi {{contact.name | "Guest"}} | Hi Alice | Hi Guest |
Hi {{contact.name | app.domain}} | Hi Alice | Hi example.com |
Quoted literals: Use quotes to force a literal fallback value ("Guest").
Variable fallbacks: Unquoted fallbacks try variable resolution first, then use as literal if not found.
Always add fallbacks for optional fields to avoid awkward blank spaces.
Conditionals
Show content only when a value exists:
Loops
Render lists from payload arrays:
Accessing variables inside loops
Inside {{#each}} blocks, the context changes to the current item. System variables like contact, app, cdn, sender, and platform work automatically:
For custom payload variables, use @root to access the root context:
Helpers
Sendivent provides helpers via handlebars-helpers:
Comparison
| Helper | Example | Result |
|---|---|---|
| Compare | {{#compare credits ">" 100}}...{{/compare}} | Content if true |
| Greater than | {{#if (gt credits 100)}}...{{/if}} | Content if true |
| Less than | {{#if (lt age 21)}}...{{/if}} | Content if true |
| Equal | {{#if (eq status "active")}}...{{/if}} | Content if true |
Compare operators: ==, ===, !=, !==, <, <=, >, >=, typeof
String
| Helper | Example | Result |
|---|---|---|
| Uppercase | {{uppercase name}} | ALICE |
| Lowercase | {{lowercase name}} | john doe |
| Capitalize | {{capitalize status}} | Active |
Date
| Helper | Example | Result |
|---|---|---|
| ISO format | {{date created_at "YYYY-MM-DD"}} | 2024-12-17 |
| Friendly | {{date created_at "MMM D, YYYY"}} | Dec 17, 2024 |
| With time | {{date created_at "YYYY-MM-DD HH:mm"}} | 2024-12-17 14:30 |
Fallback
| Helper | Example | Result |
|---|---|---|
| Quoted literal | {{contact.name | "Guest"}} | Alice or "Guest" |
| Variable fallback | {{contact.name | app.domain}} | Alice or app.domain value |
| Default helper | {{default contact.name "User"}} | Alice or "User" |
Multi-language templates
Create language variants in the dashboard. Request a specific language:
bash
curl -X POST https://api.sendivent.com/v1/send/welcome \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "anders@example.com", "language": "sv" }'Fallback: If the requested language doesn't exist, Sendivent uses the application's default language.
Common pitfalls
- Blank variables — your template references fields not sent in
toorpayload - Wrong nesting — custom contact fields go under
contact.meta.* - Missing fallback — add a fallback for optional fields (see Fallback values above)