| name | evolution-api-v2 |
| description | Complete WhatsApp automation via Evolution API v2.3 - instances, messages (text/media/polls/lists/buttons/status), groups, labels, chatbots (Typebot/OpenAI/Dify/Flowise/N8N/EvoAI), webhooks, proxy, S3 storage, and Chatwoot integration |
| metadata | {"openclaw":{"requires":{"bins":[]},"env":{"EVO_API_URL":"Evolution API base URL (e.g., http://localhost:8080 or https://api.yourdomain.com)","EVO_GLOBAL_KEY":"Global API key for admin operations (instance management)","EVO_INSTANCE":"Default instance name","EVO_API_KEY":"Instance-specific API key for messaging operations"}}} |
Evolution API v2.3
Complete WhatsApp automation via Evolution API v2.3. Send messages, manage groups, integrate chatbots (Typebot, OpenAI, Dify, Flowise, N8N, Evo AI), configure webhooks, and connect with Chatwoot.
Quick Start
1. Set Environment Variables
{
env: {
EVO_API_URL: "http://localhost:8080", // Your API URL
EVO_GLOBAL_KEY: "your-global-admin-key", // Admin key (instance mgmt)
EVO_INSTANCE: "my-bot", // Instance name
EVO_API_KEY: "your-instance-token" // Instance token (messaging)
}
}
2. Create Instance & Connect
curl -X POST "$EVO_API_URL/instance/create" \
-H "apikey: $EVO_GLOBAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"instanceName": "my-bot",
"qrcode": true,
"integration": "WHATSAPP-BAILEYS"
}'
curl -X GET "$EVO_API_URL/instance/connect/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY"
Scan the QR code returned in base64 field. Alternately pass ?number=5511999999999 for pairing code.
3. Send First Message
curl -X POST "$EVO_API_URL/message/sendText/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"number": "5511999999999",
"text": "Hello from Evolution API v2! 🚀"
}'
Authentication
Two authentication levels:
| Type | Header | Usage |
|---|
| Global API Key | apikey: $EVO_GLOBAL_KEY | Admin: create/delete instances, fetch all |
| Instance API Key | apikey: $EVO_API_KEY | Messaging, groups, chat, profile, labels |
All instance endpoints use the path pattern: /{resource}/{action}/{instanceName}
Core Concepts
Phone Number Formats
| Context | Format | Example |
|---|
| Sending messages | Country code + number | 5511999999999 |
| Group JID | Group ID | 999999999999999999@g.us |
| User JID | Number + suffix | 5511999999999@s.whatsapp.net |
Integration Types
| Value | Description |
|---|
WHATSAPP-BAILEYS | Unofficial (default, full features) |
WHATSAPP-BUSINESS | Official Cloud API |
EVOLUTION | Evolution channel |
Message Delay
Add delay (milliseconds) to avoid rate limits:
{ "delay": 1200 }
Feature Reference
Instance Management
Create Instance
POST /instance/create
Header: apikey: $EVO_GLOBAL_KEY
{
"instanceName": "my-bot",
"qrcode": true,
"integration": "WHATSAPP-BAILEYS",
// Optional
"token": "custom-api-key",
"number": "5511999999999",
// Settings (optional)
"rejectCall": false,
"msgCall": "",
"groupsIgnore": false,
"alwaysOnline": false,
"readMessages": false,
"readStatus": false,
"syncFullHistory": false,
// Proxy (optional)
"proxyHost": "",
"proxyPort": "",
"proxyProtocol": "",
"proxyUsername": "",
"proxyPassword": ""
}
Inline webhook (optional during creation):
{
"webhook": {
"url": "https://webhook.site/your-id",
"byEvents": false,
"base64": true,
"headers": {
"autorization": "Bearer TOKEN"
},
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"]
}
}
Inline RabbitMQ / SQS (optional during creation):
{
"rabbitmq": { "enabled": true, "events": ["MESSAGES_UPSERT"] },
"sqs": { "enabled": true, "events": ["MESSAGES_UPSERT"] }
}
Inline Chatwoot (optional during creation):
{
"chatwootAccountId": "1",
"chatwootToken": "TOKEN",
"chatwootUrl": "https://chatwoot.com",
"chatwootSignMsg": true,
"chatwootReopenConversation": true,
"chatwootConversationPending": false,
"chatwootImportContacts": true,
"chatwootNameInbox": "evolution",
"chatwootMergeBrazilContacts": true,
"chatwootImportMessages": true,
"chatwootDaysLimitImportMessages": 3
}
Fetch Instances
GET /instance/fetchInstances
Header: apikey: $EVO_GLOBAL_KEY
Connect Instance (QR Code)
GET /instance/connect/{instance}
Header: apikey: $EVO_API_KEY
Connection Status
GET /instance/connectionState/{instance}
Header: apikey: $EVO_API_KEY
Restart Instance
POST /instance/restart/{instance}
Header: apikey: $EVO_API_KEY
Set Presence
POST /instance/setPresence/{instance}
Header: apikey: $EVO_API_KEY
{ "presence": "available" }
Options: available, unavailable
Logout Instance
DELETE /instance/logout/{instance}
Header: apikey: $EVO_API_KEY
Delete Instance
DELETE /instance/delete/{instance}
Header: apikey: $EVO_GLOBAL_KEY
Settings
Set Settings
POST /settings/set/{instance}
Header: apikey: $EVO_API_KEY
{
"rejectCall": true,
"msgCall": "I do not accept calls",
"groupsIgnore": false,
"alwaysOnline": true,
"readMessages": false,
"syncFullHistory": false,
"readStatus": false
}
Find Settings
GET /settings/find/{instance}
Header: apikey: $EVO_API_KEY
Proxy
Set Proxy
POST /proxy/set/{instance}
Header: apikey: $EVO_API_KEY
{
"enabled": true,
"host": "0.0.0.0",
"port": "8000",
"protocol": "http",
"username": "user",
"password": "pass"
}
Find Proxy
GET /proxy/find/{instance}
Header: apikey: $EVO_API_KEY
Send Messages
Send Text
POST /message/sendText/{instance}
{
"number": "5511999999999",
"text": "Hello World!"
// Options:
// "delay": 1200,
// "linkPreview": false,
// "mentionsEveryOne": false,
// "mentioned": ["5511888888888"],
// "quoted": { "key": { "id": "MESSAGE_ID" }, "message": { "conversation": "quoted text" } }
}
Send Media (URL)
POST /message/sendMedia/{instance}
{
"number": "5511999999999",
"mediatype": "image",
"mimetype": "image/png",
"caption": "Caption text",
"media": "https://example.com/photo.jpg",
"fileName": "photo.png"
// Options: delay, quoted, mentionsEveryOne, mentioned
}
Media types: image, video, document
Send Media (File Upload)
POST /message/sendMedia/{instance}
Content-Type: multipart/form-data
Send PTV (Round Video)
POST /message/sendPtv/{instance}
{
"number": "5511999999999",
"video": "https://example.com/video.mp4"
// Options: delay, quoted, mentionsEveryOne, mentioned
}
Also supports file upload via form-data.
Send Narrated Audio (Voice Note)
POST /message/sendWhatsAppAudio/{instance}
{
"number": "5511999999999",
"audio": "https://example.com/audio.mp3"
// Options: delay, quoted, encoding (true/false)
}
Send Status/Stories
POST /message/sendStatus/{instance}
{
"type": "text",
"content": "My status update!",
"backgroundColor": "#008000",
"font": 1,
"allContacts": false,
"statusJidList": ["5511999999999@s.whatsapp.net"]
}
Types: text, image, video, audio
Fonts (text only): 1 SERIF, 2 NORICAN_REGULAR, 3 BRYNDAN_WRITE, 4 BEBASNEUE_REGULAR, 5 OSWALD_HEAVY
For image/video: use content as URL and caption for text.
Send Sticker
POST /message/sendSticker/{instance}
{
"number": "5511999999999",
"sticker": "https://example.com/sticker.webp"
// Options: delay, quoted
}
Send Location
POST /message/sendLocation/{instance}
{
"number": "5511999999999",
"name": "Bora Bora",
"address": "French Polynesia",
"latitude": -16.505538,
"longitude": -151.742277
// Options: delay, quoted
}
Send Contact (vCard)
POST /message/sendContact/{instance}
{
"number": "5511999999999",
"contact": [
{
"fullName": "Contact Name",
"wuid": "559999999999",
"phoneNumber": "+55 99 9 9999-9999",
"organization": "Company",
"email": "email@example.com",
"url": "https://example.com"
}
]
}
Multiple contacts can be sent in the array.
Send Reaction
POST /message/sendReaction/{instance}
{
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": true,
"id": "BAE5A75CB0F39712"
},
"reaction": "🚀"
}
Set reaction: "" to remove.
Send Poll
POST /message/sendPoll/{instance}
{
"number": "5511999999999",
"name": "What is your favorite color?",
"selectableCount": 1,
"values": ["Red", "Blue", "Green"]
// Options: delay, quoted
}
Send List
POST /message/sendList/{instance}
{
"number": "5511999999999",
"title": "List Title",
"description": "Choose an option",
"buttonText": "Click Here",
"footerText": "Footer text",
"sections": [
{
"title": "Section 1",
"rows": [
{
"title": "Option A",
"description": "Description of option A",
"rowId": "opt_a"
},
{
"title": "Option B",
"description": "Description of option B",
"rowId": "opt_b"
}
]
}
]
// Options: delay, quoted
}
Send Buttons
POST /message/sendButtons/{instance}
{
"number": "5511999999999",
"title": "Button Title",
"description": "Button Description",
"footer": "Footer Text",
"buttons": [
{ "type": "reply", "displayText": "Reply", "id": "btn_1" },
{ "type": "copy", "displayText": "Copy Code", "copyCode": "ABC123" },
{ "type": "url", "displayText": "Open Link", "url": "https://example.com" },
{ "type": "call", "displayText": "Call Us", "phoneNumber": "5511999999999" },
{ "type": "pix", "currency": "BRL", "name": "John Doe", "keyType": "random", "key": "uuid-key" }
]
// Options: delay, quoted
}
Button types: reply, copy, url, call, pix
Pix keyType: phone, email, cpf, cnpj, random
Chat Operations
Check WhatsApp Numbers
POST /chat/whatsappNumbers/{instance}
{
"numbers": [
"55911111111",
"55922222222",
"55933333333"
]
}
Read Messages (Mark as Read)
POST /chat/markMessageAsRead/{instance}
{
"readMessages": [
{
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "MESSAGE_ID"
}
]
}
Archive Chat
POST /chat/archiveChat/{instance}
{
"lastMessage": {
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "MESSAGE_ID"
}
},
"chat": "5511999999999@s.whatsapp.net",
"archive": true
}
Set archive: false to unarchive.
Mark Chat Unread
POST /chat/markChatUnread/{instance}
{
"lastMessage": {
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "MESSAGE_ID"
}
},
"chat": "5511999999999@s.whatsapp.net"
}
Delete Message
DELETE /chat/deleteMessageForEveryone/{instance}
{
"id": "MESSAGE_ID",
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": true,
"participant": "participant_jid"
}
Update Message (Edit)
POST /chat/updateMessage/{instance}
{
"number": "5511999999999",
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": true,
"id": "MESSAGE_ID"
},
"text": "new edited message"
}
Send Presence (Typing Indicator)
POST /chat/sendPresence/{instance}
{
"number": "5511999999999",
"delay": 1200,
"presence": "composing"
}
Options: composing, recording, paused
Update Block Status
POST /message/updateBlockStatus/{instance}
{
"number": "5511999999999",
"status": "block"
}
Options: block, unblock
Fetch Profile Picture
POST /chat/fetchProfilePictureUrl/{instance}
{ "number": "5511999999999" }
Get Base64 From Media Message
POST /chat/getBase64FromMediaMessage/{instance}
{
"message": {
"key": { "id": "MESSAGE_ID" }
},
"convertToMp4": false
}
Extracts base64 from received media. Set convertToMp4: true for audio files to get MP4 instead of OGG.
Find Contacts
POST /chat/findContacts/{instance}
{
"where": {
"id": "5511999999999"
}
}
Omit id to list all contacts.
Find Messages
POST /chat/findMessages/{instance}
{
"where": {
"key": {
"remoteJid": "5511999999999"
}
},
"page": 1,
"offset": 10
}
Find Status Message
POST /chat/findStatusMessage/{instance}
{
"where": {
"remoteJid": "5511999999999@s.whatsapp.net",
"id": "MESSAGE_ID"
},
"page": 1,
"offset": 10
}
Find Chats
POST /chat/findChats/{instance}
Calls
Fake Call (Offer)
POST /call/offer/{instance}
{
"number": "5511999999999",
"isVideo": false,
"callDuration": 3
}
Simulates a call offer to the number. callDuration is in seconds.
Labels
Find Labels
GET /label/findLabels/{instance}
Handle Labels (Add/Remove)
POST /label/handleLabel/{instance}
{
"number": "5511999999999",
"labelId": "label_id_here",
"action": "add"
}
Actions: add, remove
Profile Settings
Fetch Business Profile
POST /chat/fetchBusinessProfile/{instance}
{ "number": "5511999999999" }
Fetch Profile
POST /chat/fetchProfile/{instance}
{ "number": "5511999999999" }
Update Profile Name
POST /chat/updateProfileName/{instance}
{ "name": "My Bot Name" }
Update Profile Status
POST /chat/updateProfileStatus/{instance}
{ "status": "Available 24/7" }
Update Profile Picture
POST /chat/updateProfilePicture/{instance}
{ "picture": "https://example.com/avatar.jpg" }
Remove Profile Picture
DELETE /chat/removeProfilePicture/{instance}
Fetch Privacy Settings
GET /chat/fetchPrivacySettings/{instance}
Update Privacy Settings
POST /chat/updatePrivacySettings/{instance}
{
"readreceipts": "all",
"profile": "all",
"status": "contacts",
"online": "all",
"last": "contacts",
"groupadd": "none"
}
Privacy values:
readreceipts: all, none
profile: all, contacts, contact_blacklist, none
status: all, contacts, contact_blacklist, none
online: all, match_last_seen
last: all, contacts, contact_blacklist, none
groupadd: all, contacts, contact_blacklist
Group Management
Create Group
POST /group/create/{instance}
{
"subject": "Group Name",
"description": "Group description (optional)",
"participants": [
"5531900000000",
"5531900000000"
]
}
Update Group Picture
POST /group/updateGroupPicture/{instance}?groupJid={groupJid}
{ "image": "https://example.com/group-photo.png" }
Update Group Subject (Name)
POST /group/updateGroupSubject/{instance}?groupJid={groupJid}
{ "subject": "New Group Name" }
Update Group Description
POST /group/updateGroupDescription/{instance}?groupJid={groupJid}
{ "description": "New group description" }
Fetch Invite Code
GET /group/inviteCode/{instance}?groupJid={groupJid}
Revoke Invite Code
POST /group/revokeInviteCode/{instance}?groupJid={groupJid}
Send Invite URL
POST /group/sendInvite/{instance}
{
"groupJid": "999999999@g.us",
"description": "Join my WhatsApp group:",
"numbers": ["5511999999999"]
}
Find Group by Invite Code
GET /group/inviteInfo/{instance}?inviteCode={inviteCode}
Find Group by JID
GET /group/findGroupInfos/{instance}?groupJid={groupJid}
Fetch All Groups
GET /group/fetchAllGroups/{instance}
Find Participants
GET /group/participants/{instance}?groupJid={groupJid}
Update Participants
POST /group/updateParticipant/{instance}?groupJid={groupJid}
{
"action": "add",
"participants": ["5511999999999"]
}
Actions: add, remove, promote, demote
Update Group Settings
POST /group/updateSetting/{instance}?groupJid={groupJid}
{ "action": "announcement" }
Actions:
announcement - Only admins send messages
not_announcement - Everyone can send
locked - Only admins edit group info
unlocked - Everyone can edit group info
Toggle Ephemeral (Disappearing Messages)
POST /group/toggleEphemeral/{instance}?groupJid={groupJid}
{ "expiration": 86400 }
Expiration values (seconds):
0 - Off
86400 - 24 hours
604800 - 7 days
7776000 - 90 days
Leave Group
DELETE /group/leaveGroup/{instance}?groupJid={groupJid}
Integrations - Events
Webhook
POST /webhook/set/{instance}
{
"webhook": {
"enabled": true,
"url": "https://webhook.site/your-id",
"headers": {
"autorization": "Bearer TOKEN",
"Content-Type": "application/json"
},
"byEvents": false,
"base64": false,
"events": [
"APPLICATION_STARTUP",
"QRCODE_UPDATED",
"MESSAGES_UPSERT",
"MESSAGES_UPDATE",
"MESSAGES_DELETE",
"SEND_MESSAGE",
"CONTACTS_UPDATE",
"PRESENCE_UPDATE",
"CHATS_UPDATE",
"CHATS_DELETE",
"GROUPS_UPSERT",
"GROUP_UPDATE",
"GROUP_PARTICIPANTS_UPDATE",
"CONNECTION_UPDATE",
"LABELS_EDIT",
"LABELS_ASSOCIATION",
"CALL",
"TYPEBOT_START",
"TYPEBOT_CHANGE_STATUS"
]
}
}
GET /webhook/find/{instance}
Key options:
byEvents - If true, sends to separate URLs per event type
base64 - If true, media comes as base64 in payload
WebSocket
POST /websocket/set/{instance}
{
"websocket": {
"enabled": true,
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"]
}
}
GET /websocket/find/{instance}
RabbitMQ
POST /rabbitmq/set/{instance}
{
"rabbitmq": {
"enabled": true,
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"]
}
}
GET /rabbitmq/find/{instance}
SQS (Amazon)
POST /sqs/set/{instance}
{
"sqs": {
"enabled": true,
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"]
}
}
GET /sqs/find/{instance}
NATS
POST /nats/set/{instance}
GET /nats/find/{instance}
Same payload structure as SQS/RabbitMQ.
Pusher
POST /pusher/set/{instance}
GET /pusher/find/{instance}
Same payload structure as SQS/RabbitMQ.
Available Events (all transports):
APPLICATION_STARTUP, QRCODE_UPDATED, MESSAGES_SET, MESSAGES_UPSERT, MESSAGES_UPDATE, MESSAGES_DELETE, SEND_MESSAGE, CONTACTS_SET, CONTACTS_UPSERT, CONTACTS_UPDATE, PRESENCE_UPDATE, CHATS_SET, CHATS_UPSERT, CHATS_UPDATE, CHATS_DELETE, GROUPS_UPSERT, GROUP_UPDATE, GROUP_PARTICIPANTS_UPDATE, CONNECTION_UPDATE, LABELS_EDIT, LABELS_ASSOCIATION, CALL, TYPEBOT_START, TYPEBOT_CHANGE_STATUS
Integrations - Chatbots
All chatbot integrations share a common pattern with settings, session management, CRUD, and trigger configuration.
Common trigger options (all chatbots):
{
"triggerType": "keyword",
"triggerOperator": "equals",
"triggerValue": "hello",
"expire": 20,
"keywordFinish": "#SAIR",
"delayMessage": 1000,
"unknownMessage": "Message not recognized",
"listeningFromMe": false,
"stopBotFromMe": false,
"keepOpen": false,
"debounceTime": 10,
"ignoreJids": []
}
| Field | Description |
|---|
triggerType | all (every message) or keyword (matched) |
triggerOperator | contains, equals, startsWith, endsWith, regex, none |
triggerValue | The keyword/pattern to match |
expire | Session timeout (minutes) |
keywordFinish | Keyword to end bot session |
delayMessage | Delay between messages (ms) |
unknownMessage | Response for unrecognized input |
listeningFromMe | Process messages sent by you |
stopBotFromMe | Pause bot when you send a message |
keepOpen | Keep session alive after flow ends |
debounceTime | Debounce interval (seconds) |
ignoreJids | JIDs to ignore (e.g., ["@g.us"] to ignore groups) |
Chatwoot
POST /chatwoot/set/{instance}
{
"enabled": true,
"accountId": "1",
"token": "CHATWOOT_TOKEN",
"url": "https://chatwoot.yourdomain.com",
"signMsg": true,
"reopenConversation": true,
"conversationPending": false,
"nameInbox": "evolution",
"mergeBrazilContacts": true,
"importContacts": true,
"importMessages": true,
"daysLimitImportMessages": 2,
"signDelimiter": "\n",
"autoCreate": true,
"organization": "BOT",
"logo": "https://example.com/logo.png",
"ignoreJids": ["@g.us"]
}
GET /chatwoot/find/{instance}
Typebot
POST /typebot/create/{instance}
{
"enabled": true,
"url": "https://typebot.yourdomain.com",
"typebot": "my-typebot-flow-id",
"triggerType": "keyword",
"triggerOperator": "regex",
"triggerValue": "^atend.*",
"expire": 20,
"keywordFinish": "#SAIR",
"delayMessage": 1000,
"unknownMessage": "Message not recognized",
"listeningFromMe": false,
"stopBotFromMe": false,
"keepOpen": false,
"debounceTime": 10
}
GET /typebot/find/{instance}
GET /typebot/fetch/{typebotId}/{instance}
PUT /typebot/update/{typebotId}/{instance}
DELETE /typebot/delete/{typebotId}/{instance}
POST /typebot/start/{instance}
{
"url": "https://typebot.yourdomain.com",
"typebot": "flow-id",
"remoteJid": "5511999999999@s.whatsapp.net",
"startSession": false,
"variables": [
{ "name": "pushName", "value": "User Name" }
]
}
POST /typebot/changeStatus/{instance}
{ "remoteJid": "5511999999999@s.whatsapp.net", "status": }
GET /typebot/fetchSessions/{typebotId}/{instance}
POST /typebot/settings/{instance}
GET /typebot/fetchSettings/{instance}
{
: 20,
: ,
: 1000,
: ,
: ,
: ,
: ,
: 10,
: [],
:
}
Session statuses: opened, paused, closed
OpenAI
POST /openai/creds/{instance}
{ "name": "apikey", "apiKey": "sk-proj-..." }
GET /openai/creds/{instance}
DELETE /openai/creds/{openaiCredsId}/{instance}
POST /openai/create/{instance}
{
"enabled": true,
"openaiCredsId": "creds-id",
"botType": "assistant",
// For assistants:
"assistantId": "asst_XXXXX",
"functionUrl": "https://n8n.site.com",
// For chatCompletion:
"model": "gpt-4o",
"systemMessages": ["You are a helpful assistant."],
"assistantMessages": ["Hello, how can I help?"],
"userMessages": ["Hello!"],
"maxTokens": 300,
// Trigger options...
"triggerType": "keyword",
"triggerOperator": "equals",
"triggerValue": "ai"
}
GET /openai/find/{instance}
GET /openai/fetch/{openaiBotId}/{instance}
PUT /openai/update/{openaiBotId}/{instance}
DELETE /openai/delete/{openaiBotId}/{instance}
POST /openai/changeStatus/{instance}
GET /openai/fetchSessions/{openaiBotId}/{instance}
POST /openai/settings/{instance}
GET /openai/fetchSettings/{instance}
Bot types: assistant, chatCompletion
Dify
POST /dify/create/{instance}
{
"enabled": true,
"botType": "chatBot",
"apiUrl": "http://dify.site.com/v1",
"apiKey": "app-123456",
// Trigger options...
}
GET /dify/find/{instance}
GET /dify/fetch/{difyId}/{instance}
PUT /dify/update/{difyId}/{instance}
DELETE /dify/delete/{difyId}/{instance}
POST /dify/changeStatus/{instance}
GET /dify/fetchSessions/{difyId}/{instance}
POST /dify/settings/{instance}
GET /dify/fetchSettings/{instance}
Dify bot types: chatBot, textGenerator, agent, workflow
Flowise
POST /flowise/create/{instance}
{
"enabled": true,
"apiUrl": "http://flowise.site.com/v1",
"apiKey": "app-123456",
// Trigger options...
}
GET /flowise/find/{instance}
GET /flowise/fetch/{flowiseId}/{instance}
PUT /flowise/update/{flowiseId}/{instance}
DELETE /flowise/delete/{flowiseId}/{instance}
POST /flowise/changeStatus/{instance}
GET /flowise/fetchSessions/{flowiseId}/{instance}
POST /flowise/settings/{instance}
GET /flowise/fetchSettings/{instance}
N8N
POST /n8n/create/{instance}
{
"enabled": true,
"apiUrl": "http://n8n.site.com/v1",
"apiKey": "app-123456",
// Trigger options...
}
GET /n8n/find/{instance}
GET /n8n/fetch/{n8nId}/{instance}
PUT /n8n/update/{n8nId}/{instance}
DELETE /n8n/delete/{n8nId}/{instance}
POST /n8n/changeStatus/{instance}
GET /n8n/fetchSessions/{n8nId}/{instance}
POST /n8n/settings/{instance}
GET /n8n/fetchSettings/{instance}
Evolution Bot
POST /evolutionBot/create/{instance}
{
"enabled": true,
"apiUrl": "http://api.site.com/v1",
"apiKey": "app-123456",
// Trigger options...
}
GET /evolutionBot/find/{instance}
GET /evolutionBot/fetch/{evolutionBotId}/{instance}
PUT /evolutionBot/update/{evolutionBotId}/{instance}
DELETE /evolutionBot/delete/{evolutionBotId}/{instance}
POST /evolutionBot/changeStatus/{instance}
GET /evolutionBot/fetchSessions/{evolutionBotId}/{instance}
POST /evolutionBot/settings/{instance}
GET /evolutionBot/fetchSettings/{instance}
Evo AI
POST /evoai/create/{instance}
{
"enabled": true,
"apiUrl": "http://evoai.site.com/v1",
"apiKey": "app-123456",
// Trigger options...
}
GET /evoai/find/{instance}
GET /evoai/fetch/{evoaiId}/{instance}
PUT /evoai/update/{evoaiId}/{instance}
DELETE /evoai/delete/{evoaiId}/{instance}
POST /evoai/changeStatus/{instance}
GET /evoai/fetchSessions/{evoaiId}/{instance}
POST /evoai/settings/{instance}
GET /evoai/fetchSettings/{instance}
Integrations - Channel (WhatsApp Business Cloud API)
Send Template
POST /message/sendTemplate/{instance}
{
"number": "5511999999999",
"name": "hello_world",
"language": "en_US",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "John" },
{ "type": "text", "text": "email@email.com" }
]
},
{
"type": "button",
"sub_type": "URL",
"index": "1",
"parameters": [
{ "type": "text", "text": "/reset-password/1234" }
]
}
]
}
Create Template
POST /template/create/{instance}
{
"name": "my_template",
"category": "MARKETING",
"allowCategoryChange": false,
"language": "en_US",
"components": [
{
"type": "BODY",
"text": "Thank you {{1}}! Confirmation: {{2}}",
"example": {
"body_text": [["John", "860198-230332"]]
}
},
{
"type": "BUTTONS",
"buttons": [
{ "type": "QUICK_REPLY", "text": "Unsubscribe" },
{ "type": "URL", "text": "Support", "url": "https://example.com" }
]
}
]
}
Categories: AUTHENTICATION, MARKETING, UTILITY
Find Templates
GET /template/find/{instance}
Evolution Channel Webhook
POST /webhook/evolution
{
"numberId": "5511999999999",
"key": {
"remoteJid": "5511888888888",
"fromMe": false,
"id": "ABC1234"
},
"pushName": "Contact Name",
"message": {
"conversation": "Hello"
},
"messageType": "conversation"
}
Message types: conversation, imageMessage, videoMessage, documentMessage, audioMessage
Storage (S3/MinIO)
Get Media
POST /s3/getMedia/{instance}
{
"id": "media-id",
"type": "image",
"messageId": "MESSAGE_ID"
}
Get Media URL
POST /s3/getMediaUrl/{instance}
{
"id": "media-id"
}
System
Get API Information
GET /
Returns API version and system info.
Metrics
GET /metrics
Authorization: Basic (METRICS_USER:password)
Common Workflows
Broadcast Message
for number in 5511999999999 5511888888888 5511777777777; do
curl -X POST "$EVO_API_URL/message/sendText/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"number\": \"$number\",
\"text\": \"Broadcast message!\",
\"delay\": 2000
}"
done
Auto-Create Group + Configure Bot
curl -X POST "$EVO_API_URL/group/create/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Support Group",
"participants": ["5511999999999"]
}'
curl -X POST "$EVO_API_URL/typebot/create/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"url": "https://typebot.yourdomain.com",
"typebot": "support-flow-id",
"triggerType": "all"
}'
Full Instance Setup (Instance + Webhook + Chatwoot)
curl -X POST "$EVO_API_URL/instance/create" \
-H "apikey: $EVO_GLOBAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"instanceName": "support-bot",
"qrcode": true,
"integration": "WHATSAPP-BAILEYS",
"webhook": {
"url": "https://n8n.yourdomain.com/webhook/evo",
"byEvents": false,
"base64": false,
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"]
}
}'
curl -X GET "$EVO_API_URL/instance/connect/support-bot" \
-H "apikey: $EVO_API_KEY"
curl -X POST "$EVO_API_URL/chatwoot/set/support-bot" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"accountId": "1",
"token": "CHATWOOT_TOKEN",
"url": "https://chatwoot.yourdomain.com",
"signMsg": true,
"importContacts": true,
"importMessages": true,
"autoCreate": true,
"nameInbox": "support-bot"
}'
Check Numbers Before Sending
curl -X POST "$EVO_API_URL/chat/whatsappNumbers/$EVO_INSTANCE" \
-H "apikey: $EVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "numbers": ["5511999999999", "5511888888888"] }'
Rate Limits & Best Practices
Delays
Always add delays between messages:
{ "delay": 1200 }
Recommended:
- 1-2 seconds between individual messages
- 3-5 seconds between mass sends
- Exponential backoff on errors
Error Handling
| Status | Meaning |
|---|
200 | Success |
400 | Bad request (check body/params) |
401 | Unauthorized (check API key) |
404 | Not found (instance/resource) |
500 | Server error |
Common Issues
| Error | Solution |
|---|
| Instance not connected | Run GET /instance/connect/{instance} |
| Invalid phone format | Use country code without +: 5511999999999 |
| Message not sent | Check GET /instance/connectionState/{instance} |
| Group operation failed | Verify you're admin |
| Media extraction fails | Ensure MongoDB/file storage is enabled |
| Chatwoot not syncing | Check token and URL, verify importMessages is true |
Troubleshooting
Instance Won't Connect
GET /instance/fetchInstances
POST /instance/restart/{instance}
GET /instance/connect/{instance}
Chatbot Not Responding
- Check bot is enabled:
GET /{botType}/find/{instance}
- Check trigger matches incoming message
- Check session status:
GET /{botType}/fetchSessions/{botId}/{instance}
- Reset session:
POST /{botType}/changeStatus/{instance} with status: "closed"
Messages Not Being Delivered
- Verify connection:
GET /instance/connectionState/{instance}
- Check phone format (no
+, no spaces)
- Verify recipient has WhatsApp:
POST /chat/whatsappNumbers/{instance}
- Check webhook for delivery status events
v2 vs v3 (Evolution Go) Differences
| Feature | v2.3 | v3 (Go) |
|---|
| Language | Node.js/TypeScript | Go |
| Endpoints | /message/sendText/{instance} | /send/text |
| Chatbot integrations | 7 (Typebot, OpenAI, Dify, Flowise, N8N, EvolutionBot, EvoAI) | Fewer built-in |
| Chatwoot | Native integration | Separate |
| Event transports | 6 (Webhook, WS, RabbitMQ, SQS, NATS, Pusher) | Fewer |
| Lists/Buttons | Supported | Deprecated |
| PTV (Round Video) | Supported | Supported |
| Status/Stories | Supported | Supported |
| Templates | Business Cloud API | Business Cloud API |
| S3 Storage | Built-in | Separate |
Resources
Tips
- Always check connection before operations
- Use delays to avoid rate limits (1.2s+ between messages)
- Store keys in environment variables, never hardcode
- Handle disconnects with webhook
CONNECTION_UPDATE event
- Validate numbers with
whatsappNumbers before bulk sends
- Use
debounceTime in chatbots to group fast messages
- Set
ignoreJids: ["@g.us"] in chatbots to ignore group messages
- Test triggers with
triggerType: "keyword" before switching to "all"
- Monitor sessions - expired sessions stop chatbot responses
- Use Chatwoot for human handoff from chatbot flows