In this article, we tell you how to connect webhooks, in what form we send them, and what we expect in response.
How we send webhooks and what we expect in return
We send webhooks using the POST method to the specified URI. It may include a query “string”.
If we have your crmKey, we add the Authorization: Bearer ${crmKey} header. If not, we don’t add the Authorization header at all.
Webhooks contain JSON in the body and the corresponding header Content-Type: application/json; charset-utf-8. An object is encoded in JSON with properties that correspond to webhook types.
One webhook can contain messages and statuses types at the same time. The webhooks of the createContact and createDeal types always contain only one type.
In response, we expect the code 200 OK. In some cases, we wait for certain information in the body of the response. Timeout — 30 s.
How to enable webhooks
To subscribe to webhooks, you must invoke:
PATCH https://api.wazzup24.com/v3/webhooks
The body must contain JSON with parameters:
Parameter | Type | Description |
webhooksUri | String | Address to receive webhooks. No more than 200 characters |
subscriptions | Object | Webhook settings |
subscriptions.messagesAndStatuses | Boolean | Webhook on new messages and webhook on outgoing status changes.
If the webhook is required, specify “true”. If not, specify “false”. |
subscriptions.contactsAndDealsCreation | Boolean | Webhook about creating a new contact or deal.
If the webhook is required, specify “true”. If not, specify “false”. |
subscriptions.channelsUpdates | Boolean | Webhook about changing the status of the channel.
If the webhook is required, specify “true”. If not, specify “false”. |
subscriptions.templateStatus | Boolean | Webhook about the change in moderation status of the WABA template.
If the webhook is required, specify “true”. If not, specify “false”. |
When connecting to the specified url, a POST test request {test: true } will be sent, in reply to which the server should return 200 if webhooks are successfully connected, otherwise a :”Webhooks request not valid. Response status must be 200″.
Request example
curl --location --request PATCH 'https://api.wazzup24.com/v3/webhooks' \ --header 'Authorization: Bearer w11cf3444405648267f900520d454368d27' \ --header 'Content-Type: application/json' \ --data-raw '{ "webhooksUri": "https://example.com/webhooks", "subscriptions": { "messagesAndStatuses": true, "contactsAndDealsCreation": true } }'
Response example
{ ok }
Errors
In addition to common errors for all routes, there can be:
Error | Description |
400 Bad Request, { error: ‘uriNotValid’, description: ‘Provided URI is not valid URI’ } | If the URI is incorrect according to the formal characteristics |
400 Bad Request, { error: ‘testPostNotPassed’, description: ‘URI does not return 200 OK on test request’, data: { ‘${код ответа}’ } } | If there was an error when sending a test request to the specified URL |
Checking the address for receiving webhooks
To check the currently set callback URL, call
GET https://api.wazzup24.com/v3/webhooks
Response example
HTTP/1.1 200 OK ``json { "webhooksUri": "https://example.com/webhooks", { "subscriptions": { { "messagesAndStatuses": { "true", { "contactsAndDealsCreation": "true" } } ``
Webhook about new messages
The webhook will send a JSON object with the messages key, the value of which is an array of objects with the following parameters:
Parameter | Type | Description |
messageId | String (uuid4) | guid Wazzup messages |
channelId | String (uuid4) | Channel id |
chatType | String | Available values:
|
chatId | String | Chat Id (contact’s account in messenger):
|
dateTime | String | The message sending time specified by the messenger in the format yyyy-mm-ddThh:mm:ss.ms |
type | String | Message type:
|
status | String | Contains only value from ENUM of webhook “statuses”:
|
error | Object | Comes if ‘status: error’ |
error.error | String | Error types:
|
error.description | String | Error description |
text | String | Message text. May not be present if the message has content |
contentUri | String | Link to message content (may not exist if the message does not contain content) |
authorName | String | The sender’s name, if there is one. Only present in messages isEcho = true |
authorId | String | User ID in your CRM |
isEcho | Boolean | If the message is incoming — false, if it is outgoing, sent not from this API (from a phone or iframe) — true |
instPost | Object | Information about the post from Instagram. Applied when the post is an Instagram comment |
contact | Object | Information about contact |
contact.name | String | Contact name |
contact.avatarUri | String | The URI of the contact’s avatar. Applied if an avatar is in Wazzup |
contact.username | String | For Telegram only. Username of a Telegram contact, with no @ at the beginning |
contact.phone | String | Telegram only. Contact phone number in international format |
interactive | Interactive | Array of objects with Salesbot amoCRM buttons attached to the message |
quotedMessage | Object | Contains an object with the parameters of the quoted message |
A view of the object with information about the Instagram post
{ id: '2430659146657243411_41370968890', src: 'https://www.instagram.com/p/CG7b52ejyET', sha1: 'dc8c036b4a0122bb238fc38dcb0391c125e916f2', likes: 0, author: 'wztestdlv', comments: 22, timestamp: 1603977171000, updatedAt: 1608905897958, authorName: '', authorId: '798633247', description: 'Beauty', previewSha1: '3a55c2920912de4b6a66d24568470dd4ad367c34', imageSrc: 'https://store.dev-wazzup24.com/dc8c036b4a0122bb238fc38dcb0391c125e916f2', previewSrc: 'https://store.dev-wazzup24.com/3a55c2920912de4b6a66d24568470dd4ad367c34' }
Webhook about updating the status of outgoing messages
The webhook will send a JSON object with the messages key, the value of which will contain an array of objects with the following parameters:
Parameter | Type | Description |
messageId | String | guid Wazzup messages |
timestamp | String | The time of receiving status update information |
status | String | the status of the message that was updated: ENUM (‘sent’|’delivered’|’read’|’error’) |
error | Object | Optional, comes only when ‘status’: ‘error’ |
error.error | String | Error code |
error.description | String | Error description |
error.[data] | String | More information about the error |
{ "messages": [ { "messageId": "be3dc577-60c4-4fc8-83a5-8c358e0bfe15", // guid of the message whose status update we are notifying "timestamp": "2025-02-05T06:01:07.499Z", // is the time of receiving status update information "status": "delivered" } ] }
Webhooks about creating a new contact, deal
Send when you need to create a contact or transaction in CRM. This happens in 3 cases:
Case 1: in item 3 of the integration settings “Every new client is assigned to the first respondent” is selected.
A new client writes. An employee replies to them. Wazzup sends a webhook about new contact and deal creation if funnels with stages are loaded from CRM.
Case 2: “Sales reps are assigned new clients in turn” is selected in item 3 of the integration settings.
A new client writes. Wazzup sends a webhook about creating a new contact and deal if funnels with stages are loaded from CRM.
Case 3: When clicking the “+” button in the “Deals” list to create a new deal inside the Wazzup chats:
We first check if the contact already exists in our database.
If the contact already exists, we send a webhook to initiate deal creation:
{ createDeal: { responsibleUserId: '1', // the id of the user who was selected in turn or was the first to respond contacts: ['1'] // link of the deal with a newly created contact source: 'auto'|'byUser', // auto - on incoming or outgoing message, byUser - by the button in the "Deals" dropdown }, }
If the contact does not exist, we first send a webhook to initiate contact creation:
{ createContact: { responsibleUserId: '1', // id of the user who was selected in turn or was the first to respond name: 'contacts.name', // contact name from the contacts table contactData: [{ chatType, chatId }], source: 'auto'|'byUser', // auto - on incoming or outgoing message, byUser - by button }, }
After that, the CRM should create the contact and respond with 200 OK along with a JSON object of the new entity, matching the CRUD route signature for contacts.
Then, we will send a webhook to initiate deal creation.
Subsequently, the CRM should create the deal and similarly respond with 200 OK and a JSON object of the new entity, matching the CRUD route signature for deals.
Webhook about channel status change
Sent when the channel status changes.
Parameter | Type | Description |
channelId | String | Channel guid |
state | String | Channel status |
qr | String | QR code in base64 format, present only with state ‘qr’ |
qridle | String | The channel is deauthorized or the QR code has expired |
timestamp | Integer | Status setting time in ms |
Example
{ "channelsUpdates": [ { "channelId": "d9e5721c-ce2b-444f-9627-60a8129d7e1f", "state": "qr", "timestamp": 1603977171000, "qr": "data:image/png;base64,iVBORw0KGgoAAAANS" } ] }
Channel status values (state)
Value | Description | Channel types |
active | The channel is active, everything is fine | All |
disabled | The channel is disabled. Technical, this status can only be during work, fixing the problem | All |
qr | QR code needs to be scanned | whatsapp and tgapi |
phoneUnavailable | There is no connection with the phone. Outdated, but occasionally it can manifest itself in case of problems in the WhatsApp itself or on older versions of the WhatsApp application on the handset | |
openElsewhere | WhatsApp web app opened in a different location | |
notEnoughMoney | Channel not paid | All |
unauthorized | Not authorized, you need to re-authorize the channel | All |
Webhook about new moderation status of a WABA template
Parameter | Type | Description |
templateGuid | String | Template guid |
name | String | Template name |
status | String | Template moderation status |
Status values
Value | Description |
APPROVED | Same as “Active” in Wazzup account. The template is Meta approved and can be used |
PENDING | The same as “On moderation” in Wazzup personal account. Meta still validates template |
REJECTED | In Wazzup personal account — “Rejected”. The template did not pass Meta moderation |
PAUSED | In Wazzup personal account — “Rejected”. Recipients complained about the template, so Meta checks it again |
DISABLED | In Wazzup personal account — “Rejected”. The template was blocked after complaints |