For each message sent from the Kommo interface to the chat channel, a webhook is dispatched to a specified address. Upon receiving a webhook, it’s crucial to process it and send a message to the messenger.
Each webhook is sent only once; if the integration fails to process or receive it, it will not be retried.
Response time for the webhook is limited, so it’s recommended to check the request signature immediately upon receipt and handle business logic in the background. For example, you can queue a task for processing and promptly respond to the webhook.
If a message cannot be accepted by the integrated messenger, you should update its status to Error. Then, in an asynchronous mode, you can process the message, execute your business logic, and send the message as needed.
Currently, the response window for the webhook is a maximum of 5 seconds. To consider the webhook successfully sent, your integration must respond with a 200 HTTP code.
The Chat API employs prioritization mechanisms; if the integration takes too long to respond or fails to respond, it may be moved to a slower stream, resulting in delayed webhook delivery. This priority is calculated dynamically based on various factors, allowing the integration to switch between faster and slower queues as necessary.
Additionally, “typing” events from the manager require separate webhook subscriptions for each channel, which can be arranged through Tech Support.
Webhook v2
Kommo sends you webhooks if a message was sent. To get them, you need to specify a webhook URL in "webhook_url"
field when registering a channel.
Each webhook contains an X-Signature header, which is generated from the request body using the HMAC-SHA1 method. The channel secret serves as the secret key, allowing you to verify the authenticity of incoming webhooks.
To do this, calculate the hash from the body of the incoming request and compare it with the value in the X-Signature header.
Sending a message
{
"account_id": "XXXXXXXX-d2eb-4bd8-b862-b57934927b38",
"time": 1670571014,
"message": {
"receiver": {
"id": "XXXXXXXX-a3ab-4695-832c-919dbfc598ea",
"name": "John",
"phone": "+123456789",
"email": "[email protected]",
"client_id": "XXXXXXXX-ec21-4463-965f-1fe1d4cd5a90"
},
"sender": {
"id": "XXXXXXX-ec21-4463-965f-1fe1d4cd5b89",
"name": "Manager"
},
"conversation": {
"id": "XXXXXXXX-c40d-4efc-9f78-9625adac414c",
"client_id": "XXXXXXX-80c5-403d-93d9-bada6302810d"
},
"source": {
"external_id": "ChatSourceId"
},
"timestamp": 1670571014,
"msec_timestamp": 1670571014414,
"message": {
"id": "XXXXXXXX-2aa3-464c-b6e4-4386d0f8f3ca",
"type": "text",
"text": "Hello Adam! Let's schedule a call for next week. ",
"markup": null,
"tag": "",
"media": "",
"thumbnail": "",
"file_name": "",
"file_size": 0
}
}
}
{
"account_id": "XXXXXXXX-d75c-4ee0-a443-9adbb902f98d",
"time": 1730732453,
"message": {
"receiver": {
"id": "XXXXXXX-1bc4-457f-b941-9b699c958165",
"name": "John Johnson",
"phone": "+1234567890",
"client_id": "XXXXXXX-d95e-121212-3c0eeea9d897"
},
"sender": {
"id": "XXXXXXXXX-fadd-4995-8026-36fcc0c806bd",
"name": "Nicky"
},
"source": {
"external_id": "chatapi2externalid"
},
"conversation": {
"id": "XXXXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba",
"client_id": "12-122131"
},
"timestamp": 1730732453,
"msec_timestamp": 1730732453229,
"message": {
"id": "XXXXXXXXXXX-2d28-4853-baec-5f8f7e5e4f8a",
"type": "picture",
"text": "",
"markup": null,
"tag": "",
"media": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/1261ee39-232a-4433-a245-00b29ffbca97/a521d24e-52c2-4f99-9a3b-7741567f0529/Screenshot-1.png",
"thumbnail": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/1261ee39-232a-4433-a245-00b29ffbca97/a521d24e-52c2-4f99-9a3b-7741567f0529/13fcba3b-d8c2-4ac9-b2b0-270a1a9f5671/Screenshot-1_320_130.png",
"file_name": "Screenshot_1.png",
"file_size": 24246
}
}
}
{
"account_id": "XXXXXX-d75c-4ee0-a443-9adbb902f98d",
"time": 1730734321,
"message": {
"receiver": {
"id": "XXXXXX-1bc4-457f-b941-9b699c958165",
"name": "John 1",
"phone": "+18305803077",
"client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897"
},
"sender": {
"id": "XXXXXXXX-fadd-4995-8026-36fcc0c806bd",
"name": "Nicky"
},
"source": {
"external_id": "chatapi2externalid"
},
"conversation": {
"id": "XXXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba",
"client_id": "XXXXXXX-adlw23d21-sad21d-221svr"
},
"timestamp": 1730734321,
"msec_timestamp": 1730734321314,
"message": {
"id": "XXXXXXX-81b4-4880-9f39-c890a1c011a9",
"type": "picture",
"text": "Hello John! How are you?",
"markup": {
"mode": "inline",
"buttons": [
[
{
"text": "Fine!"
}
],
[
{
"text": "I'm fine"
}
]
]
},
"tag": "",
"media": "https://drive-g.kommo.com/download/XXXXXXX-fc00-5826-901a-6c9c06f128f0/b4b1fc59-1825-48af-b378-ab433aa7f53a/9c882236-6825-4269-a527-b11534f8561b/Screenshot-1.png",
"thumbnail": "https://drive-g.kommo.com/download/XXXXXXXX-fc00-5826-901a-6c9c06f128f0/b4b1fc59-1825-48af-b378-ab433aa7f53a/9c882236-6825-4269-a527-b11534f8561b/0c349685-3a7c-4e16-91b1-114eb93ccd3b/Screenshot-1_320_130.png",
"file_name": "picture.png",
"file_size": 24249,
"template": {
"id": 34788,
"content": "Hello {{contact.name}}! How are you?",
"params": [
{
"key": "{{contact.name}}",
"value": "John"
}
]
}
}
}
}
{
"account_id": "XXXXXXXX-d75c-4ee0-a443-9adbb902f98d",
"time": 1730742708,
"message": {
"receiver": {
"id": "XXXXXXXX-1bc4-457f-b941-9b699c958165",
"name": "John",
"phone": "+18305803077",
"client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897"
},
"sender": {
"id": "XXXXXXXXX-fadd-4995-8026-36fcc0c806bd",
"name": "Nicky"
},
"source": {
"external_id": "chatapi2externalid"
},
"conversation": {
"id": "XXXXXXX-4ccc-48a5-8bf3-68fed3cc74ba",
"client_id": "XXXXXXX-adlw23d21-sad21d-221svr"
},
"timestamp": 1730742708,
"msec_timestamp": 1730742708539,
"message": {
"id": "XXXXXXXX-628c-41ac-bdaa-a26b0372c27a",
"type": "text",
"text": "Hello!",
"markup": null,
"tag": "",
"media": "",
"thumbnail": "",
"file_name": "",
"file_size": 0,
"reply_to": {
"message": {
"id": "XXXXXXXX-832f-413b-b3f8-019fa2a5d274",
"msgid": "XXXXXXX-2sd21we12-f45665432",
"type": "text",
"text": "Hi!",
"timestamp": 1730367735,
"msec_timestamp": 1730367735000,
"sender": {
"id": "XXXXXX-1bc4-457f-b941-9b699c958165",
"name": "John",
"phone": "+18305803077",
"client_id": "XXXXXXXX-d95e-121212-3c0eeea9d897"
}
}
}
}
}
}
{
"account_id": "52e591f7-c98f-4255-8495-827210138c81",
"time": 1639572261,
"message": {
"receiver": {
"id": "2ed64e26-70a1-4857-8382-bb066a076219",
"phone": "79161234567",
"email": "[email protected]",
"client_id": "my_int-1376265f-86df-4c49-a0c3-a4816df41af8"
},
"sender": {
"id": "76fc2bea-902f-425c-9a3d-dcdac4766090"
},
"conversation": {
"id": "8e4d4baa-9e6c-4a88-838a-5f62be227bdc",
"client_id": "my_int-d5a421f7f218"
},
"source": {
"external_id": "78001234567"
},
"timestamp": 1639572260,
"msec_timestamp": 1639572260980,
"message": {
"id": "0371a0ff-b78a-4c7b-8538-a7d547e10692",
"type": "text",
"text": "Lead #15926745 Message text",
"markup": {
"list_message": {
"header": "What type of service do you want to receive?",
"body": "Please select one of the answer options from the menu by clicking the button below.",
"footer": "Sincerely, Test Company",
"button": "Services",
"sections": [
{
"title": "Available services",
"rows": [
{
"callback_data": "vG9ujre8N7",
"title": "Service 1",
"description": "Service 1 description"
}
]
}
]
}
}
}
}
}
Webhook body parameters
A message can be received along with media, text, and buttons simultaneously. When multiple attachments are sent at once, the message will be divided into several webhooks, but they will all share a common
message[message][media_group_id]
.
Parameter | Data type | Description |
---|---|---|
account_id | string | amojo account ID |
time | int | Timestamp when generating the webhook in the format of Unix Timestamp |
message | obj | An array contains the message components. |
message
Parameter | Data Type | Description |
---|---|---|
receiver | obj | Message receiver |
sender | obj | Message sender |
conversation | obj | Conversation details |
source | obj | Chat source information |
timestamp | int | Message timestamp in the format of Unix Timestamp |
msec_timestamp | int | Message timestamp in milliseconds |
message | obj | The content of the message |
message.receiver
Parameters | Data Type | Description |
---|---|---|
id | string | Chat participant ID on the integration side |
name | string | Chat participant name on the Chats API side |
phone | string | Phone number. The field is not returned if the profile wasn’t passed |
string | Email address. The field is not returned if the profile wasn’t passed | |
client_id | string | Chat participant ID on the Chats API side |
message.sender
Parameters | Data Type | Description |
---|---|---|
id | string | Chat participant ID on the integration side |
name | string | Chat participant name on the Chats API side |
message.conversation
Parameter | Data Type | Description |
---|---|---|
id | string | Chat ID in the Chat API |
client_id | string | Chat ID on the integration side |
message.source
Parameter | Data Type | Description |
---|---|---|
external_id | string | Chat source ID on the integration side |
message.message
Parameter | Data Type | Description |
---|---|---|
id | string | amojo ID of the message |
type | string | Message type, one of the following: text, file, video, picture, voice, audio, sticker |
text | string | The field is mandatory for the “text” type, can be empty for other types |
markup | obj | The keyboard object to display with the message |
media | string | URL to the file, video, picture, voice, audio, or sticker |
thumbnail | string | Link to the preview picture or video thumbnail URL |
file_name | string | The name of the file from the “media” field URL |
file_size | int | The size for the data in the “media” field |
template | obj | Template object, if the message was sent using a template |
reply_to | obj | Reply message object. |
forwards | arr of obj | Forward message object. |
message.message.markup
The markup object consists of an array of arrays of buttons arranged in a specified layout.
The arrangement method is indicated in the mode field. Currently, for integrations, this field always contains the value "inline"
.
The "inline"
value indicates that the keyboard should be positioned below the message text.
At this time, buttons of different types cannot be included in the same object.
Parameters | Data Type | Description |
---|---|---|
mode | string | Keyboard layout. Possible value:" inline" . |
button | obj | Array of the button objects |
list_message | obj | WhatsApp List Message type message object. List Message object structure |
message.message.markup.buttons
Parameters | Data Type | Description |
---|---|---|
text | string | Text. When a user clicks on a text button, the messenger should send a message with the text of this button to the chat |
button | obj | Link. When a user clicks on a link button, the messenger should follow that link. The property may be absent if another type of button was passed. |
message.message.markup.list_message
Parameter | Data Type | Description |
---|---|---|
header | string | Message title. A string of up to 60 characters (emoji supported) |
body | string | Message body. A string up to 1024 characters long (emoji and Markdown are supported) |
footer | string | Bottom of the message. Line up to 60 characters long (emoji, links, and Markdown supported) |
button | string | The name of the main button that will be shown to the user; when this button is clicked, a menu with the transferred sections opens |
sections | array | An array of objects (1 to 10 elements) describing interactive elements (sections) |
sections[0] | object | An object describing an interactive section |
sections[0][title] | string | Section name. A string up to 24 characters long. |
sections[0][rows] | array | An array of objects (1 to 10 elements) describing individual buttons in the section |
sections[0][rows][0] | object | An object that describes a single button in a section |
sections[0][rows][0][callback_data] | string | A unique identifier to be passed to WhatsApp and sent with the button selected by the user in the callback_data property of the message object. |
sections[0][rows][0][title] | string | Button name |
sections[0][rows][0][description] | string | Button description |
message.message.template
Parameter | Data Type | Description |
---|---|---|
id | string | The template id in Kommo |
content | string | The template text without interpreting the placeholders |
params | obj | An object of the placeholders |
message.message.template.params
Parameter | Data Type | Description |
---|---|---|
key | string | Key of the placeholder |
value | string | Value of the placeholder |
message.message.reply_to
Parameter | Data Type | Description |
---|---|---|
message | obj | Reply message object. Embedded message object description |
message.message.reply_to.message (embedded message)
Parameter | Data Type | Description |
---|---|---|
id | int | The ID of the quoted message in the Chats API. If passed, the remaining fields do not need to be filled in, they will be determined automatically. In case of passing the ID, scrolling to the message will also work if the chat is in the same card. |
msgid | int | The ID of the quoted message on the integration side. If passed, the remaining fields do not need to be filled in, they will be determined automatically. In case of passing the ID, scrolling to the message will also work if the chat is in the same card. |
type | string | Mandatory if no ID is passed. Message type can be one of the following: text, contact, file, video, picture, voice, audio, sticker, location. |
text | string | Mandatory for the "text" type if no ID is passed. For other message types, this can be empty. |
file_name | string | Optional. File name |
file_size | int | Optional. File size in bytes |
media_duration | int | Optional. Duration for video/audio/voice messages |
location | obj | Mandatory field for location type messages |
location[lon] | float | Longitude |
location[lat] | float | Latitude |
sender | obj | Message sender information. Sender object description |
message.message.reply_to.message.sender (embedded user)
Parameter | Data Type | Description |
---|---|---|
id | string | Sender ID on the integration side, if passed, the remaining fields do not need to be filled in, they will be determined automatically. |
ref_id | string | Sender ID in the Chats API, if passed, the remaining fields do not need to be filled in, they will be determined automatically. |
name | string | Mandatory if no ID is passed. Sender name |
Typing webhook
The webhook is sent when the manager types a message in the Kommo interface.
The webhook is sent no more than once every 5 seconds.
{
"account_id": "XXXXXXXX-d2eb-4bd8-b862-b57934927b38",
"time": 1670585310,
"action": {
"typing": {
"user": {
"id": "XXXXXXXX-ec21-4463-965f-1fe1d4cd5b89"
},
"conversation": {
"id": "XXXXXXX-9f3c-4d3f-8101-60327e14dc48",
"client_id": "XXXXXXXX-80c5-403d-93d9-bada6302810f"
},
"expired_at": 1670585315
}
}
}
Body parameters
Parameters | Data Type | Description |
---|---|---|
account_id | string | amojo account ID |
time | int | Timestamp when generating the webhook in the format of Unix Timestamp |
action[typing][user][id] | string | User ID who performs the writing in the Chat API |
action[typing][conversation][id] | string | Chat ID in Chats API |
action[typing][conversation][client_id] | string | Optional field. Chat ID on the integration side. If the chat was created using the Write first function, the field will be absent in the hook |
action[typing][expired_at] | int | Timestamp when we think the user is no longer typing. We pass the typing end timestamp as the current print start time + 5 seconds |
Reaction webhook
The webhook is triggered when the user reacts to a message or removes their reaction within the Kommo interface.
{
"account_id": "XXXXXX-8952-4785-abe2-c8d93f5fcc7d",
"time": 1637087558,
"action": {
"reaction": {
"message":{
"id": "XXXXXXX-9e04-4e1d-bee9-37c71924cd11",
"client_id": "64ff3a9baeb11",
"sender":{
"id": "XXXXX-f502-4165-9377-8575c55c5ebd",
"name": "John Smith",
"phone": "+123456789",
"client_id": "14255551212"
},
"timestamp": 1694448283,
"msec_timestamp": 1694448283000
},
"user": {
"id": "XXXXXX-9e04-4e1d-bee9-37c71924cdc2"
},
"conversation": {
"id": "XXXXXXXX-f502-4165-9377-8575c55c5ebd",
"client_id": "c1234456"
},
"type": "react",
"emoji": "😍"
}
}
}
Body parameters
Parameters | Data Type | Description |
---|---|---|
account_id | string | Chat API account ID |
time | int | Webhook create time in Unix Timestamp format |
action[reaction][message][id] | string | Chat API message ID |
action[reaction][message][client_id] | string | Optional field. Message ID on the integration side. If the message was created on the Kommo side, the field will not be in the webhook |
action[reaction][message][receiver] | obj | An object with information about the receiver of the message. |
action[reaction][message][sender] | obj | An object with information about the sender of the message |
action[reaction][message][timestamp] | int | Message creation time in Unix Timestamp format |
action[reaction][message][msec_timestamp] | int | Message create time in Unix Timestamp format with milliseconds |
action[reaction][user] | obj | An object with information about the sender of the reaction. |
action[reaction][conversation][id] | string | Chat ID in Chat API |
action[reaction][conversation][client_id] | string | Optional field. Chat ID on the integration side. If the chat was created using the Write first function, the field will be absent in the hook |
action[reaction][type] | string | Event type: "react" , "unreact" |
action[reaction][emoji] | string | Optional field. Reaction provided by the user. If the user removes the reaction, the field will not be in the webhook |