Templates & the 24-hour window
When WhatsApp allows free-form messages, and how to start or re-open a conversation with an approved template
WhatsApp only allows free-form messages (text, media, interactive) within a rolling 24-hour customer service window that opens, and resets, each time the customer messages you. Outside that window you may send only Meta-approved template messages.
The customer service window
Blooio enforces the window locally, before relaying to Meta, so you fail fast with a clear error instead of spending your messaging quota on a send Meta would refuse:
| Situation | Result |
|---|---|
| Inside the window | Any content type is allowed |
| Outside the window, non-template content | 422 template_required_outside_customer_service_window |
| Template not approved on the WABA | 422 template_not_approved |
Every inbound message the customer sends, including a button tap or a photo, opens or resets the window for that chat.
Note
A template send is allowed at any time, in or out of the window, as long as the template is approved. Sending a template is how you re-engage a customer whose window has closed; their reply opens a new window.
Send a template
Reference an approved template by name and language, and pass positional body variables in variables:
cURL
curl -X POST 'https://api.blooio.com/v4/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"to": "+15551234567",
"from": "+15559876543",
"template": {
"name": "order_confirmation",
"language": "en_US",
"variables": ["Ada", "#A1234"]
}
}'Try itNode.js
await fetch('https://api.blooio.com/v4/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+15551234567',
from: '+15559876543',
template: {
name: 'order_confirmation',
language: 'en_US',
variables: ['Ada', '#A1234']
}
})
})Python
requests.post('https://api.blooio.com/v4/messages',
headers={
'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}",
'Content-Type': 'application/json'
},
json={
'to': '+15551234567',
'from': '+15559876543',
'template': {
'name': 'order_confirmation',
'language': 'en_US',
'variables': ['Ada', '#A1234']
}
}
)An array of variables fills the body's {{1}}, {{2}}, … in order. For a template with named placeholders such as {{first_name}}, pass an object instead: "variables": { "first_name": "Ada", "order_id": "#A1234" }. For advanced templates (header media, buttons), pass a raw Cloud API components array instead of variables.
Create and sync templates
Create and sync templates from the dashboard (or POST /organizations/:id/integrations/whatsapp/:channelId/templates). Meta reviews every template, usually within minutes and at most 24 hours, and only approved templates can be sent. Pick the category that matches the content:
| Category | For |
|---|---|
| Utility | Updates about something the customer started: orders, appointments, shipping, account alerts |
| Marketing | Promotions and offers, to customers who opted in |
| Authentication | One-time passcodes |
Quick-reply buttons on templates
A template can carry quick-reply buttons. When the customer taps one, you receive a message.received with message_type: "interactive" and interactive.kind: "button", where selected.id is the button's payload. The shape is the same as a tap on an interactive message.
Related
- WhatsApp Business overview
- Interactive messages — buttons and lists inside the window
- Receiving & status