
# Bot access recovery

A bot is bound to the key it was registered with, so another key does not see it in the list and cannot claim the same code. Access is restored by transferring ownership to a working key — the bot is not re-created, chats and message history are preserved.

## What a loss of access looks like

The symptoms appear all at once:

- `GET /v1/bots` returns success and an empty `bots` array, even though the bot is running on the Bitrix24 account.
- `POST /v1/bots` with the same `code` returns `409 BOT_ALREADY_EXISTS` — the code is taken.
- `GET /v1/bots/:botId` with the identifier from the `409` response returns `403 BOT_ACCESS_DENIED`.
- At the same time, `GET /v1/me` confirms that the key itself is valid: `accessMode` equals `READWRITE`, the `imbot` scope is present.

The bot list returned to a key that does not manage those bots:

```json
{
  "success": true,
  "data": {
    "bots": [],
    "users": [],
    "hasNextPage": false
  }
}
```

Repeated registration with the same code — the existing bot is returned in the `data` field:

```json
{
  "success": false,
  "error": {
    "code": "BOT_ALREADY_EXISTS",
    "message": "Bot with this code already exists"
  },
  "data": {
    "botId": 42,
    "code": "support_bot",
    "name": "Support"
  }
}
```

A request to this bot with the same key:

```json
{
  "success": false,
  "error": {
    "code": "BOT_ACCESS_DENIED",
    "message": "This bot belongs to a different API key"
  }
}
```

## Why the bot is not visible

A bot has two different bindings. Ownership is assigned to a Vibecode user and does not change when keys expire or are revoked. The binding to a key means something else — which key manages the bot right now.

`GET /v1/bots` returns records from the Vibecode database filtered by the calling key, so a bot registered with another key does not appear in the list. The other operations — events, messages and updates — are authorized the same way and return `403 BOT_ACCESS_DENIED`.

Bot code uniqueness is checked within the Bitrix24 account, not the key. Hence the discrepancy: the list is empty, and the code is taken.

The bot itself is not affected. It stays on the Bitrix24 account, remains in the same chats and keeps its message history — only managing it through the API is unavailable.

## How to restore access

Four steps. Calls to the bot are made with the key that ownership is transferred to. The transfer is available to the bot owner, that is, the Vibecode user who owns the owner key. A Bitrix24 account administrator can also perform the transfer.

### 1. Get the bot identifier

Repeat the registration with the same `code`. A `409` response means the code is taken: the identifier of the existing bot is returned in `data.botId`, and the bot record does not change. Registration is performed on behalf of a Bitrix24 account administrator — otherwise Bitrix24 denies access.

```bash
curl -X POST https://vibecode.bitrix24.com/v1/bots \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "support_bot", "name": "Support" }'
```

A `201` response instead of `409` means the registration went through idempotently. Ownership does not transfer in that case, the bot still does not appear in `GET /v1/bots`, and its `name`, `type`, `eventMode` and `webhookUrl` are updated with the values from the request. If the bot was working in `webhook` mode, send `eventMode` and `webhookUrl` together with `code` and `name` to preserve event delivery. The bot identifier in this response is returned in `data.botId` — go to step 2.

The procedure applies to bots registered through Vibecode. A bot created directly on a Bitrix24 account, bypassing the platform, has no record in the Vibecode database: the `data` field is not present in the `409` response, and the transfer returns `404 BOT_NOT_FOUND`.

### 2. Get the target key identifier

`targetApiKeyId` is the `id` field of the key record, not the key string. The list is returned by [`GET /v1/keys`](/docs/management-keys) to a management key with the `vibe:mgmt:keys` scope — a portal key cannot get this list, and the response is `401 WRONG_KEY_TYPE`. A management key is created in your dashboard, and a read-only key is enough for this step: the list is returned, while such a key cannot modify keys. After the transfer it can be revoked.

The response contains the keys of the management key owner on the specified Bitrix24 account. You recognize your own key by the `prefix` and `suffix` fields. The `portalId` value arrives in the `portal.id` field of the [`GET /v1/me`](/docs/keys-auth) response — that call needs no management scopes. The same identifier is returned by [`GET /v1/portals`](/docs/management-keys), but it carries its own `vibe:mgmt:portals` scope. A Bitrix24 account administrator who transfers a bot to another user's key gets that key identifier from its owner — other users' keys are not returned in the list.

```bash
curl -H "X-Api-Key: YOUR_MANAGEMENT_KEY" \
  "https://vibecode.bitrix24.com/v1/keys?portalId=PORTAL_ID"
```

### 3. Transfer ownership

```bash
curl -X POST https://vibecode.bitrix24.com/v1/bots/42/transfer \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "targetApiKeyId": "3f9a1c20-5e6b-4d18-9a77-0c2b8e4f1d33" }'
```

```json
{
  "success": true,
  "data": {
    "transferred": true,
    "botId": 42,
    "fromApiKeyId": "8c41d5e7-2b90-4a63-b1f5-6d7e9a0c4b12",
    "toApiKeyId": "3f9a1c20-5e6b-4d18-9a77-0c2b8e4f1d33"
  }
}
```

After this response the bot appears in `GET /v1/bots` for the new key.

### 4. Check the binding

The transfer changes the binding on the Vibecode side. A separate call checks the new key's access to the bot on the Bitrix24 account. It answers the owner key only, so this step is performed by the owner of the target key: a Bitrix24 account administrator who transferred the bot to another user's key gets `403 BOT_ACCESS_DENIED`.

```bash
curl -X POST https://vibecode.bitrix24.com/v1/bots/42/reauth \
  -H "X-Api-Key: YOUR_API_KEY"
```

```json
{
  "success": true,
  "data": {
    "validated": true,
    "refreshed": false
  }
}
```

`validated: true` confirms that the new key manages the bot on the Bitrix24 account — events, messages and updates work with it again.

## Target key requirements

A key is accepted when all conditions are met:

| Condition | Value |
|---------|----------|
| State | `ACTIVE` |
| Account | The same Bitrix24 account as the bot |
| Owner | The same Vibecode user who performs the transfer. A Bitrix24 account administrator transfers a bot to the key of any user of the same account — this path works from a personal `vibe_api_` key, and the role on the account is determined by it |
| Scope | `imbot` |
| Expiration | Not expired |
| Purpose | A general-purpose key. Service keys issued by the platform are not accepted: they have their own lifecycle, and after their rotation the bot is left unmanaged again |

The transfer does not check the target key's access mode — a read-only key is accepted. Managing the bot with such a key is still impossible: step 4 and every later call return `403 WRITE_BLOCKED_READONLY_KEY`. Transfer ownership to a key in `READWRITE` mode.

You can check the key before the call using its record from the `GET /v1/keys` call in step 2: the state is in the `status` field, the Bitrix24 account in `portalId`, the owner in `userId`, the scopes in `scopes`, the expiration in `expiresAt`, the access mode in `accessMode`.

A key that fails the check is rejected with `400 TARGET_KEY_INVALID`, and the cause is returned in the `reason` field — the causes are listed in the error table of the [Bot ownership transfer](/docs/bots/management/transfer) page.

## When this is needed

Three states lead to the same picture — the bot works, and the key does not see it.

**The owner key stopped working.** The key value was not saved at creation, the key was revoked, or its validity period ended. The bot binding is intact — access is restored by a transfer to a new key.

**The bot is registered with another key.** This happens when the application is deployed with one key while the bot was registered with another, or when the key was re-created together with the OAuth application. The transfer brings the bot and the working key back together.

**The bot belongs to a platform resource.** The bot of an AI agent or a managed bot is governed by that resource itself, so a direct transfer returns `409 BOT_TRANSFER_NOT_ALLOWED`. Such a bot is restored through its own resource — see [AI agents](/docs/agents).

## Errors

| HTTP | Code | When it is returned |
|------|-----|---------------------|
| 409 | `BOT_ALREADY_EXISTS` | The code is taken by a bot registered with another key. For a bot created through Vibecode, its identifier is returned in `data.botId` |
| 403 | `BOT_ACCESS_DENIED` | A request to the bot with a key that does not manage it |
| 401 | `WRONG_KEY_TYPE` | The key list is requested with a portal key — `GET /v1/keys` responds only to a management key |
| 403 | `NOT_BOT_OWNER` | The transfer is performed by someone other than the bot owner — the same Vibecode user that owns the owner key, or a portal admin, is required |
| 400 | `TARGET_KEY_INVALID` | The target key failed the check, the cause is in the `reason` field |
| 404 | `TARGET_KEY_NOT_FOUND` | There is no key with such `targetApiKeyId` |
| 409 | `BOT_TRANSFER_NOT_ALLOWED` | The bot belongs to an AI agent or another platform resource |
| 409 | `BOT_TRANSFER_CONFLICT` | Ownership was changed by a parallel request — re-read the current binding and repeat if needed |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | A write call was made with a read-only key: registration, transfer or binding check |
| 401 | `TOKEN_MISSING` | The `vibe_app_` authorization key is sent without the `Authorization: Bearer` header |
| 410 | `REAUTH_REQUIRED` | The check at step 4 did not confirm access: the key credentials are invalid and are not refreshed automatically. Authorize the key again through OAuth or create a new personal key |

The full code reference — [Error codes](/docs/errors).

## Known specifics

**The procedure is safe to repeat from the start.** A transfer to a key that already owns the bot does not change the binding. Checking the current state before a repeat is not needed.

**The previous key stops seeing the bot immediately.** After the transfer the bot disappears from the previous key's `GET /v1/bots` — its other bots stay in the list. If two processes were polling the bot, only the one working with the new key continues polling.

**Registering under a new code creates a different bot.** It has its own `botId`, its own chats and history, while the previous bot stays on the Bitrix24 account and continues to occupy its code.

## See also

- [Bot ownership transfer](/docs/bots/management/transfer)
- [Bot re-authorization](/docs/bots/management/reauth)
- [Bot list](/docs/bots/management/list)
- [Troubleshooting](/docs/bots/troubleshooting)
- [Management keys](/docs/management-keys)
