This article explains how to embed the Wazzup chat window into your CRM and set up event-driven updates for the Deals dropdown.
Deals dropdown — a tool in the chat window that lets users:

We recommend using webhooks to manage the Deals dropdown. If webhooks aren't an option, you can use events instead.
Currently, it is not possible to create a Telegram dialog via the Chat Window API using a phone number. To create a Telegram chat, use either the Send Message method or a username. Once the chat is created, you will receive a chat id, which can then be used to open MAX and Telegram dialogs in the iframe.
POST /v2/iframe-links/chatsPOST /v2/iframe-links/chats │ ├── user │ └── id * ├── author_name ├── scope * ├── chats[] │ ├── contact_name │ ├── chat_type * │ ├── chat_id * │ └── username * ├── active_chat │ ├── channel_id │ ├── chat_type * │ ├── chat_id * │ └── username * ├── use_events │ ├── deals │ └── messages └── client_type
| Body parameter. Required marked with * | Type | Description |
user |
object user |
User data |
author_name |
String |
Sender name. If not provided, the CRM user's name is used |
scope* |
String |
Defines what the user sees: global — all chats the user has access to, card — opens a chat from a specific deal, contact, or record |
chats |
array(object) chats |
Array of chats to display. Required for scope=card. Do not include when scope=global |
active_chat |
object active_chat |
Specifies which chat should be active when the iframe opens |
use_events |
object use_events |
Event-based settings for the iframe. Required if you plan to create contacts and deals in response to events |
client_type |
String |
CRM type. This field can be left empty |
| Body parameter. Required marked with * | Type | Description |
id* |
String |
ID of the CRM user opening the chat window |
| Body parameter. Required marked with * | Type | Description |
contact_name |
String |
Contact name. Can be specified for a new contact with no prior conversation history |
chat_type* |
String |
Chat type. Supported values:
|
chat_id* |
String |
Chat ID — the contact's identifier in the messenger. The format depends on the chat type:
|
username* |
String |
Alternate identifier for Telegram Personal only. The contact's Telegram username (without the @ symbol). Use this if the chat_id is unknown |
| Body parameter. Required marked with * | Type | Description |
channel_id |
String |
ID of the channel the active chat should open from |
chat_type* |
String |
Chat type. Same possible values as chats.chat_type |
chat_id* |
String |
Chat ID (the contact's messenger account). Format follows the same rules as chats.chat_id |
username* |
String |
For Telegram Personal only. The contact's Telegram username (without the @ symbol). Use this if the chat_id is unknown |
| Body parameter. Required marked with * | Type | Description |
deals |
Boolean |
Set to true to receive notifications from the iframe when a deal needs to be created or displayed. The event is triggered when the user clicks + in the Deals dropdown to create a deal, or clicks an existing deal in the list to open it |
messages |
Boolean |
Set to true to receive notifications from the iframe when a new contact needs to be created. The event is triggered when the user replies to an incoming message from within the iframe |
If a contact with the specified chat_type and chat_id does not exist in Wazzup, it will be created when opened from a CRM contact record. The contact's name will be set to the value provided in contact_name, or to the id if contact_name is not supplied.
Example request for opening the iframe within a contact or deal record
{
"user_id": "crm-user-id-123",
"author_name": "John Smith",
"scope": "card",
"chats": [
{
"contact_name": "Anthony Stone",
"chat_type": "whatsapp",
"chat_id": "37111234567"
},
{
"contact_name": "Anthony Stone",
"chat_type": "telegram",
"username": "my_tg_user"
},
{
"contact_name": "Anthony Stone",
"chat_type": "telegram",
"chat_id": "1670185"
}
],
"active_chat": {
"channel_id": "string",
"chat_type": "whatsapp",
"chat_id": "37111234567"
},
"use_events": {
"deals": false,
"messages": false
}
}
Example of a minimal request to open the iframe with all user chats
{
"user_id": "crm-user-1",
"scope": "global"
}
Example request for creating a Telegram chat using a username
{
"user": {
"id": "crm-user-id-123",
"name": "John Smith"
},
"scope": "card",
"filter": [
{
"chatType": "telegram",
"username": "best_client"
}]
}
200
The response returns a JSON object containing the URL for opening the chat window.
{
"data": {
"link": "https://app.wazzup24.com/1234-1234/chat/telegram/1670185301/123?token=token"
},
"meta": {
"timestamp": 1764849838
}
}
If you are opening the URL in an iframe, include the allow="microphone *; clipboard-write *" attribute in the iframe tag.
The microphone permission is required to record voice messages from the chat window. If omitted, users won't be able to record voice messages — clicking the microphone will simply trigger an error.
The clipboard-write permission is required for copy‑to‑clipboard functionality within the iframe — for example, allowing users to copy an error code from a notification with a single click.
<iframe src="link" allow="microphone *; clipboard-write *" ></iframe>
Error response parameters
| Parameter. Required are marked with * | Type | Description |
code* |
string |
Error code. Possible values for different HTTP statuses are listed below. Example: INTERNAL_SERVER_ERROR |
title* |
string |
Error title. Example: Internal Server Error |
status* |
number |
HTTP status. Values: 400, 401, 403, 500 |
detail* |
string |
Error description. Possible values for different HTTP statuses are listed below. Example: One or more fields did not pass validation. |
instance* |
string |
URI of the request that caused the error. Example: /v2/templates/waba/123 |
method* |
string |
HTTP method. Values: GET, POST, PATCH, PUT, DELETE |
errors |
array |
Additional field for multiple errors (e.g., several parameters failing validation). Example: ["validation_error_string"] |
Error example
{
"code": "VALIDATION_FAILED",
"title": "Validation Failed",
"status": 400,
"detail": "One or more fields did not pass validation.",
"instance": "/v2/iframe-links/chats",
"method": "POST",
"errors": [
"user_id should not be empty",
"scope must be a valid enum value"
]
}
400
Possible Error Codes for 400 Status
| Error code | Description |
VALIDATION_FAILED |
One or more fields in the request failed validation |
401
Possible Error Codes for 401 status
| Error code | Description |
OAUTH_AUTH_HEADER_MISSING |
Authorization header is missing |
OAUTH_UNKNOWN_SCHEME |
Unknown authorization scheme. Use Basic or Bearer |
OAUTH_INVALID_PARTNER_TOKEN |
Invalid partner token |
OAUTH_TOKEN_INVALID_OR_EXPIRED |
Access token is invalid or has expired |
OAUTH_TOKEN_UNKNOWN_OR_REVOKED |
Access token is unknown or has been revoked |
403
Possible Error Codes for 403 status
| Error code | Description |
OAUTH_SCOPE_FORBIDDEN |
The user does not have access to the required scope |
OAUTH_CRM_INTEGRATION_REQUIRED |
An active CRM integration is required to use these methods |
OAUTH_BASIC_SCHEME_FORBIDDEN |
This method cannot be called with Basic authentication |
OAUTH_BEARER_SCHEME_FORBIDDEN |
This method cannot be called with Bearer authentication |
OAUTH_PARTNER_NOT_FOUND |
Partner not found |
OAUTH_PARTNER_NOT_ACTIVE |
Partner account is disabled or inactive |
OAUTH_CLIENT_NOT_CHILD_OF_PARTNER |
The client does not belong to this partner |
500
Possible Error Codes for 500 status
| Error code | Description |
INTERNAL_SERVER_ERROR |
An unexpected error occurred |
Events notify you when you need to:
The user clicks + in the Deals dropdown to create a deal
What this means: A new deal needs to be created using the parameters provided by the iframe.
Event name: WZ_CREATE_ENTITY
What it contains:
{body}
├── type
└── data
├── chatType
├── chatId
├── channelId
├── userId
└── integrationId
| Field | Type | Description |
type |
String |
Event name — WZ_CREATE_ENTITY |
data |
Object data |
Object containing event data |
| Field | Type | Description |
chatType |
String |
Messenger chat type: whatsapp, instagram, telegram, vk |
chatId |
String |
Chat ID (the contact's messenger account) |
channelId |
String |
Channel identifier |
userId |
Number |
CRM user ID |
integrationId |
String |
Integration ID |
Event example:
{
type: 'WZ_CREATE_ENTITY',
data: {
chatType: whatsapp,
chatId: 37198887766,
channelId: c16tc1c-9f20-4rda-46jd-q92ty4j6s36888,
userId: test_id,
integrationId: 608df5ye-45hj-j6k7-l77k-qe5t88j4h1222
}
}
After creating a deal, you need to send the new deal data from your CRM back to Wazzup.
The user opens a deal, contact, or other record from the Deals dropdown.
What this means: The user needs to view a deal, contact, or other record using the parameters provided by the iframe.
Event name: WZ_OPEN_ENTITY
What it contains:
WZ_OPEN_ENTITY
├── type
└── data
├── chatType
├── chatId
├── channelId
├── userId
├── integrationId
└── entity
├── closed
├── id
├── link
├── name
└── responsibleUserName
| Field | Type | Description |
type |
String |
Event name — WZ_OPEN_ENTITY |
data |
Object data |
Object containing event data |
| Field | Type | Description |
chatType |
String |
Messenger chat type: whatsapp, instagram, telegram, vk |
chatId |
String |
Chat ID (the contact's messenger account) |
channelId |
String |
Channel identifier |
userId |
Number |
CRM user ID |
integrationId |
String |
Integration ID |
entity |
Object entity |
Object containing entity data |
| Field | Type | Description |
closed |
Boolean |
Indicates if the deal is closed or open |
id |
Number |
ID of the entity the user is opening |
link |
String |
Link to the entity (may be omitted) |
name |
String |
Entity name |
responsibleUserName |
String |
Name of the user responsible for the entity |
Event example:
{
type: 'WZ_OPEN_ENTITY',
data: {
chatType: whatsapp,
chatId: 37198887766,
channelId: c16tc1c-9f20-4rda-46jd-q92ty4j6s36888,
userId: test_id,
integrationId: 608df5ye-45hj-j6k7-l77k-qe5t88j4h1222,
entity: {
closed: false,
id: clientId3,
link: #,
name: TestDeal,
responsibleUserName: TestUser
}
}
}
We've created a sample HTML page that demonstrates how to capture events from the iframe. How to use it: