A template is a message text you save once and reuse. It can contain placeholders, holes
between braces such as {firstname}, that the gateway fills with the details of the contact the
message goes to.
What templates are for
- Answering the same questions over and over in a conversation without retyping: opening hours, address, payment details.
- Giving an automatic reply a personal touch: "Hello {firstname}, we received your message".
- Keeping the wording of a campaign in one place, approved once, instead of copying it from an old campaign.
How it works
A template has four fields:
| Field | Required | Limit | What it is for |
|---|---|---|---|
name |
yes | 80 characters | How you find it. Two templates cannot share a name, whatever the case |
body |
yes | 4000 characters | The text, placeholders included |
category |
no | 60 characters | Free label to sort your templates (support, promo...) |
description |
no | 500 characters | A note for your team: when to use it, who approved it |
The 4000-character limit is a storage bound, not a recommendation: a text message over 160 characters is billed as several SMS. See Sending messages for how the length is counted.
Placeholders
Write the name of a field between braces. Two forms exist:
| You write | When the contact has a value | When the contact has no value |
|---|---|---|
{firstname} |
Hello Marie |
Hello {firstname}: the placeholder stays visible |
{firstname|there} |
Hello Marie |
Hello there: the value after the bar is used |
A placeholder left visible is deliberate: an SMS that reads "Hello {firstname}" is a mistake you notice when you check, while "Hello ," with an empty hole would go unnoticed. When a field may be empty, always give a fallback value after the bar.
The names are not case sensitive ({FirstName} and {firstname} are the same), and each field
answers to a French and an English name:
| Placeholder | Filled with |
|---|---|
{firstname} or {prenom} |
The contact's first name |
{lastname} or {nom} |
The last name |
{company} or {societe} |
The company |
{email} |
The email address |
{phone} or {telephone} |
The phone number, in international format |
{<your field>} |
A custom field of the contact, by its key (for example {city}) |
Custom fields are set on each contact: see Contacts and groups. A custom field never replaces one of the built-in names above.
Where templates are used
| Where | What happens to the placeholders |
|---|---|
| Rules > an action Reply by SMS, content Saved template | Filled from the contact record of the person who wrote in, at the moment the reply leaves. A sender who is not in your contacts gets the fallback values |
| Campaigns > Create a campaign > Message source = Saved template | The text is resolved once, when the campaign is created, without any contact's details: every placeholder takes its fallback value, and those without one stay visible. The same text goes to everyone |
| Conversations, in the message box | The button next to the box, or typing / at the start of the message, lists your templates. Picking one pastes its text into the box, placeholders as written: edit them before sending |
Two consequences to keep in mind:
- A campaign is not personalised per recipient. Write campaign templates with fallback values
(
{firstname|Dear customer}) or without placeholders, and read the summary of the wizard before starting: a placeholder you forgot is visible there. - Changing a template does not change what already left, nor a campaign already created from it: the campaign kept its own copy of the text at creation.
Creating and editing templates
In this version, templates are created, edited and deleted through the API; the dashboard lists them wherever you can pick one (campaign wizard, rule form, conversation box) but has no screen to write them. Any tool that can send an HTTP request works (curl, Postman, n8n, your own code), with an API key: see Using the API and API keys.
| Method | Path | What it does |
|---|---|---|
GET |
/api/v1/templates |
Your templates, sorted by name. ?category= filters |
POST |
/api/v1/templates |
Creates a template (name, body, optional category, description) |
GET |
/api/v1/templates/{templateId} |
One template, with the list of placeholders found in its body |
PUT |
/api/v1/templates/{templateId} |
Changes a template. An omitted field is left as it is |
DELETE |
/api/v1/templates/{templateId} |
Deletes it. Messages already sent keep their text |
POST |
/api/v1/templates/{templateId}/preview |
Shows the final text for a contact, without sending anything |
Example:
curl -X POST https://sms.example.com/api/v1/templates \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Opening hours", "category": "support",
"body": "Hello {firstname|there}, we are open Monday to Friday, 9:00 to 18:00."}'
With an API key, reading needs the read scope and every change needs the admin scope. See
API keys.
You never declare the placeholders: the gateway reads them from the body every time, so the list can never disagree with the text.
Check before you send: the preview
POST /api/v1/templates/{templateId}/preview takes a contactId (a real contact) and/or
variables (values you type, which win over the contact's), and returns:
| Field | Meaning |
|---|---|
body |
The final text |
segments |
How many SMS it will be billed as |
encoding |
gsm7 or ucs2: a character outside the SMS alphabet (some accents, emoji) switches to ucs2, which fits fewer characters per SMS |
unresolved |
The placeholders that found neither a value nor a fallback. Empty is what you want |
Preview is allowed to every role, Read only included: it changes nothing.
Who can do what
| Role | Templates |
|---|---|
| Read only | See them and preview them |
| Operator, Superadmin | Create, edit, delete |
See Users and roles.
Troubleshooting
| What you see | Why, and what to do |
|---|---|
The recipient received {firstname} as is |
The contact had no first name and the placeholder had no fallback, or it was a campaign (never personalised). Add |fallback |
| "No template saved yet." in a picker | No template exists yet: create one through the API |
Creating a template answers 409 |
The name is already used by another template, possibly with different capitals |
| A placeholder is printed with its braces even with data | Check the spelling: a name the gateway does not know stays visible. For a custom field, use exactly its key |
| The SMS costs twice what you expected | The text contains characters outside the SMS alphabet. Look at encoding in the preview |