Message Templates
CRUD for message templates on a customer’s WABA. All endpoints are
scoped by {WABA_ID}. WABAs that don’t belong to a customer under
your partner account return 403.
1. Create a template
POST /api/v25.0/{WABA_ID}/message_templates
Authorization: Bearer pk_live_<your-key>
Content-Type: application/jsonRequest body
{
"name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "HEADER",
"format": "TEXT",
"text": "Order {{1}} confirmed"
},
{
"type": "BODY",
"text": "Hi {{1}}, your order {{2}} has been confirmed and will ship in 24 hours."
},
{
"type": "FOOTER",
"text": "Splashify · Order tracking"
},
{
"type": "BUTTONS",
"buttons": [
{ "type": "URL", "text": "Track order", "url": "https://example.com/orders/{{1}}" },
{ "type": "QUICK_REPLY","text": "Talk to us" }
]
}
]
}category is one of MARKETING, UTILITY, AUTHENTICATION,
SERVICE.
Response — 200
{
"id": "964823735155832",
"status": "PENDING",
"category": "UTILITY"
}New templates land in PENDING. Meta reviews them; expect
APPROVED or REJECTED within minutes-to-hours. Status updates
are delivered through the
whatsapp.template_status webhook
event.
2. List all templates on a WABA
GET /api/v25.0/{WABA_ID}/message_templates
Authorization: Bearer pk_live_<your-key>Response — 200
{
"data": [
{
"name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"status": "APPROVED",
"id": "964823735155832",
"components": [ /* … */ ]
}
],
"paging": { "cursors": { "before": "...", "after": "..." } }
}3. Get one template by ID
GET /api/v25.0/{WABA_ID}/message_templates/id/{TEMPLATE_ID}
Authorization: Bearer pk_live_<your-key>4. Edit a template (category)
POST /api/v25.0/{WABA_ID}/message_templates/id/{TEMPLATE_ID}
Authorization: Bearer pk_live_<your-key>
Content-Type: application/jsonUse this to re-categorise an approved template — for example, moving
a template from UTILITY to MARKETING after a copy change.
{
"category": "MARKETING"
}The template’s status flips back to PENDING for a fresh Meta
review.
Response — 200
{ "success": true }5. Edit a template (components)
Same endpoint, different body — change the body / header / footer / buttons of an existing template.
POST /api/v25.0/{WABA_ID}/message_templates/id/{TEMPLATE_ID}{
"components": [
{
"type": "HEADER",
"format": "TEXT",
"text": "Updated header for {{1}}"
},
{
"type": "BODY",
"text": "Hi {{1}}, we've updated your order {{2}} status."
},
{
"type": "FOOTER",
"text": "Splashify · Updated"
}
]
}Component edits also flip status to PENDING. Variables in the new
copy must remain contiguous ({{1}}, {{2}}, …) or Meta rejects.
6. Template previews
Generate a preview block for an authentication template before you create it — useful for showing your customer what their authentication template will look like in WhatsApp.
GET /api/v25.0/{WABA_ID}/message_template_previews?category=AUTHENTICATION&languages=en_US&add_security_recommendation=true&code_expiration_minutes=10&button_types=OTP
Authorization: Bearer pk_live_<your-key>| Param | Notes |
|---|---|
category | Currently only AUTHENTICATION is supported in the preview API |
languages | Comma-separated list of language codes |
add_security_recommendation | true to include “For your security, don’t share this code” footer text |
code_expiration_minutes | If set, adds an expiry footer note |
button_types | OTP (one-tap autofill) or COPY_CODE |
Response — 200
{
"data": [
{
"language": "en_US",
"preview": {
"body": "{{1}} is your verification code.",
"footer": "For your security, do not share this code.",
"buttons":[
{ "type": "OTP", "text": "Autofill" }
]
}
}
]
}7. Compare templates (analytics)
Compare per-template metrics for 2 templates within a date range.
GET /api/v25.0/{TEMPLATE_ID}/compare?template_ids=[<OTHER_TEMPLATE_ID>]&start=<UNIX>&end=<UNIX>
Authorization: Bearer pk_live_<your-key>| Param | Notes |
|---|---|
template_ids | The OTHER template ID to compare against. Only one entry — exactly 2 templates compared at a time (the path one + the query one) |
start / end | UNIX timestamps. UTC day boundaries |
Response — 200
{
"data": [
{
"template_id": "964823735155832",
"sent": 125400,
"delivered": 118200,
"read": 82100,
"ctr": 0.045
},
{
"template_id": "954638012257287",
"sent": 89200,
"delivered": 85100,
"read": 71400,
"ctr": 0.082
}
]
}ctr is computed by Meta on button-tap analytics for MARKETING /
UTILITY templates.
8. Delete a template
Two delete shapes — by ID + name (precise), or by name only (deletes all language variants).
By ID + name (recommended)
DELETE /api/v25.0/{WABA_ID}/message_templates?hsm_id=964823735155832&name=order_confirmation
Authorization: Bearer pk_live_<your-key>Pass both hsm_id (the template ID) and name. Meta uses both
to disambiguate when multiple language variants of a template share
a name. Deletes that specific variant only.
By name only
DELETE /api/v25.0/{WABA_ID}/message_templates?name=order_confirmation
Authorization: Bearer pk_live_<your-key>Deletes all language variants with this name in a single call. Use with care — there’s no undo.
Response — 200
{ "success": true }Errors
| Status | Example |
|---|---|
400 | Meta returns 400 verbatim for invalid payloads (unknown variable index, oversized header, disallowed URL, etc.) |
401 | { "success": false, "message": "unauthorized" } |
403 | { "success": false, "message": "id does not belong to your account" } |
404 | { "success": false, "message": "id not found" } |
502 | { "success": false, "message": "WhatsApp request failed. Try again shortly." } |
cURL — create
curl -X POST \
"https://api.splashifypro.com/api/v25.0/$WABA_ID/message_templates" \
-H "Authorization: Bearer $SPLASHIFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"components": [
{ "type": "BODY", "text": "Hi {{1}}, your order {{2}} is confirmed." }
]
}'Notes
- Review can take up to 24 hours during high-volume periods on the Meta side. Avoid baking a new template into a live send queue without a fallback path.
- Re-submitting the same name in the same language replaces the PENDING/REJECTED variant; an APPROVED variant must be deleted before re-creating.
- Variable indices must be contiguous (
{{1}},{{2}}, …). Gaps cause Meta to reject the template at submission.