KanalKanal API
Messaging API

Send a template

Send an approved WhatsApp template message (outbound-first).

POST /api/v1/templates

Sends 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

FieldTypeRequiredNotes
template_idintrequiredID of one of your templates — see List templates.
phone_numberstringrequiredRecipient. Non-digits stripped; validated as a possible number.
variablesobjectconditionalFlat map keyed by the variable name declared in the template. Required if the template defines header/body/dynamic-button variables.
cleanForCountrystringoptional"FR" strips a leading 0 and prefixes 33 if missing.
namestringoptionalContact name on creation (default Unknown).
emailstringoptionalContact 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

HeaderNotes
Idempotency-KeyReplaying 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

StatusBodyCause
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.

On this page