## Chats by CRM card

`GET /v1/openlines/crm/chats` · `POST /v1/openlines/sessions/intercept` · `POST /v1/openlines/sessions/join`

Three endpoints cover the CRM-card widget flow: find the Open Channel dialogs attached to a lead, deal, company or contact, then put the current operator into the dialog you found. All three require the `imopenlines` scope, are available on every Bitrix24 account and do not require the `imopenlines 26.700.0` update.

The `chatId` from the first endpoint's response is passed to the second and third endpoints unchanged. The other source of the same identifier is the `sessions[].chatId` field in the [Session list](./sessions.md) response.

**Important:** `sessions/intercept` and `sessions/join` write into a live conversation with a client: after the call the operator becomes a participant in the conversation. Permissions are checked by Bitrix24, and a Bitrix24 account administrator passes that check for any dialog on the account.

## Chats of a CRM card

`GET /v1/openlines/crm/chats`

### Request parameters (query)

| Parameter | Type | Description |
|-----------|------|-------------|
| `crmEntityType` | string | Required. One of `lead`, `deal`, `company`, `contact`. Case-insensitive |
| `crmEntityId` | number | Required. Identifier of the CRM object, a positive integer |
| `activeOnly` | boolean \| string | Optional. `true`, `false`, `Y`, `N`, `1`, `0`. Without the parameter only open dialogs are returned; `false` adds the closed ones |

Each parameter is passed exactly once and under a flat name: a repeat (`crmEntityId=1&crmEntityId=2`) and the bracket form (`crmEntityId[]=1`) are rejected with `400 INVALID_PARAMS` rather than resolved in favor of one of the values.

### Response fields

`data` is an array of rows. For an object with no Open Channel dialogs it is empty, and that is not an error. It is also empty when no object with that `crmEntityId` exists.

| Field | Type | Description |
|-------|------|-------------|
| `chatId` | number | Open Channel chat identifier. Goes into `sessions/intercept` and `sessions/join` as is |
| `connectorId` | string \| null | Identifier of the channel the dialog came from |
| `connectorTitle` | string \| null | Human-readable channel name |

### Example

```bash
curl "https://vibecode.bitrix24.com/v1/openlines/crm/chats?crmEntityType=lead&crmEntityId=1001213" \
  -H "X-Api-Key: YOUR_API_KEY"
```

```json
{
  "success": true,
  "data": [
    { "chatId": 4531, "connectorId": "telegrambot", "connectorTitle": "Telegram" }
  ]
}
```

The same request with `activeOnly=false` for an object whose dialogs are already closed returns them in the same shape — for example `{ "chatId": 31, "connectorId": "network", "connectorTitle": "Bitrix24 Network" }`.

## Intercepting a dialog

`POST /v1/openlines/sessions/intercept`

Moves the dialog to the current operator: the previous operator is no longer in charge of this session.

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openlines/sessions/intercept" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "chatId": 4531 }'
```

Successful response: `{ "success": true, "data": { "chatId": 4531, "intercepted": true } }`.

## Joining a dialog

`POST /v1/openlines/sessions/join`

Adds the current operator to the dialog as one more participant, leaving the previous one in place.

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/openlines/sessions/join" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "chatId": 4531 }'
```

Successful response: `{ "success": true, "data": { "chatId": 4531, "joined": true } }`.

Both endpoints accept `chatId` as a number (`4531`) or as a string in the `chat4531` form; in the response the identifier is always a number. The field name is `chatId` or `CHAT_ID`; `dialogId` is not accepted.

## Errors

| HTTP | Code | Description |
|:----:|------|-------------|
| 400 | `MISSING_PARAMS` | A required parameter is missing: `crmEntityType`, `crmEntityId` or `chatId` |
| 400 | `INVALID_PARAMS` | A parameter value is invalid: `crmEntityType` outside the list, `crmEntityId` not a positive integer, `chatId` cannot be parsed into a chat identifier (a positive integer and the `chat<N>` form are accepted), `activeOnly` outside the accepted set. The same code is returned when a query parameter is passed twice or in the bracket form |
| 401 | `TOKEN_MISSING` | The key has no configured tokens |
| 403 | `SCOPE_DENIED` | The key has no `imopenlines` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is read-only, while `sessions/intercept` and `sessions/join` change the dialog |
| 403 | `BITRIX_ACCESS_DENIED` | The key's user has no access to the CRM object or to the dialog |
| 422 | `BITRIX_ERROR` | Bitrix24 rejected the request; its code is returned in `error.b24Code`. For `sessions/join`: `CHAT_ID` — no chat with that identifier, `CHAT_TYPE` — the chat is not an Open Channel. For `sessions/intercept` both cases give `OPERATOR_WRONG`. The `error.message` text comes from Bitrix24 verbatim: for `CHAT_ID` and `CHAT_TYPE` in the portal language, for `OPERATOR_WRONG` in English |
| 429 | `RATE_LIMITED` | Two sources return this code. The first is the platform's own operation limit, counted per portal rather than per key: 300 requests per minute for `crm/chats`, 120 for `sessions/intercept` and `sessions/join`. Take the effective value from the `X-RateLimit-Limit` header, the remaining quota and the reset time from `X-RateLimit-Remaining` and `X-RateLimit-Reset`; they come with every response. The second is Bitrix24 rejecting the call under its own request rate limit: the response carries a `Retry-After` header |
| 502 | `OPENLINE_SESSION_FAILED` | Bitrix24 answered without confirmation — `result` is not `true`, yet no error was returned. A closed dialog does not produce this response: joining and intercepting a closed dialog succeed |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 returned a response of an unexpected shape |

A misspelled `crmEntityType` is rejected before Bitrix24 is called — with `400 INVALID_PARAMS` and the list of accepted values.

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **Dialog closure is not checked.** `sessions/intercept` and `sessions/join` succeed on a dialog whose session was closed long ago: the operator is added to the chat participants, the response is `intercepted: true` and `joined: true`. To work with open dialogs only, take `chatId` from `crm/chats` without `activeOnly=false`.
- **A repeated join is not an error.** `sessions/join` for an operator who already participates in the dialog answers `joined: true` again.
- **The join is visible in the participant list.** After `join` the operator appears among the participants of the Open Channel chat — that is the check that the call took effect.

## See also

- [Session list](./sessions.md)
- [Dialog metadata](./dialog.md)
- [Session history](./history.md)
- [Open Channels](/docs/openlines)
