Chatbot messaging protocol reference
HTTP protocol reference for integrating third-party chatbots with Zoom Contact Center. This protocol defines the message format and endpoints that chatbot providers implement to support action and trigger mode integration.
The integration enables third-party chatbots to act as AI bots within Zoom Contact Center, handling conversation messages, rich media content, and handover to live agents.
For the full integration workflow and Marketplace app setup, see Integrate third-party chatbots with actions and triggers.
Send messages to third-party bot
To send messages from Zoom Contact Center to your chatbot endpoint, Zoom sends HTTP requests with the following payload structure.
Request payload
{
"id": "xxx",
"sessionId": "xxx",
"conversationMode": "START_CONVERSATION",
"message": {
"type": "text",
"value": "hi"
},
"conversationVariables": {
"global_system.Engagement.timezone": "America/New_York",
"global_system.Engagement.regionCode": "GA",
"global_system.Consumer.email": "a@q.com",
"global_system.Engagement.latLong": "34.0409, -84.0237",
"global_custom.CustomerVariableGroup.QueueOpenHours": "1698872160000",
"global_custom.CustomerVariableGroup.CVariable001": "this is default value",
"global_system.Engagement.locale": "en-us",
"global_custom.Website_Data_Value.GJavescriptVariable_hostname": "localhost",
"global_system.Engagement.regionName": "Georgia",
"global_system.Engagement.cityName": "Suwanee"
},
"languageCode": "en-US",
"additionalPayload": null,
"timestamp": 111,
"userId": "xxx",
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
{
"id": "xxx",
"sessionId": "xxx",
"conversationMode": "KEEP_CONVERSATION",
"conversationVariables": {},
"additionalPayload": null,
"languageCode": "en-US",
"message": {
"type": "text",
"value": "Hi, I need some help!"
},
"timestamp": 111,
"userId": "xxx",
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
{
"id": "xxx",
"sessionId": "xxx",
"conversationMode": "KEEP_CONVERSATION",
"message": {
"type": "text",
"value": "yes"
},
"conversationVariables": {},
"additionalPayload": {
"action": "optionSubmit",
"data": {
"interactionId": "a806116e-5301-4b0c-b448-cc09c32ed72a-0fffcb44",
"interacted": true,
"value": "yes",
"originMessage": {
"type": "quickReplies",
"value": {
"title": "Please make your choice",
"options": [
{
"label": "Yes",
"value": "yes"
},
{
"label": "No",
"value": "no"
}
]
}
}
}
},
"languageCode": "en-US",
"timestamp": 111,
"userId": "xxx",
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
{
"id": "xxx",
"sessionId": "xxx",
"conversationMode": "KEEP_CONVERSATION",
"message": {
"type": "text",
"value": "info_collection_form(form name)"
},
"conversationVariables": {},
"additionalPayload": {
"action": "formSubmit",
"data": {
"interactionId": "a806116e-5301-4b0c-b448-cc09c32ed72a-0fffcb44",
"skipped": false,
"values": [
{
"key": "name",
"type": "text",
"value": "Tom"
},
{
"key": "education",
"type": "select",
"value": "bachelor"
},
{
"key": "option",
"type": "multi-select",
"value": ["1", "2"]
}
],
"originMessage": {
"type": "form",
"value": {
"title": "your title",
"description": "<p>I really like using Markdown.</p> ",
"fields": [
{
"type": "text",
"label": "Name",
"key": "name",
"required": true,
"defaultValue": ""
},
{
"type": "select",
"label": "Education",
"key": "education",
"required": true,
"options": [
{
"label": "High School Diploma",
"value": "high_school"
},
{
"label": "Associate Degree",
"value": "associate"
},
{
"label": "Bachelor's Degree",
"value": "bachelor"
},
{
"label": "Doctoral Degree (Ph.D.)",
"value": "doctor"
},
{
"label": "Other",
"value": "other"
}
],
"defaultValue": ""
},
{
"type": "multi-select",
"label": "Make you chocie",
"key": "option",
"required": true,
"options": [
{
"label": "Option1",
"value": "1"
},
{
"label": "Option2",
"value": "2"
},
{
"label": "Option3",
"value": "3"
}
],
"defaultValues": ["1", "2"]
}
]
}
}
}
},
"languageCode": "en-US",
"timestamp": 111,
"userId": "xxx",
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
{
"id": "xxx",
"sessionId": "xxx",
"conversationMode": "END_CONVERSATION",
"timestamp": 111,
"userId": "xxx",
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
Request parameters
| Parameter Name | Type | Required | Description | Possible Values |
|---|---|---|---|---|
| id | String | Yes | Unique identifier for this request. | |
| sessionId | String | Yes | Unique identifier for the bot conversations. | |
| conversationMode | String | Yes | Parameter to define whether to start a new conversion, continue with the existing, or close the conversation.START_CONVERSATION: starts a session KEEP_CONVERSATION: keeps the current session. END_CONVERSATION: ends the current session | START_CONVERSATION, KEEP_CONVERSATION, END_CONVERSATION |
| conversationVariables | Object | No | Will be sent only once when conversationMode is START_CONVERSATION. Include both system-defined and customer-defined values. Bot providers should store these variables within the conversation context so that customers can reference within the bot's flow. | |
| additionalPayload | Object | No | For submissions of forms, cards, action cards, or quick replies, the data will be placed in the additionalPayload field. Note: additionalPayload may be null if the consumer's input is not related to any of these rich media selections. | |
| languageCode | String | Yes | Required when conversationMode is START_CONVERSATION or KEEP_CONVERSATION. | en-US |
| message | Object | Yes | Details of the message to be sent.Required when conversationMode is START_CONVERSATION or KEEP_CONVERSATION. | |
| timestamp | Long | Yes | Unix epoch time when the message was sent from the end-user of the chat client. | |
| userId | String | Yes | Unique user identifier. This is the identifier of the end-user who is interacting with the bot. | |
| customData | Object | Yes | Pass-through JSON-formatted name-value pairs that are sent back in the response. These values are not processed by the endpoint, but can be used to keep specific customer information attached to the conversation. |
Message input types
Text
To handle plain text messages from consumers, parse the message object.
{
"type": "text",
"value": "Hi, I need some help!"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| value | Yes | String | Plain text | n/a |
Receive messages from third-party bot
To respond with messages from your chatbot to Zoom Contact Center, return HTTP responses with the following payload structure.
Response payload
Basic response example.
{
"id": "xxx",
"sessionId": "xxx",
"body": [
{
"type": "text",
"value": "Hi, I'm your virtual agent!"
}
],
"timestamp": 111,
"userId": "xxx",
"completed": false,
"customData": {
"trackingId": "xxx",
"engagmentId": "xxx"
}
}
Response parameters
| Parameter Name | Type | Required | Description | Possible Values |
|---|---|---|---|---|
| id | String | Yes | Unique identifier for this request. | |
| sessionId | String | No | Unique identifier for the bot conversations. | |
| body | Array | Yes | List of objects that describe the elements of the response message body. | |
| timestamp | Long | Yes | Unix epoch time when the message was sent from the end-user of the chat client. | |
| userId | String | Yes | Unique user identifier. This is the identifier of the end-user who is interacting with the bot. | |
| completed | Boolean | No | Flag that indicates whether the ServiceNow Virtual Agent has successfully completed the conversation. true means conversation has been successfully completed. false means conversation is not complete and this parameter is not returned in the response. | true, false |
| customData | Object | Yes | Pass-through JSON-formatted name-value pairs that are sent back in the response. These values are not processed by the endpoint, but can be used to keep specific customer information attached to the conversation. |
Message body structure
Each message in the body array contains a type and value.
| Field | Required | Value | Description | Possible Values |
|---|---|---|---|---|
| type | Yes | String | Message content type. | action, text, html, markdown, quickReplies, card, carousel, article, image, audio, video, link, form, attachment |
| value | Yes | Object | Refer to the message content types below. | |
| fallbackText | No | String | When a chatbot is integrated with social channels such as Facebook or WhatsApp, these platforms may not fully support rich text messages. Setting a fallbackText helps ensure that users can still see a message instead of receiving no prompt at all. |
Message content types
Action | Article | Attachment | Audio | Card | Carousel | Form | HTML | Image | Link | Markdown | Quick replies | Text | Video
Action
To trigger actions in the conversation, use action messages.
Set variables
To dynamically route to queues, set variables in the conversation context.
{
"type": "action",
"value": {
"action": "setVariables",
"data": {
"variables": [
{
"name": "global_custom.dynamic routing.dynamical_queue",
"value": "Main Team Queue"
}
]
}
}
}
Note
global_customis the prefix used for custom-defined variables.dynamic routingis the variable group name.dynamical_queueis the variable name. Thevaluefield contains the queue name.
Typing indicator
To display a typing indicator, send a typing action.
{
"type": "action",
"value": {
"action": "typing",
"data": {
"typingTime": 1000
}
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| typingTime | No | long | Typing indicator display duration in milliseconds. If not specified, the default maximum display time is 5 seconds. | n/a |
Transfer to live agent
To transfer the conversation to a live agent, send a transfer action.
{
"type": "action",
"value": "TransferToLiveAgent"
}
Article
To send an article with content and sources, use the article type.
{
"type": "article",
"value": {
"title": "How Zoom can help you stay safe in cyberspace",
"content": "<!DOCTYPE html><html><head><style>body {background-color: powderblue;}h1 {color: blue;}p {color: red;}</style></head><body><h1>This is a heading</h1><p>This is a paragraph.</p></body></html>",
"style": "multi-sources",
"sources": [
{
"label": "reference 1",
"title": "this is reference 1",
"content": "<!DOCTYPE html><html><head><style>body {background-color: powderblue;}h1 {color: blue;}p {color: red;}</style></head><body><h1>This is a heading</h1><p>This is a paragraph.</p></body></html>",
"contentType": "markdown",
"url": "https://www.zoom.com/en/blog/how-zoom-can-help-you-stay-safe-in-cyberspace/"
},
{
"label": "reference 2",
"title": "this is reference 2",
"contentType": "html",
"content": "<!DOCTYPE html><html><head><style>body {background-color: powderblue;}h1 {color: blue;}p {color: red;}</style></head><body><h1>This is a heading</h1><p>This is a paragraph.</p></body></html>",
"url": "https://www.zoom.com/en/blog/how-zoom-can-help-you-stay-safe-in-cyberspace/"
}
]
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| title | Yes | String | Article title | 256 Bytes |
| content | Yes | String | Standard HTML format or plain text | n/a |
| sources | Yes | List | List of article sources | 20 |
| style | No | String | Source display style: single-source, multi-sources | n/a |
Article source
To add source references to an article, include source objects.
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | The button or label name | 128 Bytes |
| title | Yes | String | The title in the details | 256 Bytes |
| content | Yes | String | Standard HTML format or plain text | n/a |
| contentType | No | String | Content format type: markdown or html | n/a |
| url | No | String | The article link | n/a |
| openNewTab | No | Boolean | The URL will open in new tab | n/a |
Attachment
Note
Coming soon.
To send a file attachment, use the attachment type.
{
"type": "attachment",
"value": {
"title": "attachment pdf title",
"name": "attachment pdf name.pdf",
"url": "https://file-examples.com/storage/fe091522ae6912e509be331/2017/10/file-sample_150kB.pdf"
}
}
Warning
File size limit: 15MB
| Field | Required | Value Type | Description |
|---|---|---|---|
| title | Yes | String | Attachment title |
| url | Yes | String | Attachment URL |
| name | Yes | String | Attachment filename |
Audio
To send an audio file, use the audio type.
{
"type": "audio",
"value": {
"title": "This is a title",
"name": "audio name",
"url": "https://youtube.com/123456"
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| url | Yes | String | Audio URL | n/a |
| title | No | String | Audio title | 128 Bytes |
| name | No | String | Audio name | 128 Bytes |
Card
To send a card with an image, description, and action buttons, use the card type.
{
"type": "card",
"value": {
"title": "card title",
"description": "This text is **bold**.",
"imageUrl": "https://static-st1.zoomdev.us/static/6.3.34762/image/new/topNav/Zoom_logo.svg",
"options": [
{
"type": "option",
"label": "Select case 1",
"value": "case1"
},
{
"type": "link",
"label": "More",
"value": "https://example.com/link"
}
]
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| title | No | String | Card title | 256 Bytes |
| description | No | String | Standard Markdown format | 4096 Bytes |
| imageUrl | Yes | String | Image URL | n/a |
| options | Yes | List | List of card options | 20 |
| mandatory | No | Boolean | If true, and the options list contains at least one option type item (button), the live chat client will disable the input box if the button is not clicked. Default: false | n/a |
Card option types
Option button
To add an option button to a card, use type option.
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| type | Yes | String | option | |
| label | Yes | String | Display name | 128 Bytes |
| value | Yes | String | The identified value | n/a |
Link button
To add a link button to a card, use type link.
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| type | Yes | String | link | |
| label | Yes | String | Display name | 128 Bytes |
| value | Yes | String | URL | n/a |
Carousel
To send multiple cards in a carousel, use the carousel type.
{
"type": "carousel",
"value": {
"cards": [
{
"title": "carousel title 1",
"description": "This is the first item.",
"imageUrl": "https://images.unsplash.com/photo-1682685794304-99d3d07c57d2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=772&q=80",
"options": [
{
"type": "option",
"label": "Select case 1",
"value": "case1"
},
{
"type": "link",
"label": "More",
"value": "https://example.com/link"
}
]
},
{
"title": "carousel title 2",
"description": "This is the second item.",
"imageUrl": "https://plus.unsplash.com/premium_photo-1691852519415-0df4c22e49e1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80",
"options": [
{
"type": "option",
"label": "Select case 1",
"value": "case1"
},
{
"type": "link",
"label": "More",
"value": "https://example.com/link"
}
]
}
]
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| cards | Yes | List | List of card objects with the same structure as the card type | 10 |
Form
To collect information from consumers through a form, use the form type.
{
"type": "form",
"value": {
"name": "form name",
"title": "form title",
"subtitle": "I really like it ",
"fields": [
{
"type": "text",
"label": "Name",
"key": "name",
"required": true,
"defaultValue": "name"
},
{
"type": "single-select",
"label": "Education",
"key": "education",
"required": true,
"options": [
{
"label": "High School Diploma",
"value": "high_school"
},
{
"label": "Other",
"value": "other"
}
],
"defaultValue": "high_school"
},
{
"type": "multi-select",
"label": "Make you chocie",
"key": "option",
"required": true,
"options": [
{
"label": "Option1",
"value": "1"
},
{
"label": "Option2",
"value": "2"
},
{
"label": "Option3",
"value": "3"
}
],
"defaultValue": ["1", "2"]
}
]
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| name | No | String | Form name | |
| title | No | String | Form title | 256 Bytes |
| subtitle | No | String | Form subtitle | 1024 Bytes |
| mandatory | No | Boolean | If true, and the field list contains at least one field element, the live chat client will disable the input box before the form has been submitted. Default: false. Note: Works with livechat SDK only. | |
| fields | Yes | List | List of form fields |
Text input field
To add a text input field to a form, use the text field type.
{
"type": "text",
"label": "Name",
"key": "name",
"required": true,
"defaultValue": "",
"pattern": "text"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | Field label | 128 Bytes |
| key | Yes | String | Field key | 64 Bytes |
| required | No | Boolean | Whether field is required | |
| defaultValue | No | String | Default value | 256 Bytes |
| pattern | No | String | Validation pattern: text (no rule)email (must be in email address format)integer (require input of positive integers)decimal (require decimal input)custom (use the regex set in field customRegex to do the validation). Default: text | |
| customRegex | No | String | Regular expression for custom pattern validation | 128 characters |
| errorLabel | No | String | The error message to show while the data is invalid | 128 characters |
Note
Maximum text input value length is 256 Bytes.
Select field
To add a single-select dropdown to a form, use the single-select field type.
{
"type": "single-select",
"label": "Education",
"key": "education",
"required": true,
"options": [
{
"label": "High School Diploma",
"value": "high_school"
},
{
"label": "Associate Degree",
"value": "associate"
},
{
"label": "Bachelor's Degree",
"value": "bachelor"
},
{
"label": "Doctoral Degree (Ph.D.)",
"value": "doctor"
},
{
"label": "Other",
"value": "other"
}
],
"defaultValue": ""
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | Field label | 128 Bytes |
| key | Yes | String | Field key | 128 Bytes |
| required | No | Boolean | Whether field is required | |
| defaultValue | No | String | Default option value | |
| options | Yes | List | List of select options |
Select option
Each option in a select field has the following structure.
{
"label": "Male",
"value": "male"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | Display name | 128 Bytes |
| value | Yes | String | The identify value | 128 Bytes |
Multi-select field
To add a multi-select dropdown to a form, use the multi-select field type.
{
"type": "multi-select",
"label": "Make you chocie",
"key": "option",
"required": true,
"options": [
{
"label": "Option1",
"value": "1"
},
{
"label": "Option2",
"value": "2"
},
{
"label": "Option3",
"value": "3"
}
],
"defaultValues": ["1", "2"]
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | Field label | 128 Bytes |
| key | Yes | String | Field key | 64 Bytes |
| required | No | Boolean | Whether field is required | |
| defaultValue | No | List | Default option values | |
| options | Yes | List | List of select options |
Multi-select option
Each option in a multi-select field has the following structure.
{
"label": "Male",
"value": "male"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| label | Yes | String | Display name | 128 Bytes |
| value | Yes | String | The identify value. Only strings consisting of a-z and 0-9 are allowed. | 64 Bytes |
HTML
To send HTML-formatted messages, use the html type.
{
"type": "html",
"value": "<!DOCTYPE html><html><head><title>Page Title</title></head><body><h1>HTML message</h1><a href=\"https://zoom.com\">Zoom</a><p><b>Please type your query below</b></p></body></html>"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| value | Yes | String | Standard HTML format | n/a |
Image
To send an image, use the image type.
{
"type": "image",
"value": {
"title": "image title",
"width": 300,
"height": 200,
"name": "zoom_logo",
"altText": "This is a logo",
"url": "https://zoom.us/logo.jpeg"
}
}
| Field | Required | Value Type | Description | Limitation |
|---|---|---|---|---|
| url | Yes | String | Image URL | n/a |
| width | No | Number | Image width | n/a |
| height | No | Number | Image height | n/a |
| name | No | String | Image name | 128 Bytes |
| altText | No | String | Text displayed when hovering the mouse | 128 Bytes |
Link
To send a link, use the link type.
{
"type": "link",
"value": {
"label": "link name",
"url": "https://zoom.us"
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| url | Yes | String | Link URL | n/a |
| label | No | String | Link label | 128 Bytes |
Markdown
To send Markdown-formatted messages, use the markdown type.
{
"type": "markdown",
"value": "## This text is **bold**."
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| value | Yes | String | Standard Markdown format | n/a |
Quick replies
To provide quick reply buttons for consumer responses, use the quickReplies type.
{
"type": "quickReplies",
"value": {
"title": "Please make your choice",
"options": [
{
"label": "Yes",
"type": "postback",
"value": "yes"
},
{
"label": "No",
"type": "postback",
"value": "no"
}
],
"mandatory": true
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| title | Yes | String | Title text | 1024 Bytes |
| options | Yes | List | List of quick reply options | 20 |
| options.label | Yes | String | Display name | 128 Bytes |
| options.type | Yes | String | Option type: postback, phone_number, web_url, trigger_intent | |
| options.value | Yes | String | The identified value | n/a |
| mandatory | No | Boolean | If true, the live chat client will disable the input box when the quick reply button is not clicked. Default: false | n/a |
Text
To send plain text messages, use the text type.
{
"type": "text",
"value": "Hi, I'm your virtual agent!"
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| value | Yes | String | Plain text | n/a |
Video
To send a video (YouTube), use the video type.
{
"type": "video",
"value": {
"title": "This is a title",
"name": "video name",
"url": "https://youtube.com/123456"
}
}
| Field | Required | Value | Description | Limitation |
|---|---|---|---|---|
| url | Yes | String | Video URL | n/a |
| title | No | String | Video title | 128 Bytes |
| name | No | String | Video name | 128 Bytes |