openapi: 3.0.0 info: title: Bots pinmessages API description: "
Bots are conversational assistants designed to automate repetitive tasks and manage simple user interactions. Their behavior is fully customizable through predefined Bot Handlers, which are activated by specific actions or through Webhooks that communicate with your own external server.
For more information about Bots, please refer to the Bots Help Documentation.
Bot Handlers
Types of Bot Handlers
| Handler | \nDescription | \n
|---|---|
| Menu Handler | \nAdds up to 5 quick-action items to the bot's chat menu. Triggered when a user interacts with the menu. | \n
| Message Handler | \nTriggered when the bot receives a message. | \n
| Welcome Handler | \nDefines the greeting message sent when a user subscribes to the bot. | \n
| Mention Handler | \nTriggered when the bot is @mentioned in a chat or channel. | \n
| Incoming Webhook Handler | \nAllows external services to post messages into the bot via outgoing webhooks. | \n
| Context Handler | \nManages multi-turn conversations, maintaining context across a user's interaction with the bot. | \n
What you can do with the Bots API?
With the Bots API, you can retrieve information about a specific bot, list all bots within your organization, manage configurations specific to handlers, trigger bot calls programmatically, manage subscribers, and much more.
Each bot has an execution_type that defines how its handlers run when a trigger event occurs. The Bots API allows developers to create two types of bots:
Deluge Bots (default)
Deluge bot executes handler logic using Zoho's Deluge scripting language, hosted entirely within the Zoho Cliq Developer platform, where no external server is required.
execution_type is not specified during bot creation, it defaults to deluge.Webhook Bots
A Webhook bot delegates all handler execution to your own external server. When a trigger event fires, Zoho Cliq sends an HTTP POST request to the execution_url you configure, and your server processes the event and returns a response.
execution_type to webhook during bot creation and provide the execution_url where event payloads should be sent.\n Threshold limit: 20 requests per min per user
\n Number of API calls allowed within a minute.
\n Lock period: 5 minutes
Wait time before consecutive API requests.
\n
| Error Code | \nDescription | \n
|---|---|
| operation_not_allowed | \nUser might not be a participant of that chat. | \n
| operation_failed | \nUnexpected error while fetching the primary pin. | \n
When an error occurs, the API returns a JSON response in this format:
\n{\"message\": \"A human-readable description of the error.\", \"code\": \"error_code\"}\n where code is the error identifier (as listed above) and message is a human-readable explanation of what went wrong.
sync_token received in an earlier response to fetch only updates after that sync point.primary=true).
content:
application/json:
schema:
$ref: '#/components/schemas/get-pinned-messages-response'
'400':
description: Bad Request.
content:
application/json:
schema:
$ref: '#/components/schemas/error-response'
examples:
operation_not_allowed:
summary: User is not a participant of the chat
value:
message: Uh-Oh! You are not authorized to do this operation.
code: operation_not_allowed
operation_failed:
summary: Unexpected error while fetching the primary pin
value:
code: operation_failed
'401':
description: Unauthorized.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Request was rejected because of invalid AuthToken.
'403':
description: Forbidden.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The user does not have enough permission or possibly not an user of the respective organization to access the resource.
'404':
description: Invalid URL.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The URL you've sent is wrong. It's possible that the resource you've requested has been moved to another URL.
'405':
description: Method Not Allowed.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The requested resource does not support the HTTP method used. For example, requesting List of all customers API with PUT as the HTTP method.
'406':
description: Not Acceptable.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The response has been received but the requested response type is not supported by the browser.
'429':
description: Too many requests.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Too many requests within a certain time frame.
'500':
description: Internal Server Error.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Cliq server encountered an error which prevents it from fulfilling the request.
security:
- Cliq_Auth:
- ZohoCliq.Chats.READ
post:
summary: Add a pinned message
operationId: addPinnedMessage
description: "Pins a message in a chat.\n\n Threshold limit: 20 requests per min per user
\n Number of API calls allowed within a minute.
\n Lock period: 5 minutes
Wait time before consecutive API requests.
\n
| Error Code | \nDescription | \n
|---|---|
| operation_failed | \nInvalid expiry time - the specified time is in the past. | \n
| operation_not_allowed | \nUser might not be a participant of that chat. | \n
When an error occurs, the API returns a JSON response in this format:
\n{\"message\": \"A human-readable description of the error.\", \"code\": \"error_code\"}\n where code is the error identifier (as listed above) and message is a human-readable explanation of what went wrong.
\n Threshold limit: 20 requests per min per user
\n Number of API calls allowed within a minute.
\n Lock period: 5 minutes
Wait time before consecutive API requests.
\n
| Error Code | \nDescription | \n
|---|---|
| client_not_synced | \nThe provided sync timestamp is stale. Re-fetch pins and retry. | \n
| operation_failed | \nIncorrect values submitted. | \n
| operation_not_allowed | \nCaller is not authorized to perform this operation. | \n
When an error occurs, the API returns a JSON response in this format:
\n{\"message\": \"A human-readable description of the error.\", \"code\": \"error_code\"}\n where code is the error identifier (as listed above) and message is a human-readable explanation of what went wrong.
\n Threshold limit: 20 requests per min per user
\n Number of API calls allowed within a minute.
\n Lock period: 5 minutes
Wait time before consecutive API requests.
\n
| Error Code | \nDescription | \n
|---|---|
| operation_not_allowed | \nCaller is not authorized to perform this operation. | \n
When an error occurs, the API returns a JSON response in this format:
\n{\"message\": \"A human-readable description of the error.\", \"code\": \"error_code\"}\n where code is the error identifier (as listed above) and message is a human-readable explanation of what went wrong.
message_ids to remove specific pinned messages. If omitted, all pinned messages in the chat are removed.
content:
application/json:
schema:
$ref: '#/components/schemas/delete-pinned-messages-request'
responses:
'204':
description: Pinned message(s) deleted successfully. No response body.
'400':
description: Bad Request.
content:
application/json:
schema:
$ref: '#/components/schemas/error-response'
examples:
operation_not_allowed:
summary: Caller is not authorized to perform this operation
value:
message: Uh-Oh! You are not authorized to do this operation.
code: operation_not_allowed
'401':
description: Unauthorized.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Request was rejected because of invalid AuthToken.
'403':
description: Forbidden.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The user does not have enough permission or possibly not an user of the respective organization to access the resource.
'404':
description: Invalid URL.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The URL you've sent is wrong. It's possible that the resource you've requested has been moved to another URL.
'405':
description: Method Not Allowed.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The requested resource does not support the HTTP method used. For example, requesting List of all customers API with PUT as the HTTP method.
'406':
description: Not Acceptable.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: The response has been received but the requested response type is not supported by the browser.
'429':
description: Too many requests.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Too many requests within a certain time frame.
'500':
description: Internal Server Error.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Cliq server encountered an error which prevents it from fulfilling the request.
security:
- Cliq_Auth:
- ZohoCliq.Chats.DELETE
/chats/{CHAT_ID}/pin-messages?primary=true:
get:
summary: Get primary pinned message
operationId: getPrimaryPinnedMessage
description: "Fetches the primary pinned message in a chat. The primary pin is the most prominently displayed pinned message, typically shown at the top of the pinned list and highlighted in the UI.\n\n Threshold limit: 20 requests per min per user
\n Number of API calls allowed within a minute.
\n Lock period: 5 minutes
Wait time before consecutive API requests.
\n
| Error Code | \nDescription | \n
|---|---|
| operation_not_allowed | \nUser might not be a participant of that chat. | \n
| operation_failed | \nUnexpected error while fetching the primary pin. | \n
When an error occurs, the API returns a JSON response in this format:
\n{\"message\": \"A human-readable description of the error.\", \"code\": \"error_code\"}\n where code is the error identifier (as listed above) and message is a human-readable explanation of what went wrong.
"2026-04-19T19:09:44+05:30") or epoch timestamps (e.g., 1745068184000). The server rejects the request if this is stale.
'
oneOf:
- type: string
- type: integer
example:
message_id: '1773894772896_12958180473'
pin_above: '1773895219462_47318365091'
last_sync_time: 1745068184000
pinned-message:
type: object
description: A pinned message object. Contains the original message fields (id, type, content, sender, time, mentions) along with pin-specific fields.
properties:
id:
type: string
type:
type: string
example: text
content:
type: object
properties:
text:
type: string
sender:
type: object
properties:
name:
type: string
id:
type: string
time:
type: string
format: date-time
mentions:
type: array
description: Present only when the message contains mentions.
items:
type: object
properties:
name:
type: string
id:
type: string
type:
type: string
is_pinned:
type: boolean
description: Always true for pinned messages.
pin_information:
$ref: '#/components/schemas/pin-information'
get-pinned-messages-response:
type: object
description: Response envelope for listing all pinned messages.
properties:
url:
type: string
type:
type: string
example: pinmessages
sync_token:
type: string
description: Pass in subsequent requests to fetch only pins updated since the last sync.
data:
type: array
items:
$ref: '#/components/schemas/pinned-message'
example:
url: /company/16557244/v3/chats/1488288613043522033/pin-messages
type: pinmessages
sync_token: NTB8MTc3MzkyNzUxMjcwNnw0MDAwMDAwMDExMDAz
data:
- is_pinned: true
pin_information:
expiry_time: -1
creator:
name: Tim Harrison
id: '16557777'
created_time: '2026-03-19T19:08:32+05:30'
last_modified_time: '2026-03-19T19:08:32+05:30'
is_primary: true
sender:
name: Tim Harrison
id: '16557777'
type: text
content:
text: '{@16557498}'
time: '2026-03-19T10:02:52+05:30'
id: 1.7738947728961294e+23
mentions:
- name: '@sharan 203'
id: '16557498'
type: user
error-response:
type: object
description: Error response returned by the Pin Messages API.
properties:
message:
type: string
description: Human-readable error description.
code:
type: string
description: Machine-readable error code.
enum:
- operation_not_allowed
- operation_failed
- client_not_synced
- pinned_message_limit_reached
add-pinned-message-request:
type: object
description: Request body for pinning a message in a chat.
required:
- message_id
- expiry_time
- notify
properties:
message_id:
type: string
description: 'ID of the message to pin. This message must already exist in the chat and cannot be deleted.
'
expiry_time:
description: 'When the pin should expire. Accepts ISO 8601 datetime strings (e.g., "2026-04-19T19:09:44+05:30") or epoch timestamps (e.g., 1745068184000). Use -1 for no expiry.
'
oneOf:
- type: string
- type: integer
notify:
type: boolean
description: 'Set to true to send a notification to chat participants about the new pin. Defaults to false.
'
primary:
type: boolean
description: 'Set to true to pin as the primary (top) message. Defaults to false. If this is the first pin in the chat, it automatically becomes primary regardless of this value.
'
example:
message_id: '1773894772896_12958180473'
expiry_time: '2026-04-19T19:09:44+05:30'
notify: false
add-pinned-message-response:
type: object
description: Response envelope after pinning a message.
properties:
url:
type: string
type:
type: string
example: pinmessages
data:
$ref: '#/components/schemas/pinned-message'
example:
url: /v3/chats/1488288613043522033/pin-messages
type: pinmessages
data:
pin_information:
expiry_time: '2026-04-19T19:09:44+05:30'
creator:
name: Tim Harrison
id: '16557777'
created_time: '2026-03-19T19:08:32+05:30'
last_modified_time: '2026-03-19T19:08:32+05:30'
is_primary: false
is_pinned: true
sender:
name: Tim Harrison
id: '16557777'
type: text
content:
text: Please review the deployment checklist before the release.
time: '2026-03-19T10:02:52+05:30'
id: '1773894772896_12958180473'
delete-pinned-messages-request:
type: object
description: Request body for deleting specific pinned messages.
required:
- message_ids
properties:
message_ids:
type: array
description: 'List of message IDs to unpin. These messages must currently be pinned in the chat. If this field is omitted or an empty array is provided, all pinned messages in the chat are removed.
-1 means no expiry. ISO 8601 datetime string when an expiry is set.
'
oneOf:
- type: integer
example: -1
- type: string
example: '2026-04-19T19:09:44+05:30'
creator:
type: object
properties:
name:
type: string
id:
type: string
created_time:
type: string
format: date-time
last_modified_time:
type: string
format: date-time
is_primary:
type: boolean
description: true if this is the primary (top) pinned message.
get-primary-pinned-message-response:
type: object
description: Response envelope when fetching the primary pinned message.
properties:
url:
type: string
type:
type: string
example: pinmessages
data:
$ref: '#/components/schemas/pinned-message'
example:
url: /company/16557244/v3/chats/1488288613043522033/pin-messages
type: pinmessages
data:
type: text
id: '1746000123456789001'
time: '2026-04-30T09:00:00Z'
sender:
id: '1234567890'
name: Alice Johnson
content:
text: Please review the Q2 report before Friday.
is_pinned: true
pin_information:
expiry_time: -1
creator:
id: '9876543210'
name: Bob Smith
created_time: '2026-04-30T09:15:00Z'
last_modified_time: '2026-04-30T09:15:00Z'
is_primary: true
securitySchemes:
Cliq_Auth:
type: oauth2
x-authorization-example: Bearer 1000.41d9xxxxxxxxxxxxxxxxxxxxxxxxc2d1.8fccxxxxxxxxxxxxxxxxxxxxxxxx125f
flows:
implicit:
authorizationUrl: https://accounts.zoho.com/oauth/v2/auth
scopes:
ZohoCliq.Bots.READ: Read Bot Information
ZohoCliq.Bots.CREATE: Create Bots
ZohoCliq.Bots.UPDATE: Update Bots
ZohoCliq.Bots.DELETE: Delete Bots
ZohoCliq.Webhooks.CREATE: Post messages to conversations via webhooks
ZohoCliq.BotMessages.CREATE: Send messages via bot incoming webhooks
ZohoCliq.Channels.UPDATE: Update Channel Settings
externalDocs:
description: Find out more about Zoho Cliq APIs V3
url: https://www.zoho.com/cliq/help/restapi/v3/