Active Message: Evolution
Active messages allow you to proactively send messages to a list of contacts via WhatsApp. When using the Evolution integration, you can send free-form text, images, videos, documents, and interactive lists: no approved templates required.
Prerequisites
- Evolution instance created and connected in the Verboo dashboard
assistantIDof the assistantintegrationIDof the Evolution instance
How to get the integrationID
List the assistant's Evolution instances to find the id of the desired instance:
GET /evolution-instance
Authorization: Bearer {token}[
{
"id": 456,
"uuid": "abc123...",
"assistantID": 123,
"active": true,
"tags": ["clients"]
}
]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": 456,
"integrationType": "EVOLUTION",
"triggerType": "CRONJOB",
"triggerData": "0 9 * * 1-5",
"type": "MULTIPLE_MESSAGES",
"data": {
"title": "Monday Campaign: Clinics",
"contacts": [
{
"to": "5585999990001",
"name": "Ana Souza",
"clientData": {
"plan": "premium",
"source": "whatsapp"
}
},
{
"to": "5511988880002",
"name": "Carlos Lima"
}
],
"messages": [
{
"text": "Hello $name! We have something special for you today.",
"delay": 0
},
{
"text": "Check out our exclusive offer 👇",
"image": "https://cdn.company.com/banner.png",
"delay": 2000
}
],
"delayBetweenMessages": {
"minSecs": 30,
"maxSecs": 90
},
"maxMessagesPerDay": 500,
"webhooks": [
{
"url": "https://crm.company.com/hooks/message-sent",
"method": "POST",
"headers": {
"Authorization": "Bearer my_token"
},
"body": "{\"phone\": \"$phone\", \"name\": \"$name\"}"
}
]
}
}Payload fields
Root
| Field | Type | Required | Description |
|---|---|---|---|
integrationID |
number | yes | Evolution instance ID |
integrationType |
string | yes | Always "EVOLUTION" |
triggerType |
string | yes | Always "CRONJOB" |
triggerData |
string | yes | Cron expression (TZ: America/Sao_Paulo) |
type |
string | yes | Always "MULTIPLE_MESSAGES" |
data |
object | yes | Campaign configuration |
`data`
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | no | Internal campaign name |
contacts |
array | yes | List of recipients |
messages |
array | yes | Sequence of messages to send |
delayBetweenMessages |
object | no | Random interval between contacts |
maxMessagesPerDay |
number | no | Daily send limit |
webhooks |
array | no | HTTP calls before/after sending |
`contacts[]`
| Field | Type | Required | Description |
|---|---|---|---|
to |
string | yes | Phone number (digits only, country code required) |
name |
string | no | Contact name (used in $name, $firstName variables) |
clientData |
object | no | Extra data stored in the contact's session |
`messages[]`
| Field | Type | Required | Description |
|---|---|---|---|
text |
string | no | Message text (supports variables) |
textAlternatives |
string[] | no | Text alternatives: one is picked randomly |
image |
string | no | Image URL (.jpg, .png, .gif) |
video |
string | no | Video URL (.mp4) |
document |
string | no | Document URL (.pdf, .docx, etc.) |
list |
object | no | Interactive list message (see below) |
delay |
number | no | Delay in milliseconds before sending this message |
`delayBetweenMessages`
| Field | Type | Description |
|---|---|---|
minSecs |
number | Minimum seconds between contacts |
maxSecs |
number | Maximum seconds between contacts |
Message types
Plain text
{
"text": "Hello $name, how are you?"
}Text with alternatives (A/B)
The system randomly picks from text and textAlternatives:
{
"text": "Hello $name! How can I help you today?",
"textAlternatives": [
"Hi $name! What can I do for you?",
"Hey $name! Need anything?"
]
}Image with caption
{
"text": "Check out our updated catalog!",
"image": "https://cdn.company.com/catalog-2025.png"
}Video with caption
{
"text": "Watch the full tutorial:",
"video": "https://cdn.company.com/tutorial.mp4"
}Document
{
"text": "Here's the proposal in PDF:",
"document": "https://cdn.company.com/proposal.pdf"
}Interactive list
{
"text": "Choose an option:",
"list": {
"title": "Support Menu",
"description": "Select your contact subject",
"buttonText": "View options",
"footerText": "Verboo Support",
"sections": [
{
"title": "Support",
"rows": [
{
"rowID": "technical_support",
"title": "Technical Support",
"description": "System issues"
},
{
"rowID": "billing_support",
"title": "Billing",
"description": "Invoices and payments"
}
]
},
{
"title": "Sales",
"rows": [
{
"rowID": "plans",
"title": "View Plans",
"description": "Pricing and features"
}
]
}
]
}
}Substitution variables
Use $variable in any text, textAlternatives, webhook URL, or webhook body field.
Contact variables
| Variable | Description |
|---|---|
$name / $nome |
Contact full name |
$firstName / $first_name / $primeiroNome |
First name |
$phone |
Original phone number |
$phone.treated |
Formatted number (digits only) |
$phone.evolution |
Number in Evolution JID format (5585...@s.whatsapp.net) |
Assistant variables (webhooks)
| Variable | Description |
|---|---|
$assistant.id |
Assistant ID |
ClientData
Any key sent in the contact's clientData becomes a variable:
// contacts[].clientData
{ "plan": "premium", "source": "facebook" }
// In text
"Your $plan plan came from $source."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 9 * * 1-5 → weekdays at 9am
0 8 * * 1 → every Monday at 8am
0 14 1 * * → 1st of every month at 2pmWebhooks
Execute HTTP calls before or after sending to each contact.
{
"webhooks": [
{
"url": "https://crm.company.com/hooks/pre-send",
"method": "POST",
"headers": {
"Authorization": "Bearer $crm_token",
"Content-Type": "application/json"
},
"body": "{\"phone\": \"$phone\", \"name\": \"$name\", \"assistant\": \"$assistant.id\"}"
}
]
}Webhooks fire before messages are sent to each contact. Up to 5 webhooks run concurrently.
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 |
Execution logs
After completion, the task contains per-contact logs:
[
{
"created_at": "2025-03-10T09:00:05Z",
"success": true,
"composing_times_secs": [1200, 2400]
},
{
"created_at": "2025-03-10T09:01:12Z",
"success": false,
"error": "contact not registered on WhatsApp"
}
]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 |