Message templates are pre-registered, Meta-approved message structures. You must use a template to start a conversation or to message a user outside the 24-hour window. This guide shows how to find templates, read their parameters, and feed them into a send. For the full field list, see the reference: Templates API.
Only templates whose status is APPROVED can be sent. Listing with ?status=APPROVED shows exactly what you can send right now.
Listing templates
The list endpoint is cursor-paginated and filterable.
curl "https://karibu.briq.tz/v1/whatsapp/templates?status=APPROVED&limit=50" \
-H "X-API-Key: YOUR_API_KEY"
{
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"params": ["customer_name", "order_id"],
"status": "APPROVED",
"whatsapp_sender_number_id": "9c1f0b2e-7d44-4a91-8f0a-1b2c3d4e5f60"
}
],
"cursor_next": "eyJ1cGRhdGVkX2F0Ijoi...",
"total_count": 137
}
Filters (most are repeatable to OR multiple values):
| Filter | Notes |
|---|
status | Repeat to OR, e.g. ?status=APPROVED&status=PAUSED. Accepts Meta aliases (PENDING -> IN_REVIEW). |
category | AUTH/AUTHENTICATION, UTILITY, MARKETING. |
language | e.g. en_US. |
sender_id | Restrict to one sender. |
name_or_content | Case-insensitive substring match (max 200 chars). |
sort | updated_desc (default), updated_asc, created_desc, name_asc, name_desc. |
limit | Page size, 1-200 (default 50). |
Request a page, then if cursor_next is non-null pass it back as the cursor query param to fetch the next page. Stop when cursor_next is null. Keep sort and your filters identical across pages - the cursor encodes position for the active sort order.
import requests
BASE = "https://karibu.briq.tz"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
def all_approved_templates():
cursor, out = None, []
while True:
params = {"status": "APPROVED", "limit": 200, "sort": "updated_desc"}
if cursor:
params["cursor"] = cursor
page = requests.get(f"{BASE}/v1/whatsapp/templates", headers=HEADERS, params=params).json()
out.extend(page["items"])
cursor = page.get("cursor_next")
if not cursor:
return out
Understanding template statuses
status reflects the admin lifecycle. The full set is DRAFT, IN_REVIEW, APPROVED, PAUSED, REJECTED, DISABLED, IN_APPEAL, PENDING_DELETION, DELETED, LIMIT_EXCEEDED, ARCHIVED. Only APPROVED templates are sendable; sending any other status fails with TEMPLATE_NOT_APPROVED or TEMPLATE_PAUSED_OR_DISABLED.
To poll a template through review, fetch it by id:
curl "https://karibu.briq.tz/v1/whatsapp/templates/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "X-API-Key: YOUR_API_KEY"
Sending with a template
Map the listed template’s fields directly onto the send-template body:
template_name: the template’s name
variables: an object keyed by the template’s ordered params (each placeholder name maps to its value)
sender_id: the template’s whatsapp_sender_number_id (the sender that owns it)
language: implied by the template you reference (it is not a field on the send body)
Given the example template above (name: "order_confirmation", params: ["customer_name", "order_id"]):
{
"sender_id": "9c1f0b2e-7d44-4a91-8f0a-1b2c3d4e5f60",
"template_name": "order_confirmation",
"recipient": "255700000000",
"variables": { "customer_name": "Asha", "order_id": "A-10293" }
}
Provide a value for every key in params. A mismatch returns TEMPLATE_PARAM_COUNT_MISMATCH (400). If the sender doesn’t own a template with that name you’ll get NO_TEMPLATE_LINK (404).
Next: Sending messages | Delivery events