Templates
A template is a message Meta has reviewed in advance. You need one to start any conversation, because outside an open 24-hour window a template is the only thing WhatsApp will deliver.
Create one
curl -X POST https://core-prod.malipopay.co.tz/api/v1/waba/templates \
-H "apiToken: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "payment_received",
"language": "en",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, we have received TZS {{2}} for order {{3}}. Thank you.",
"example": { "body_text": [["John", "50,000", "ORD-001"]] }
}
]
}'
| Field | Required | Notes |
|---|---|---|
name | Yes | Lowercase letters, digits and underscores |
language | Yes | en or en_US form. The language is part of the template's identity |
category | Yes | MARKETING, UTILITY or AUTHENTICATION |
components | Yes | At least a BODY. May also carry HEADER, FOOTER, BUTTONS |
wabaAccountId | No | Defaults to your own account, falling back to the shared platform WABA |
allowCategoryChange | No | Lets Meta re-file the template rather than reject it outright |
MALIPOPAY validates against Meta's rules before submitting, so a malformed template comes back immediately with a sentence you can act on, rather than hours later as an unexplained rejection.
The rules that actually cause rejections
A body cannot end with a variable. "Your code is {{1}}" is rejected. Add trailing text: "Your code is {{1}}. Do not share it."
- Every variable needs an example. Meta reviews the rendered message, not the skeleton. Supply
example.body_textwith one entry per placeholder. - Buttons need examples too. A URL button with a variable needs an example URL.
- Placeholders are positional. Use
{{1}},{{2}}. Named placeholders like{{name}}are accepted at submission and then rejected during review, which is the worst way to find out. - Numbering must be sequential from 1 with no gaps.
- Authentication templates follow their own grammar: a copy-code button and a single body parameter. Do not pass the code twice.
- Category matters. A promotion filed as
UTILITYgets rejected or re-categorised, andMARKETINGcosts more per conversation.
Check status
curl "https://core-prod.malipopay.co.tz/api/v1/waba/templates?status=APPROVED" \
-H "apiToken: YOUR_API_KEY"
| Status | Meaning |
|---|---|
PENDING | Submitted, awaiting Meta review |
APPROVED | Ready to send |
REJECTED | Refused. Fix and resubmit under a new name |
PAUSED | Throttled by Meta after poor user feedback |
DISABLED | Withdrawn by Meta |
IN_APPEAL | Under appeal |
Review usually takes minutes but can take much longer. Get your templates approved before launch day, not during it.
GET /api/v1/waba/templates/{id} fetches one and refreshes its status from Meta. POST /api/v1/waba/templates/sync reconciles every template across all your connected accounts, which is the fix when the dashboard looks stale.
Delete
curl -X DELETE https://core-prod.malipopay.co.tz/api/v1/waba/templates/{id} \
-H "apiToken: YOUR_API_KEY"
Deletion is permanent at Meta. A name that has been used and deleted cannot always be reused immediately, so version your names (order_confirmation_v2) rather than deleting and recreating under the same one.
Practical advice
- Keep a small set of well-tested templates rather than one per situation. Every template is a review you have to pass and a thing that can be paused.
- Write the example values as real data. Reviewers read them.
- If a template is rejected, change the copy rather than resubmitting the same text under a new name. The second submission fails the same way.