Active Message: WhatsApp Official
Active messages via WhatsApp Official (Meta Business API) allow you to proactively send messages using pre-approved Meta templates. This is the recommended option for companies that require full compliance with WhatsApp's terms of service.
Difference from Evolution
| WhatsApp Official | Evolution | |
|---|---|---|
| Message type | Meta-approved templates only | Free-form text, media, and lists |
| Approval | Template must be approved by Meta first | No approval required |
| Compliance | Fully within WhatsApp's terms | Unofficial API usage |
| Variables | Indexed template parameters ({{1}}, {{2}}) |
Free variables ($name, $plan) |
Prerequisites
- Meta Business Manager account with WhatsApp Business API enabled
- WhatsApp instance created in the Verboo dashboard with:
MetaAccessToken: Meta access tokenPhoneNumberID: phone number ID in MetaMetaBusinessID: business account ID
- Template created and approved in Meta Business Manager
assistantIDof the assistantintegrationIDof the WhatsApp instance
How to get the integrationID
List the assistant's WhatsApp instances to find the id of the desired instance. The phoneNumber field helps identify which number to use:
GET /whatsapp-instance
Authorization: Bearer {token}[
{
"id": 789,
"uuid": "xyz456...",
"assistantID": 123,
"phoneNumber": "+55 85 99999-0001",
"active": true
}
]Use the id field as integrationID in the task payload.
Create a task
POST /assistant/{assistant_id}/task
Content-Type: application/json
Authorization: Bearer {token}Full payload
{
"integrationID": 789,
"integrationType": "WHATSAPP",
"triggerType": "CRONJOB",
"triggerData": "0 10 * * 1",
"type": "TEMPLATE_MESSAGES",
"data": {
"title": "Appointment Reminder: Monday",
"template": {
"name": "appointment_reminder",
"language": {
"code": "en_US"
}
},
"contacts": [
{
"to": "5585999990001",
"name": "Ana Souza",
"header": {
"params": [
{
"key": "clinic_name",
"text": "BioClinic"
}
]
},
"body": {
"params": [
{
"key": "patient_name",
"text": "Ana"
},
{
"key": "appointment_date",
"text": "March 12, 2025 at 2pm"
},
{
"key": "specialty",
"text": "Cardiology"
}
]
},
"clientData": {
"patient_id": "pac_001"
}
}
],
"webhooks": [
{
"url": "https://system.clinic.com/hooks/reminder-sent",
"method": "POST",
"headers": {
"Authorization": "Bearer clinic_token"
},
"body": "{\"patient_id\": \"$patient_id\", \"phone\": \"$phone\"}"
}
]
}
}Payload fields
Root
| Field | Type | Required | Description |
|---|---|---|---|
integrationID |
number | yes | WhatsApp instance ID |
integrationType |
string | yes | Always "WHATSAPP" |
triggerType |
string | yes | Always "CRONJOB" |
triggerData |
string | yes | Cron expression (TZ: America/Sao_Paulo) |
type |
string | yes | Always "TEMPLATE_MESSAGES" |
data |
object | yes | Campaign configuration |
`data`
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | no | Internal campaign name |
template |
object | yes | Template to be used |
contacts |
array | yes | List of recipients |
webhooks |
array | no | HTTP calls before/after sending |
`data.template`
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Template name in Meta Business Manager |
language.code |
string | yes | Language code (e.g., en_US, pt_BR) |
`contacts[]`
| Field | Type | Required | Description |
|---|---|---|---|
to |
string | yes | Phone number (digits only, with country code) |
name |
string | no | Contact name |
header |
object | no | Template header parameters |
body |
object | no | Template body parameters |
clientData |
object | no | Extra data stored in the contact's session |
`header` and `body`
Each contains a list of params:
{
"params": [
{ "key": "variable_name", "text": "value" }
]
}For a header with an image:
{
"params": [
{
"key": "header_image",
"image": {
"link": "https://cdn.company.com/banner.png"
}
}
]
}How parameter mapping works
The Meta template defines variables by position: {{1}}, {{2}}, {{3}}. In the Verboo payload, you name each parameter with a descriptive key: the system substitutes them in the order they appear in the params array.
Example of an approved Meta template:
Hello {{1}}, your {{2}} appointment is confirmed for {{3}}.Body payload:
{
"params": [
{ "key": "patient_name", "text": "Ana" },
{ "key": "specialty", "text": "Cardiology" },
{ "key": "appointment_date", "text": "March 12, 2025 at 2pm" }
]
}Result sent:
Hello Ana, your Cardiology appointment is confirmed for March 12, 2025 at 2pm.Use case examples
Appointment reminder with image header
{
"data": {
"template": {
"name": "appointment_reminder_v2",
"language": { "code": "en_US" }
},
"contacts": [
{
"to": "5585999990001",
"name": "John Silva",
"header": {
"params": [
{
"key": "clinic_image",
"image": {
"link": "https://cdn.clinic.com/logo-banner.png"
}
}
]
},
"body": {
"params": [
{ "key": "name", "text": "John" },
{ "key": "date", "text": "Tuesday, Mar 13 at 10am" },
{ "key": "doctor", "text": "Dr. Carlos Andrade" }
]
}
}
]
}
}Payment reminder
{
"data": {
"template": {
"name": "friendly_payment_reminder",
"language": { "code": "en_US" }
},
"contacts": [
{
"to": "5511988880002",
"name": "Mary Costa",
"body": {
"params": [
{ "key": "name", "text": "Mary" },
{ "key": "amount", "text": "$299.90" },
{ "key": "due_date", "text": "March 15, 2025" },
{ "key": "payment_link", "text": "https://pay.company.com/invoice123" }
]
}
}
]
}
}Phone number format
The number must be sent digits only, including the country code:
| Format | Example |
|---|---|
| Brazil (55) + area code + number | 5585999990001 |
| With 9th digit (mobile SP area 11) | 5511991234567 |
Do not include +, (, ), -, or spaces.
Cron expression
The triggerData field accepts a standard 5-field cron expression. The system executes in America/Sao_Paulo timezone.
┌─────────── minute (0-59)
│ ┌───────── hour (0-23)
│ │ ┌─────── day of month (1-31)
│ │ │ ┌───── month (1-12)
│ │ │ │ ┌─── day of week (0=sun, 1=mon ... 6=sat)
│ │ │ │ │
0 10 * * 1 → every Monday at 10am
0 8 * * 1-5 → weekdays at 8am
0 9 1 * * → 1st of every month at 9amWebhooks
Execute HTTP calls before sending to each contact. Supports the same contact variables ($phone, $name, $phone.treated), plus any clientData keys.
{
"webhooks": [
{
"url": "https://system.company.com/hooks/send",
"method": "POST",
"headers": {
"Authorization": "Bearer token"
},
"body": "{\"phone\": \"$phone\", \"patient_id\": \"$patient_id\"}"
}
]
}Task lifecycle
WAITING → IN_PROGRESS → DONE
↘ ERROR| Status | Description |
|---|---|
waiting |
Waiting for the cron execution window |
in_progress |
Processing: messages being sent |
done |
All contacts processed successfully |
error |
Failure during execution |
Official API restrictions
- Only pre-approved Meta templates can be sent
- Templates are reviewed and approved within 24h in Meta Business Manager
- Avoid excessive promotional language in templates: it may result in rejection
- The sender phone number must be linked to a verified Business account
- For each contact, parameters must be provided in the correct order matching the template
API endpoints
| Method | Route | Description |
|---|---|---|
POST |
/assistant/{id}/task |
Create task |
GET |
/assistant/{id}/task |
List tasks |
GET |
/assistant/{id}/task/{task_id} |
Get task |
PUT |
/assistant/{id}/task/{task_id} |
Update task |
DELETE |
/assistant/{id}/task/{task_id} |
Delete task |