
# Chats and messages

Work with the Bitrix24 messenger on behalf of the authorized user: find chats of CRM entities, read and send messages, manage members, upload files, and receive events via polling.

**Scope:** `im` | **Base URL:** `https://vibecode.bitrix24.com/v1` | **Authorization:** `X-Api-Key`

[Quick start](#quick-start) | [Full example](#full-example) | [Endpoint reference](#endpoint-reference) | [Error codes](#error-codes)

## Documentation sections

- [Chat discovery](/docs/chats/discovery) — list of recent dialogs, finding a CRM entity chat, text search, dialog details
- [Messages](/docs/chats/messages) — read, send, edit, delete, mark as read, bulk loading
- [Chat management](/docs/chats/management) — creating group chats, renaming, transferring ownership, leaving
- [Members](/docs/chats/members) — list of members, adding, removing
- [Files](/docs/chats/files) — uploading files to a chat, file metadata, the chat folder on Drive
- [Events](/docs/chats/events) — subscribe, poll messenger events, unsubscribe

## Message formatting

References for formatting text when sending and editing messages:

- [Text formatting (BB codes)](/docs/chats/messages/formatting)
- [Keyboard](/docs/chats/messages/keyboard)
- [Attachments](/docs/chats/messages/attach)

## Chat identifiers

Two kinds of identifiers appear in requests:

- `dialogId` — the dialog identifier: a number (user ID) for a private conversation, a string of the form `chatN` (for example `chat123`) for group chats.
- `chatId` — the numeric chat ID without the `chat` prefix. Required for managing the chat, members, and files.

Instead of your own identifier you can pass the literal `me` — it is replaced with the ID of the current user who owns the key. This lets you send a message to yourself without requesting your own ID with a separate call. The literal is written in lowercase and works everywhere `dialogId` is accepted: dialog details, reading and sending messages, list of members.

Example — send yourself a notification:

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/chats/me/messages" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Quarterly report is ready"}'
```

## Direct message to a user

To send a personal message to a specific user, pass their numeric Bitrix24 user ID as the `dialogId`. No separate lookup or dialog creation is needed — `POST /v1/chats/:dialogId/messages` with a numeric `dialogId` delivers the message to a private conversation with that user. The chat lookup [`GET /v1/chats/find`](/docs/chats/discovery/find) finds chats of CRM entities and is not required for a private dialog.

A user's numeric ID comes from the user list [`GET /v1/users`](/docs/entities/users).

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/chats/42/messages" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Sales digest for today is ready"}'
```

## Quick start

Find the chat of a CRM deal, read the messages, and send a reply.

### 1. Find the deal chat

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://vibecode.bitrix24.com/v1/chats/find?entityType=CRM&entityId=DEAL|123"
```

Response:

```json
{
  "success": true,
  "data": {
    "id": 2741
  }
}
```

`data.id` is the numeric `chatId`. To build the `dialogId` when calling the message endpoints, add the `chat` prefix: `chat2741`.

### 2. Read the messages

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://vibecode.bitrix24.com/v1/chats/chat2741/messages?limit=5"
```

Response:

```json
{
  "success": true,
  "data": {
    "chatId": 253,
    "messages": [
      {
        "id": 9357,
        "chatId": 253,
        "authorId": 1,
        "date": "2026-04-26T18:10:54+00:00",
        "text": "Team, the proposal is approved. We can issue the invoice.",
        "unread": false
      }
    ],
    "users": [
      {
        "id": 1,
        "name": "John Brown",
        "firstName": "John",
        "lastName": "Brown"
      }
    ],
    "files": []
  }
}
```

### 3. Send a reply

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/chats/chat2741/messages" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Invoice issued. Number: INV-2026-0458"}'
```

Response:

```json
{
  "success": true,
  "data": 36889
}
```

`data` is the ID of the sent message.

## Full example

A continuous scenario: create a group chat, send a greeting, mark the conversation as read, rename the chat, and leave it.

```javascript
const VIBE_KEY = process.env.VIBE_KEY
const BASE = 'https://vibecode.bitrix24.com/v1'

async function api(method, path, body = null) {
  const opts = { method, headers: { 'X-Api-Key': VIBE_KEY } }
  if (body) {
    opts.headers['Content-Type'] = 'application/json'
    opts.body = JSON.stringify(body)
  }
  const res = await fetch(`${BASE}${path}`, opts)
  return res.json()
}

// 1. Create a group chat
const created = await api('POST', '/chats', {
  title: 'Working group',
  users: [1, 5, 12],
})
const chatId = created.data            // numeric chatId
const dialogId = `chat${chatId}`       // dialogId for the message endpoints
console.log('Chat created, ID:', chatId)

// 2. Send a greeting
const sent = await api('POST', `/chats/${dialogId}/messages`, {
  message: 'Welcome to the working group!',
})
console.log('Message sent, ID:', sent.data)

// 3. Mark the conversation as read
const read = await api('POST', `/chats/${dialogId}/read`, {})
console.log('Unread remaining:', read.data.counter)

// 4. Rename the chat — management is done by the numeric chatId, without the chat prefix
await api('PATCH', `/chats/${chatId}`, {
  title: 'Project: Equipment delivery',
})

// 5. Leave the chat
await api('POST', `/chats/${chatId}/leave`, {})
console.log('Done')
```

> If you are the chat owner, first transfer ownership via `POST /v1/chats/:chatId/owner`, then leave the chat — otherwise you will leave the chat but remain its owner.

## Endpoint reference

All 23 endpoints of the section:

| Method | Path | Bitrix24 method | Description |
|-------|------|---------------|---------|
| GET | [/v1/chats/recent](/docs/chats/discovery/recent) | im.recent.list | Recent dialogs |
| GET | [/v1/chats/find](/docs/chats/discovery/find) | im.chat.get | Find a CRM entity chat |
| GET | [/v1/chats/search](/docs/chats/discovery/search) | im.search.chat.list | Search chats by text |
| GET | [/v1/chats/:dialogId](/docs/chats/discovery/get) | im.dialog.get | Dialog details |
| GET | [/v1/chats/:dialogId/messages](/docs/chats/messages/list) | im.dialog.messages.get | Read messages |
| POST | [/v1/chats/:dialogId/messages](/docs/chats/messages/send) | im.message.add | Send a message |
| PATCH | [/v1/chats/:dialogId/messages/:messageId](/docs/chats/messages/update) | im.message.update | Edit a message |
| DELETE | [/v1/chats/:dialogId/messages/:messageId](/docs/chats/messages/delete) | im.message.delete | Delete a message |
| POST | [/v1/chats/:dialogId/read](/docs/chats/messages/read) | im.dialog.read | Mark as read |
| POST | [/v1/chats/messages/bulk](/docs/chats/messages/bulk) | batch (im.dialog.messages.get) | Bulk loading from several dialogs |
| POST | [/v1/chats](/docs/chats/management/create) | im.chat.add | Create a group chat |
| PATCH | [/v1/chats/:chatId](/docs/chats/management/rename) | im.chat.updateTitle | Rename a chat |
| POST | [/v1/chats/:chatId/owner](/docs/chats/management/owner) | im.chat.setOwner | Transfer ownership |
| POST | [/v1/chats/:chatId/leave](/docs/chats/management/leave) | im.chat.leave | Leave a chat |
| GET | [/v1/chats/:dialogId/users](/docs/chats/members/list) | im.dialog.users.list | List of members |
| POST | [/v1/chats/:chatId/users](/docs/chats/members/add) | im.chat.user.add | Add members |
| DELETE | [/v1/chats/:chatId/users](/docs/chats/members/remove) | im.chat.user.delete | Remove a member |
| POST | [/v1/chats/:chatId/files](/docs/chats/files/upload) | im.disk.folder.get + disk.folder.uploadfile + im.disk.file.commit | Upload a file to a chat |
| GET | [/v1/chats/files/:fileId](/docs/chats/files/file-get) | disk.file.get | File metadata |
| GET | [/v1/chats/:chatId/folder](/docs/chats/files/folder) | im.disk.folder.get | Chat folder on Drive |
| POST | [/v1/chats/events/subscribe](/docs/chats/events/subscribe) | im.v2.Event.subscribe | Subscribe to events |
| POST | [/v1/chats/events/unsubscribe](/docs/chats/events/unsubscribe) | im.v2.Event.unsubscribe | Unsubscribe from events |
| GET | [/v1/chats/events](/docs/chats/events/poll) | im.v2.Event.get | Get events |

## Error codes

Codes specific to working with chats:

| Code | HTTP | Description |
|-----|------|---------|
| `SCOPE_DENIED` | 403 | The API key does not have the `im` scope |
| `TOKEN_MISSING` | 401 | The API key has no Bitrix24 tokens configured |
| `MISSING_PARAMS` | 400 | Required parameters were not passed (`entityType`/`entityId` when searching, `filename`/`content` when uploading a file) |
| `INVALID_REQUEST` | 400 | Malformed request body (for example, an empty `dialogs` array in bulk loading) |
| `BATCH_LIMIT_EXCEEDED` | 400 | The limit of 50 dialogs in bulk loading is exceeded |
| `INVALID_CHAT_ID` | 400 | `chatId` is not a positive integer |
| `TITLE_EMPTY` | 400 | Empty title when renaming a chat |
| `INVALID_OFFSET` | 400 | Invalid `offset` when polling events |
| `INVALID_LIMIT` | 400 | `limit` is out of the allowed range |
| `CHAT_NOT_FOUND_OR_NO_ACCESS` | 404 | The chat does not exist or there are no rights for the operation |
| `DIALOG_NOT_FOUND_OR_NO_ACCESS` | 404 | The dialog does not exist or there is no access |
| `ENTITY_NOT_FOUND` | 404 | The requested object was not found |
| `FILE_NOT_FOUND` | 404 | A file with the given `fileId` was not found |
| `FOLDER_NOT_FOUND` | 404 | The chat folder on Drive was not found |
| `UPLOAD_FAILED` | 500 | Failed to upload the file to Drive |
| `ME_ALIAS_RESOLUTION_FAILED` | 502 | Failed to resolve the current user for the `me` alias |
| `BITRIX_ERROR` | 422 | Bitrix24 returned an error (text in the `message` field) |
| `BITRIX_UNAVAILABLE` | 502 | The Bitrix24 portal is unavailable or returned a server error |

General codes for authorization, keys, and limits are on the [Errors](/docs/errors) page.

## See also

- [Bot platform](/docs/bots)
- [Notifications](/docs/notifications)
- [Keys and authorization](/docs/keys-auth)
- [Limits and optimization](/docs/optimization)
- [Errors reference](/docs/errors)
