Templates
Templates centralise reusable notification content. They are versioned, can be drafted or published, and are snapshotted into every notification that uses them.
Create a template#
POST /v1/templates
{
"name": "Order dispatched",
"status": "published",
"content": {
"title": "Your order is on its way",
"body": "Hi {{ properties.first_name }}, order {{ template.order_id }} has shipped.",
"click_url": "myapp://orders/{{ template.order_id }}",
"data": {
"screen": "order_tracking"
}
}
}
name is required. content.title and content.body must be non-empty strings. Initial status may be draft or published and defaults to draft.
Placeholder sources#
Template content can use recipient and send-time values:
{{ external_user_id }}— the recipient's external ID;{{ tags.plan }}— a user tag;{{ properties.first_name }}— a user property; and{{ template.order_id }}— a value from the notification'stemplate_dataobject.
Keep a sensible fallback in the surrounding copy when a recipient value might be absent. Do not put confidential values in notification bodies: lock-screen content can be visible without unlocking a device.
Send from a template#
POST /v1/notifications
Idempotency-Key: order-7815-dispatched-v1
{
"template_id": "7e87f5f0-8dfc-4b92-aa10-1be72dcce1f1",
"target": {"type": "user", "external_user_id": "customer_123"},
"template_data": {"order_id": "7815"},
"interruption_level": "time_sensitive",
"priority": "transactional"
}
Fields supplied on the notification override the corresponding template content. That lets one send change a title, destination, or custom data without creating a new template version.
Template content may include interruption_level using passive, active, time_sensitive, or critical. A send-level value overrides the template; omitted values default to active after template resolution.
Archived templates cannot create new notifications. Existing notifications retain their content snapshot.
Read and update templates#
GET /v1/templates
GET /v1/templates/{template_id}
PATCH /v1/templates/{template_id}
DELETE /v1/templates/{template_id}
The list returns current metadata. The detail endpoint also returns current content.
Every PATCH creates a new immutable content version, even when only name or status changes. Supply the complete content object when changing content; it replaces the previous version.
{
"name": "Order dispatched v2",
"status": "published",
"content": {
"title": "Order {{ template.order_id }} is moving",
"body": "Track its progress in the app.",
"click_url": "myapp://orders/{{ template.order_id }}"
}
}
Valid update statuses are draft, published, and archived. DELETE is a convenient archive operation and returns {"deleted":true}.
Template design checklist#
- Keep titles short enough for lock-screen truncation.
- Put dynamic send-specific values in
template_data, not in saved user tags. - Use deep links that old app versions can handle safely.
- Test missing properties, long names, and supported locales.
- Avoid sensitive data in title, body, and image URLs.
- Treat template edits as releases: preview them, publish intentionally, and monitor the first send.
