## Finish a session

`POST /v1/bots/:botId/openlines/session/finish`

Finishes the current Open Channel session on behalf of the bot that runs the conversation. Call it when the bot has resolved the customer's question itself and the conversation does not need to go to an operator.

## Parameters

| Parameter | Type | Required | Default | Description |
|----------|-----|:-----:|-----------|----------|
| `botId` (path) | integer | yes | — | ID of a bot registered with this key. List: [`GET /v1/bots`](/docs/bots/management/list) |

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `chatId` | integer \| string | yes | Open Channel chat ID: a positive integer, a string of digits or the `chat<N>` form. Source: the `data.chat.id` field of a [bot event](/docs/bots/events/bot-events) or `sessions[].chatId` in [`POST /v1/openlines/sessions/search`](/docs/openlines/sessions/search). Instead of `chatId`, you can pass `dialogId` or `CHAT_ID` |
| `dialogId` | string | no | The same chat, only in the `chat<N>` form, for example `chat2043`. A number without the prefix is not accepted here |
| `CHAT_ID` | integer \| string | no | Alternative name for `chatId` with the same formats |

The first of `chatId`, `dialogId` and `CHAT_ID` that is set is read, checked in exactly this order. A field set to `null` counts as not set. An invalid value in the first filled field returns `400 INVALID_CHAT_ID`, and the remaining fields are not checked in that case.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/bots/621/openlines/session/finish" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"chatId": 2043}'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/bots/621/openlines/session/finish" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chatId": 2043}'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/bots/621/openlines/session/finish', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ chatId: 2043 }),
})

const { success, data, error } = await res.json()
console.log(success ? data.finished : error.code)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/bots/621/openlines/session/finish', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ chatId: 2043 }),
})

const { success, data, error } = await res.json()
console.log(success ? data.finished : error.code)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` when Bitrix24 confirmed the call |
| `data.chatId` | integer | ID of the chat the action was applied to. Returned as a number even if the request passed the `chat<N>` form |
| `data.finished` | boolean | Always `true` in a successful response |

## Response example

```json
{
  "success": true,
  "data": {
    "chatId": 2043,
    "finished": true
  }
}
```

## Error response example

404 — no bot with this `botId` on the Bitrix24 account:

```json
{
  "success": false,
  "error": {
    "code": "BOT_NOT_FOUND",
    "message": "Bot 999999 not found. Register it first via POST /v1/bots."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_BOT_ID` | `botId` in the path is not a positive integer |
| 400 | `INVALID_PARAMS` | The request body is not a JSON object, for example an array or a string |
| 400 | `INVALID_CHAT_ID` | None of the `chatId`, `dialogId`, `CHAT_ID` fields was passed, the value is invalid, or `dialogId` was passed without the `chat` prefix. A body that cannot be parsed as JSON is treated as empty and also gets this code. `message` says where to get the chat ID |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not passed |
| 401 | `TOKEN_MISSING` | The key has no portal tokens. For an application key, the user session token was not passed |
| 403 | `SCOPE_DENIED` | The key lacks the `imbot` or `imopenlines` scope — both are required |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is in read-only mode |
| 403 | `BOT_ACCESS_DENIED` | The bot was registered by another key. To regain control, see [Restoring access to a bot](/docs/bots/ownership-recovery) |
| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 denied access to the chat |
| 404 | `BOT_NOT_FOUND` | No bot with this `botId` on the portal — register it via `POST /v1/bots` |
| 404 | `ENTITY_NOT_FOUND` | Bitrix24 reported that the record was not found |
| 409 | `BOT_ID_REPLACED` | The bot was registered again after the portal address changed. The new ID is in `error.details.botId` |
| 409 | `BOT_RECOVERY_IN_PROGRESS` | The bot is being restored automatically after the portal address changed. Retry after the pause from the `Retry-After` header |
| 410 | `BOT_DISABLED` | The bot is disabled. To bring the bot back, see [Bot disabled](/docs/bots/troubleshooting#bot-disabled-bot_disabled) |
| 422 | `BITRIX_ERROR` | Bitrix24 rejected the call. The Bitrix24 code is in `error.b24Code`, for example `BOT_ID_ERROR` |
| 429 | `RATE_LIMITED` | The shared platform ceiling of 30 requests per minute per portal was exceeded. The ceiling is shared by the four Open Channel bot actions and the `POST /v1/openlines/operator/answer` and `POST /v1/openlines/operator/finish` calls, and is split between platform replicas, so the code can arrive before the 30th request. The effective value is in the `x-ratelimit-limit` header, and the time until a retry is in `error.message`. A request rejected with `400` because of an error in the body also counts against the limit |
| 429 | `RATE_LIMITED` | Bitrix24 throttled requests to the portal. Retry after the pause from the `Retry-After` header |
| 429 | `QUEUE_OVERFLOW` | The request queue to the portal is full. Retry after the pause from the `Retry-After` header |
| 429 | `QUEUE_TIMEOUT` | The request did not get its turn in the portal queue and was not sent to Bitrix24. Retry after the pause from the `Retry-After` header |
| 502 | `OPENLINE_BOT_SESSION_FAILED` | Bitrix24 did not confirm the finish: the call result is not `true` |
| 502 | `BITRIX_UNAVAILABLE` | The Bitrix24 portal is unavailable |
| 503 | `BITRIX_TIMEOUT` | The Bitrix24 portal did not respond in time |
| 503 | `user_self_deletion_pending` | The key owner's account on the portal is pending deletion |

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

## Known specifics

**`finished: true` does not prove that a session existed.** A `200` response with `finished: true` also arrives when there is nothing to finish, for example for a nonexistent `chatId`. To make sure the session is closed, check the `status` and `dateClose` fields of the session in [`POST /v1/openlines/sessions/search`](/docs/openlines/sessions/search).

## See also

- [Open Channel bot](/docs/bots/openlines)
- [Hand to an operator](/docs/bots/openlines/operator)
- [Transfer a session](/docs/bots/openlines/transfer)
- [Session search](/docs/openlines/sessions/search)
- [Bot events](/docs/bots/events/bot-events)
