Templates
Overview
A Template in Sent is a reusable blueprint for messages that enables consistent, personalized communication at scale across multiple messaging channels. It represents a structured message format with dynamic variables, media support, and interactive elements that automatically adapts to each channel's requirements.
Every time you need to send repetitive messages with variable content, a Template provides:
- Consistency: Maintain uniform tone, branding, and structure across all communications.
- Personalization: Insert dynamic content like names, order numbers, and custom data at send time.
- Multi-Channel Support: Automatically adapt content for SMS, WhatsApp, and other channels with their specific formatting rules.
- Compliance Management: Handle channel-specific approval requirements (like WhatsApp template approval) automatically.
- Scalability: Send thousands of personalized messages without manual composition.
The Template Lifecycle
When you create a template, it progresses through several stages before becoming available for messaging. Understanding this lifecycle is essential for building reliable messaging workflows.
Templates submitted for use with WhatsApp undergo an approval process managed by Meta. While your template status is Pending—that is, while waiting for Meta's approval—you can still use your templates to send SMS messages via Sent. Only WhatsApp message delivery is blocked until the template is approved; SMS channels remain available throughout the review process.
Template Creation and Approval Flow
Status Descriptions
- Draft: Template is being created or edited. Can be modified, tested, and deleted.
- Pending: Template has been submitted for review and approval by Meta. Cannot be edited until approved or rejected. You can still send SMS messages via Sent using this template.
- Approved: Template is ready for use in messaging. Content is locked to ensure consistency.
- Rejected: Template needs revision based on review feedback. Returns to draft status for editing.
Template Anatomy & Variables
The template content is composed of the following components, each thoroughly documented below:
| Component | Channel Support | Description |
|---|---|---|
| Header | WhatsApp only | Optional title or introduction for your messages |
| Body | WhatsApp & SMS | Main message content with variable placeholders |
| Footer | WhatsApp only | Optional disclaimers or context |
| Buttons | WhatsApp only | Interactive elements (URL, phone, quick reply, etc.) |
Templates support variables that are dynamically inserted into the template content. Variables use a numbered ID system and a unified props structure to support text, links, and media across channels.
Template Header
The header is an optional component that can be used to add a title or introduction for your messages. It is only supported on WhatsApp.
It supports up to 60 characters and up to 1 dynamic variable.
Fill in the template header details
Result
Template Body
The body is the main component of the template that contains the message content. It is supported on WhatsApp and SMS. It supports up to 1028 characters and as many dynamic variables and links as you need.
SMS message length is limited to 160 characters per message segment. If your template body exceeds this limit when sent as an SMS, it will automatically be split into multiple SMS messages. Each segment may include additional metadata, meaning the actual character limit per segment could be slightly lower for concatenated messages. On the recipient’s phone, these are usually combined and appear as a single long message, but your SMS usage and billing will reflect the number of segments sent.
Fill in the template body details
- The yellow boxes are the dynamic variables
- The lightblue boxes are the dynamic links
Adding dynamic variables and links
- You can add dynamic variables and links to the template body by clicking on the
Insert dynamic variableandInsert dynamic linkbuttons
| Dynamic Variable Type | Description |
|---|---|
| Text | Plain text content that can be personalized |
| Link | Dynamic URLs for tracking or personalization |
| Image/Media | Images or media files (WhatsApp only) |
| File | Document files (WhatsApp only) |
| Dynamic Link Type | Description |
|---|---|
| Link | Call to Action with dynamic URL that can be personalized |
Result
Template Footer
The footer is an optional component that can be used to add a footer to the template. It is supported on WhatsApp only.
It supports up to 60 characters and no dynamic variables or links.
Fill in the template footer details
Result
Template Buttons
The buttons are an optional component that can be used to add interactive buttons to the template.
Fill in the template buttons details
Buttons types & options
- You can add buttons to the template by clicking on the
Add buttonbutton.
| Button Type | Quantity allowed in the template | Description |
|---|---|---|
| Custom Buttons | Unlimited | Custom Button type and Preconfigured Response type |
| Visit Website Buttons | Up to 2 | Support static and dynamic URLs |
| Phone Number Button | Up to 1 | One-tap calling with country code and phone number support |
| Copy Offer Button | Up to 1 | One-tap copying for OTP or offer codes |
Result
Template Category & Language
The category and language are optional fields that can be used to categorize and language the template.
- The category is automatically detected based on the template content, but you can also manually choose it.
- The language is automatically detected based on the template content, but you can also manually choose it.
Template JSON Definition
The JSON definition is the JSON representation of the template. You can view the JSON definition by clicking on the View JSON button in the template builder.
This is the JSON that you need to send to the Sent API when you create a template.
JSON definition of the template that we created above
{
"category": "AUTO",
"language": "AUTO",
"creationSource": "from-scratch",
"definition": {
"header": {
"type": "text",
"template": "📦 Order {{0:variable}} — Delivery Update",
"variables": [
{
"id": 0,
"name": "orderNumber",
"type": "variable",
"props": {
"variableType": "text",
"sample": "12345"
}
}
]
},
"body": {
"multiChannel": {
"type": "body",
"template": "Hi {{0:variable}},\nYour Acme order {{1:variable}} has been shipped and is expected to arrive {{2:variable}} between {{3:variable}}.\nYou can track your package or update your delivery preferences on this page: {{4:link}} .",
"variables": [
{
"id": 0,
"name": "customerName",
"type": "variable",
"props": {
"variableType": "text",
"sample": "Lucas"
}
},
{
"id": 1,
"name": "orderNumber",
"type": "variable",
"props": {
"variableType": "text",
"sample": "#12345"
}
},
{
"id": 2,
"name": "arrivalDate",
"type": "variable",
"props": {
"variableType": "text",
"sample": "tomorrow (Oct 11)"
}
},
{
"id": 3,
"name": "arrivalTime",
"type": "variable",
"props": {
"variableType": "text",
"sample": "2 PM – 4 PM"
}
},
{
"id": 4,
"name": "orderLink",
"type": "link",
"props": {
"url": "https://example.com",
"shortUrl": "",
"alt": "Tracking Page"
}
}
]
}
},
"footer": {
"type": "text",
"template": "Thank you for shopping with Acme.",
"variables": []
},
"buttons": [
{
"id": 1,
"type": "URL",
"props": {
"text": "Track your order",
"urlType": "dynamic",
"url": "https://www.example.com"
}
},
{
"id": 2,
"type": "PHONE_NUMBER",
"props": {
"text": "Acme customer support",
"countryCode": "US",
"phoneNumber": "+112345678"
}
}
]
}
}Template Header Object
| Field | Type | Description |
|---|---|---|
type | string | Header type: text or media |
template | string | Header text content with variable placeholders |
variables | array | Array of Variable Objects used in the header |
Template Body Object
| Field | Sub-field | Type | Description |
|---|---|---|---|
multiChannel | type | string | Body type: body |
template | string | Body text content with variable placeholders | |
variables | array | Array of Variable Objects used in the body | |
sms | template | string | SMS-specific body text (optional) |
whatsapp | template | string | WhatsApp-specific body text (optional) |
Template Footer Object
| Field | Type | Description |
|---|---|---|
type | string | Footer type: text |
template | string | Footer text content (max 60 characters) |
variables | array | Array of variables (typically empty for footers) |
Template Buttons Array
Template buttons are an array of button objects. Below is the definition of the button object.
| Field | Sub-field | Type | Description |
|---|---|---|---|
id | number | Button identifier | |
type | enum | Button type: QUICK_REPLY, URL, PHONE_NUMBER, or COPY_CODE | |
props | text | string | Button label text |
quickReplyType | enum | Quick reply type: custom or pre-configured (QUICK_REPLY type only) | |
urlType | enum | URL type: static or dynamic (URL type only) | |
url | string | Destination URL (URL type only) | |
countryCode | string | Country code (PHONE_NUMBER type only) | |
phoneNumber | string | Phone number with country code (PHONE_NUMBER type only) | |
offerCode | string | Offer code to copy (COPY_CODE type only) |
Variable Object
| Field | Sub-field | Type | Description |
|---|---|---|---|
id | number | Sequential ID starting from 1 | |
name | string | Readable identifier for the variable | |
type | enum | Variable type: variable, link, or media | |
props | variableType | enum | Specific type: text, link, image, or file |
sample | string | Example value for previews and approval | |
url | string | Full URL (for links/media) | |
shortUrl | string | Optional shortened URL | |
alt | string | Alternative text (for media) | |
mediaType | enum | Media type: image, video, or document |
Managing Templates
Templates can be managed either through the Sent Dashboard playground or programmatically via the API.
Sent Dashboard
You can manage templates through the Sent Dashboard. The dashboard provides:
- Visual template builder with drag-and-drop interface
- Real-time preview across different channels
- View template details
- Delete templates
API Endpoints
For programmatic template management, use the following API endpoints:
Best Practices
- Store the
templateId: This is your primary key for referencing templates when sending messages. Log it in your local database for easy retrieval. - Choose the Right Category: Select the most appropriate category (UTILITY, AUTHENTICATION, MARKETING) for your message type to ensure faster approval and optimal delivery rates.
- Use Descriptive Variable Names: Name variables clearly to indicate their purpose (e.g.,
customerName,orderNumber,orderLink). - Provide Realistic Sample Data: Use production-like sample values that demonstrate actual use cases for better approval chances.
- Test Before Submission: Always test templates with
submitForReview=falsefirst, then submit for approval once verified. - Leverage Multi-Channel Fallback: Define
multiChannelbody content as a safe fallback for all channels. - Optimize for Character Limits: Keep body content concise and use variables for dynamic details to stay within channel limits.
- Order Buttons by Importance: Place the most critical action button first for better user engagement.
- Monitor Template Status: Implement webhook handlers to track template approval status and handle rejections gracefully.
- Create Language-Specific Templates: Build separate templates for each language rather than translating variables for better localization.
When to Use Templates:
- Transactional messages (order confirmations, shipping updates)
- Authentication flows (OTP codes, password resets)
- Appointment reminders with dynamic details
- Marketing campaigns with personalized content
- Status updates with variable information
Avoid Templates For:
- Conversational customer service interactions
- Real-time chat that requires back-and-forth
- One-off or highly contextual messages
- Content that needs frequent editing