Messaging API
Send a template
Send an approved WhatsApp template message (outbound-first).
POST /api/v1/templatesSends an approved WhatsApp template. This is how you message a contact first (outside the 24h window). Rate-limited to 60 requests/minute per API key.
Body
| Field | Type | Required | Notes |
|---|---|---|---|
template_id | int | required | ID of one of your templates — see List templates. |
phone_number | string | required | Recipient. Non-digits stripped; validated as a possible number. |
variables | object | conditional | Flat map keyed by the variable name declared in the template. Required if the template defines header/body/dynamic-button variables. |
cleanForCountry | string | optional | "FR" strips a leading 0 and prefixes 33 if missing. |
name | string | optional | Contact name on creation (default Unknown). |
email | string | optional | Contact email on creation. |
The variables object is flat — Kanal builds the WhatsApp component payload
server-side. Static-URL and quick-reply buttons need no variables; a
dynamic-URL button takes its URL from the variable named after the button.
Optional header
| Header | Notes |
|---|---|
Idempotency-Key | Replaying the same key short-circuits (returns 201). |
Request
curl -X POST https://api.getkanal.com/api/v1/templates \
-H "Authorization: Bearer 8fK2pX9mWq4Ld7Vb3Nc6Ts1Z" \
-H "Content-Type: application/json" \
-d '{
"template_id": 1234,
"phone_number": "+33612345678",
"name": "Jane Doe",
"variables": { "first_name": "Jane", "order_id": "10456" }
}'Response 200 OK
{
"success": true,
"message": "Template message sent successfully",
"message_id": 987654,
"contact_id": 54321,
"phone_number": "33612345678"
}201 when an Idempotency-Key matches a prior request.
Errors
| Status | Body | Cause |
|---|---|---|
401 | { "error": "Invalid API key" } | Auth. |
403 | { "error": "Team has no active subscription" } | No active subscription. |
429 | { "error": "Too many requests. Please slow down.", "retry_after": 60 } | Over 60 req/min. |
400 | { "error": "template_id is required" } | Missing template_id. |
404 | { "error": "Template not found for this phone number" } | Unknown template. |
400 | { "error": "phone_number is required" } / { "error": "Phone number is not valid" } | Bad recipient. |
400 | { "error": "Contact has opted out from receiving messages", "contact_id": …, "phone_number": "…" } | Recipient opted out. |
400 | { "message": "Error sending template message", "error": "Variable <name> not found in row" } | Missing a required template variable / send failure. |