# Send a WhatsApp template over the API

> POST https://flowserver.skode.ai/api/v1/messages/template/ with the header Authorization: Bearer <Flow API key> (permission messages:send) sends an approved WhatsApp template from your own Flow number, at any time — including outside WhatsApp’s 24-hour window. Body: to (the number with its country code; Flow keeps only the digits and adds no country code); template_name (the template’s technical name in Flow); variables (a flat list of text, one per {{1}}, {{2}}… blank in the body, in order); optional language (defaults to the template’s own); optional callback_data (up to 512 characters, returned in the answer and in that message’s delivered/read/failed webhooks). Names may be snake_case or camelCase. Success is 200 {"ok": true, "id": "<WhatsApp message id>", "flowMessageId": "<Flow’s message id — the webhooks’ message_id>", "callbackData": …}; an opted-out recipient answers 422. Header media and button variables are not supported yet. Each send is charged to the messaging wallet; an empty wallet returns 402.

Product: SkedX Flow · Topic: APIs & Developers · Draft — steps not yet re-verified in the live product

A WhatsApp template’s words are fixed when Meta approves it; your request only fills its blanks. This is the full reference for that one request — what to send, what comes back, what isn’t supported yet, and the mistakes that cost the most time.

## Step 1: The request

Send a **POST** to `https://flowserver.skode.ai/api/v1/messages/template/` with your key in the `Authorization` header. The key needs **Send messages and templates**. A template can go out at any time — including to someone who hasn’t written to you in the last 24 hours. This request sends the class reminder pictured under it, each value in its own blank: the batch, the faculty, the time, the topic and the class link.

```bash
curl -s -X POST "https://flowserver.skode.ai/api/v1/messages/template/" \
  -H "Authorization: Bearer $FLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+91XXXXXXXXXX",
       "template_name": "batch_session_reminder_v1",
       "variables": ["Batch 108", "Meera Nair", "8.30 PM to 10:00 PM",
                     "SEO recap", "https://example.com/class/108"],
       "callback_data": "batch-108-reminder"}'
```

## Step 2: The fields

- `to` — required. The customer’s number **with its country code**, such as `+91 98765 43210`. Flow keeps only the digits and never adds a country code, so `9876543210` alone goes nowhere. (`phone` works as a name too.)
- `template_name` — required. The template’s technical name (step 3). It must be approved.
- `variables` — one value per blank in the template’s **body**, `{{1}}` first, as a plain list of text.
- `language` — optional. Left out, Flow uses the language the template was approved in. `en` and `en_US` are different templates.
- `callback_data` — optional. Up to 512 characters of your own reference. It comes back in the answer, and in the delivered, read and failed webhooks for that message.

Names may be written `template_name` or `templateName` — both work.

## Step 3: Find the template’s name and blanks

In Flow, open the template in **Templates**: its **Technical name** is the name you send, it must show **Approved**, and **Variables** is how many values it needs. From code, `GET /api/v1/templates/?channel=whatsapp` (the key needs **List templates**) returns the same as `templateName`, `status` and `variableCount` — the highest blank number it uses.
Open it directly: https://flow.skode.ai/templates/

## Step 4: What comes back

The key, the name and the blanks went in; `"ok": true` came back, with an `id` — the message’s id on WhatsApp’s side — a `flowMessageId`, the message’s id in Flow, which is the `message_id` its delivered, read and failed webhooks carry, and your `callbackData`. Keep both ids with your records. The message also appears in the customer’s conversation in Flow’s inbox. Answers always use camelCase names.

## Step 5: Fill the blanks exactly

Values go in a plain list — `["Batch 108", "8.30 PM"]` — never as named pairs: Flow checks that itself and refuses before anything is sent. The number of values and the template’s approval are checked by WhatsApp: too few or too many values, an unapproved template or a wrong language come back as a `400` carrying WhatsApp’s own explanation.

## Step 6: Not supported yet: images, documents and button blanks

The API fills blanks in a template’s **body** only. A template whose header needs an image, video or document, or whose header or buttons have their own blanks, can’t be sent through the API yet — use a body-only version of the template for automated sends.

## Step 7: Replies within 24 hours don’t need a template

Within 24 hours of a customer’s last message you can reply with free text: `POST /api/v1/messages/send/` with `"channel": "WHATSAPP"`, the customer’s number in `to`, your `text`, and the conversation’s `conversation_id` from the [conversations list](https://skode.ai/help/flow/developers/contacts-and-conversations-api/) — the reliable way to land in the right thread. Success is `{"ok": true, "id": "…"}` — the message’s id in Flow. Outside the window WhatsApp refuses free text, and Flow answers `400` with `"reason": "window_closed"` — send a template instead.

## Step 8: What it costs

Each template sent is charged to the messaging wallet at its category’s rate — marketing, utility or authentication. If the wallet is empty, or the workspace’s daily spending limit is reached, Flow answers `402` “Your messaging wallet is empty — top it up to send.” and sends nothing. Have your system alert a person on `402`, so reminders never stop without anyone noticing.
Open it directly: https://flow.skode.ai/settings/?tab=wallet

## Common questions

### Can I send a template with an image or a document?

Not through the API yet — it fills body blanks only (step 6). For automated sends, use a version of the template without header media or button blanks.

### Do I get delivered and read receipts?

Yes, as [outbound webhooks](https://skode.ai/help/flow/developers/outbound-webhooks/): A message is delivered, A message is read and A message fails to send. Each carries the message’s id in Flow (`message_id`, the answer’s `flowMessageId`), the id the send answered with (`provider_message_id`) and your `callback_data`.

### Can one request go to several numbers?

No — one request per recipient. Loop over your list; each send is charged separately.

### Where do replies go?

Into the customer’s conversation in Flow’s inbox. To receive them in your own system too, use an outbound webhook for A customer sends a message.

### Is there a limit on how fast I can send?

Flow doesn’t slow your requests down, but WhatsApp limits how many people a number may start conversations with each day, by its messaging tier. Check your number’s limit in WhatsApp Manager before a large send.

## Useful links
- Templates in Flow — technical names, status and the preview: https://flow.skode.ai/templates/
- Flow API reference — this request, with a playground: https://flow.skode.ai/docs/
- Wallet in Flow — top up before a large send: https://flow.skode.ai/settings/?tab=wallet

Videos and screenshots © 2026 SkedX, with sample data only. Share and link to them freely; copying the SkedX product or its design is not allowed. Terms: https://skode.ai/terms/

## Related guides
- Send your first WhatsApp template in 5 minutes: https://skode.ai/help/flow/developers/send-your-first-template-in-5-minutes/
- Flow API errors, and how to fix each one: https://skode.ai/help/flow/developers/flow-api-errors/
- Contacts and conversations over the API: https://skode.ai/help/flow/developers/contacts-and-conversations-api/
- Move your WhatsApp API calls from Interakt to Flow: https://skode.ai/help/flow/developers/move-your-api-calls-from-interakt/
- Get a WhatsApp template approved: https://skode.ai/help/flow/templates/get-a-whatsapp-template-approved/
- Pause an automation in a chat when someone on your team replies: https://skode.ai/help/flow/automation/automations-pause-when-your-team-replies/

Source: https://skode.ai/help/flow/developers/send-a-whatsapp-template-over-the-api/