Skip to main content
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):
FilterNotes
statusRepeat to OR, e.g. ?status=APPROVED&status=PAUSED. Accepts Meta aliases (PENDING -> IN_REVIEW).
categoryAUTH/AUTHENTICATION, UTILITY, MARKETING.
languagee.g. en_US.
sender_idRestrict to one sender.
name_or_contentCase-insensitive substring match (max 200 chars).
sortupdated_desc (default), updated_asc, created_desc, name_asc, name_desc.
limitPage size, 1-200 (default 50).

Cursor pagination

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