| title | Webhooks |
|---|---|
| icon | webhook |
Webhooks allow real-time integration between the Evolution API and WhatsApp™, enabling automated data synchronization and sharing.
This feature is exactly what makes it possible to create self-service bots and multi-service systems.
There are two ways to enable the webhook:
- In the
.envfile with global events - By calling the
/webhook/instanceendpoint
Most users will prefer instance-based activation, as it makes it easier to control the received events. However, in some cases, a global webhook is necessary. This can be done using the global webhook variable.
Here is an example with some common events being listened to:
{
"url": "{{webhookUrl}}",
"webhook_by_events": false,
"webhook_base64": false,
"events": [
"QRCODE_UPDATED",
"MESSAGES_UPSERT",
"MESSAGES_UPDATE",
"MESSAGES_DELETE",
"SEND_MESSAGE",
"CONNECTION_UPDATE",
"TYPEBOT_START",
"TYPEBOT_CHANGE_STATUS"
]
}| Parameter | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | Yes | Enter "true" to create or change Webhook data, or "false" if you want to stop using it. |
| url | string | Yes | Webhook URL to receive event data. |
| headers | object | No | Custom HTTP headers sent with every webhook request. See Custom Headers. |
| webhook_by_events | boolean | No | Whether to generate a specific Webhook URL for each of your events. |
| base64 | boolean | No | Encode media as base64 in the webhook payload. |
| events | array | No | List of events to be processed. If you don't want to use some of these events, simply remove them from the list. |
You can configure custom HTTP headers that will be sent with every webhook request for the instance. This is useful for authentication, identification, and integration with external systems that require tokens or API keys.
The headers field accepts any JSON object with string key-value pairs.
{
"webhook": {
"enabled": true,
"url": "https://your-endpoint.com/webhook",
"headers": {
"Authorization": "Bearer your-token-here",
"X-Api-Key": "your-secret-key"
},
"events": [
"MESSAGES_UPSERT",
"CONNECTION_UPDATE"
],
"byEvents": false,
"base64": false
}
}Any valid HTTP header can be used. Below are the most common patterns:
"headers": {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."
}"headers": {
"X-Api-Key": "your-key-here"
}"headers": {
"Authorization": "Basic dXNlcjpwYXNzd29yZA=="
}You can combine as many headers as needed:
"headers": {
"Authorization": "Bearer token",
"X-Tenant-Id": "company-123",
"X-Source": "evolution-api"
}Evolution API has a special feature for automatic JWT token generation. When you set the jwt_key key in the headers, the API will:
- Use the value as a secret key to sign a JWT token (HS256 algorithm)
- Generate a new token for each event with the following payload:
{ "iat": 1711367040, "exp": 1711367640, "app": "evolution", "action": "webhook" } - Send the token in the
Authorization: Bearer <generated_jwt>header - The
jwt_keyitself is not sent as a header — it is removed before sending
"headers": {
"jwt_key": "your-secret-signing-key"
}Every webhook request will be sent with the header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
On your server, validate the token using the same secret key configured in jwt_key with the HS256 algorithm.
You can combine jwt_key with other custom headers:
"headers": {
"jwt_key": "secret-key",
"X-Tenant-Id": "company-123"
}In this case, the request will be sent with Authorization: Bearer <jwt> and X-Tenant-Id: company-123.
You can also configure headers directly when creating an instance:
{
"instanceName": "my-instance",
"integration": "WHATSAPP-BAILEYS",
"qrcode": true,
"webhook": {
"url": "https://your-endpoint.com/webhook",
"headers": {
"Authorization": "Bearer my-token"
},
"events": ["MESSAGES_UPSERT", "CONNECTION_UPDATE"],
"byEvents": false,
"base64": false
}
}Each instance's Webhook URL and events will be requested when they are created. Set up a global webhook that will listen to enabled events from all instances.
WEBHOOK_GLOBAL_URL=''
WEBHOOK_GLOBAL_ENABLED=false
# With this option enabled, you work with one URL per webhook event, respecting the global URL and each event's name
WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false
## Set the events you want to listen to; all events listed below are supported
WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true
# Some extra events for errors
WEBHOOK_EVENTS_ERRORS=false
WEBHOOK_EVENTS_ERRORS_WEBHOOK=These are the available and supported webhook events:
| Environment Variable | URL | Description |
|---|---|---|
| APPLICATION_STARTUP | /application-startup | Notifies when an application startup occurs |
| QRCODE_UPDATED | /qrcode-updated | Sends the QR code in base64 format for scanning |
| CONNECTION_UPDATE | /connection-update | Informs the status of the WhatsApp connection |
| MESSAGES_SET | /messages-set | Sends a list of all messages loaded in WhatsApp. This event occurs only once |
| MESSAGES_UPSERT | /messages-upsert | Notifies when a message is received |
| MESSAGES_UPDATE | /messages-update | Informs when a message is updated |
| MESSAGES_DELETE | /messages-delete | Informs when a message is deleted |
| SEND_MESSAGE | /send-message | Notifies when a message is sent |
| CONTACTS_SET | /contacts-set | Performs the initial loading of all contacts. This event occurs only once |
| CONTACTS_UPSERT | /contacts-upsert | Reloads all contacts with additional information. This event occurs only once |
| CONTACTS_UPDATE | /contacts-update | Informs when a contact is updated |
| PRESENCE_UPDATE | /presence-update | Informs if the user is online, performing an action such as typing or recording, and their last seen status: 'unavailable', 'available', 'typing', 'recording', 'paused' |
| CHATS_SET | /chats-set | Sends a list of all loaded chats |
| CHATS_UPDATE | /chats-update | Informs when a chat is updated |
| CHATS_UPSERT | /chats-upsert | Sends any new chat information |
| CHATS_DELETE | /chats-delete | Notifies when a chat is deleted |
| GROUPS_UPSERT | /groups-upsert | Notifies when a group is created |
| GROUPS_UPDATE | /groups-update | Notifies when a group has its information updated |
| GROUP_PARTICIPANTS_UPDATE | /group-participants-update | Notifies when an action occurs involving a participant: 'add', 'remove', 'promote', 'demote' |
| NEW_TOKEN | /new-jwt | Notifies when the token (jwt) is updated |
When enabling the WEBHOOK_BY_EVENTS options in both global and local webhooks, the following paths will be appended to the end of the webhook URL.
Add the event name at the end of the URL with a hyphen (-) between the words that make up the event.Suppose your webhook URL is https://sub.domain.com/webhook/. Evolution will automatically add the event name to the end of the URL when webhook_by_events is set to true.
If necessary, there is an option to locate any active webhook on the specific instance.
| Method | Endpoint |
|---|---|
| GET | [baseUrl]/webhook/find/[instance] |
Calling the endpoint will return all information about the webhook being used by the instance.
{
"enabled": true,
"url": "[url]",
"headers": {
"Authorization": "Bearer configured-token"
},
"webhookByEvents": false,
"events": [
[events]
]
}