## Update an API key

`PATCH /v1/keys/:id`

Changes the settings of an API key owned by the management key owner. The body is flat, without a `fields` wrapper: pass only the fields that change.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|----------|
| `id` (path) | string | yes | Key record ID. List: [`GET /v1/keys`](/docs/management-keys/list) |

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `name` | string | no | Key name, from 1 to 255 characters. A whitespace-only name is not accepted |
| `scopes` | string[] | no | New full list of the key's [scopes](/docs/scopes), at least one. The scope set is checked the same way as on [creation](/docs/management-keys/create). The `vibe:storage` scope is added only to a personal key. For an application key or a key of unknown origin it can be re-sent unchanged or removed |
| `status` | string | no | `ACTIVE` — return the key to service, `REVOKED` — revoke it |
| `mode` | string | no | Key access mode: `READWRITE` or `READONLY`. Details — [Access mode](/docs/keys-auth/access-mode). Switching to `READWRITE` is forbidden if the Bitrix24 account policy requires `READONLY` |
| `ipWhitelist` | string[] | no | Allowed IP addresses. An empty array removes the restriction |
| `expiresAt` | string \| null | no | Expiration date in ISO 8601 format. `null` — the key never expires |
| `rateLimit` | number \| null | no | Individual request limit for AI endpoints. Only the key's current value is accepted: a change returns `403 RATE_LIMIT_ADMIN_ONLY` |
| `totalDefault` | boolean \| null | no | Whether `meta.total` is returned in lists requested with this key. `null` — the platform setting applies |

## Examples

The request accepts only a management key — see [Limitations](/docs/management-keys#limitations).

### curl — management key

```bash
curl -X PATCH "https://vibecode.bitrix24.com/v1/keys/6dbad0ce-79a9-43f5-8ca4-3e1af7ef63bc" \
  -H "X-Api-Key: YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CRM and tasks integration"
  }'
```

### JavaScript — management key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/keys/6dbad0ce-79a9-43f5-8ca4-3e1af7ef63bc', {
  method: 'PATCH',
  headers: {
    'X-Api-Key': 'YOUR_MANAGEMENT_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'CRM and tasks integration',
  }),
})

const { success, data } = await res.json()
console.log('Key:', data.name, '—', data.status)
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | Always `true` on success |
| `data.id` | string | Key record ID |
| `data.name` | string | Key name |
| `data.prefix` | string | First characters of the key value |
| `data.suffix` | string | Last four characters of the key value |
| `data.type` | string | Key record type, always `APP` |
| `data.userId` | string | Key owner ID |
| `data.portalId` | string | Bitrix24 account ID |
| `data.clientId` | string \| null | OAuth client ID, if one is recorded on the key. Otherwise `null` |
| `data.scopes` | array | Key [scopes](/docs/scopes) after the change |
| `data.ipWhitelist` | array | Allowed IP addresses. An empty array — no restriction |
| `data.expiresAt` | string \| null | Expiration date (ISO 8601), `null` — never expires |
| `data.rateLimit` | number \| null | Individual request limit for AI endpoints, `null` — the platform-wide limit |
| `data.status` | string | `ACTIVE`, `REVOKED`, `EXPIRED` or `BLOCKED` |
| `data.lastUsedAt` | string \| null | Date of the last request made with this key (ISO 8601) |
| `data.createdAt` | string | Creation date (ISO 8601) |
| `data.updatedAt` | string | Last modification date (ISO 8601) |
| `data.accessMode` | string | `READWRITE` or `READONLY` |
| `data.totalDefault` | boolean \| null | Whether `meta.total` is returned in lists requested with this key. `null` — the platform setting applies |
| `data.issuedVia` | string \| null | Channel through which the key's webhook was issued: `per-portal` and `cloud-shared` — the connector module on the Bitrix24 account, `dev_key` — the owner's developer key, `legacy` — registration via Bitrix24 Network, `none` — no webhook was created. `null` if the channel is not recorded |

The response has no `b24Ready` field. To get it, call [`GET /v1/keys/:id`](/docs/management-keys/get).

## Response example

```json
{
  "success": true,
  "data": {
    "id": "6dbad0ce-79a9-43f5-8ca4-3e1af7ef63bc",
    "name": "CRM and tasks integration",
    "prefix": "vibe_api_XXXXXXXXX",
    "suffix": "XXXX",
    "type": "APP",
    "userId": "fafa9780-eed7-4d29-b040-2448d924f452",
    "portalId": "0d9f7744-f853-47c7-b06e-6f61f9dd1b7f",
    "clientId": null,
    "scopes": ["crm", "task", "tasks", "im"],
    "ipWhitelist": [],
    "expiresAt": null,
    "rateLimit": null,
    "status": "ACTIVE",
    "lastUsedAt": "2026-10-28T13:11:06.013Z",
    "createdAt": "2026-05-18T10:22:10.950Z",
    "updatedAt": "2026-10-29T12:16:49.962Z",
    "accessMode": "READWRITE",
    "totalDefault": null,
    "issuedVia": null
  }
}
```

## Error response example

403 — a Bitrix24 scope is being added to an application authorization key:

```json
{
  "success": false,
  "error": {
    "code": "OAUTH_SCOPE_CHANGE_REQUIRES_REISSUE",
    "message": "An OAuth app's permissions can't be changed on an existing key — they're fixed when the key is issued. Create a new authorization key with the scopes you need."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | A body field failed validation: a whitespace-only name or one longer than 255 characters, an unknown `status`, `mode` or scope value, an empty `scopes` list, an invalid IP address, `rateLimit` outside the range from 1 to 100,000 |
| 400 | `INVALID_JSON_BODY` | The request body is invalid JSON |
| 400 | `PERSONAL_KEY_WEBHOOK_SCOPES_INVALID` | The new `scopes` list contains no data scope: only `placement`, `entity` and `userfieldtype` are left. The check runs before the Bitrix24 account is contacted |
| 400 | `PERSONAL_KEY_WEBHOOK_SCOPES_INVALID` | The Bitrix24 account refused to store all Bitrix24 scopes from the new list on the key's webhook. The key's scopes do not change |
| 400 | `INVALID_SCOPES` | Some of the new scopes are unavailable on the Bitrix24 account. The key's scopes do not change |
| 400 | `BOX_NO_DEVELOPER_KEY` | Bitrix24 scopes are changed on a Bitrix24 account where they are checked on the Bitrix24 side, and the key owner has no developer key. The key's scopes do not change |
| 402 | `ACCOUNT_FROZEN` | The account balance is frozen. A request whose body is only `{"status": "REVOKED"}` goes through on a frozen account as well |
| 403 | `KEY_BLOCKED` | The key is blocked (`status: BLOCKED`) and cannot be changed. It can be replaced only by [rotation](/docs/management-keys/rotate) |
| 403 | `RATE_LIMIT_ADMIN_ONLY` | The request changes `rateLimit`. An individual limit cannot be changed through this endpoint |
| 403 | `KEY_POLICY_READONLY_REQUIRED` | The request switches the key to `READWRITE`, and the Bitrix24 account policy requires `READONLY` for keys. An exception for an individual key is granted by the Bitrix24 account administrator |
| 403 | `OAUTH_SCOPE_CHANGE_REQUIRES_REISSUE` | A Bitrix24 scope is being added to an application authorization key (`vibe_app_`). The scopes of such a key are fixed at issue time — create a new authorization key with the required set. Removing scopes goes through |
| 403 | `KEY_STORAGE_SCOPE_REQUIRES_PERSONAL_KEY` | The new list adds `vibe:storage` to an application key or a key of unknown origin. Create a new personal key with storage access |
| 403 | `INFRA_DISABLED_FOR_PORTAL` | The new list adds the `vibe:infra` scope, which the key did not carry, and the Bitrix24 account administrator has turned server management off. The key's scopes do not change. Editing a key that already carries this scope goes through on such an account as well, and removing the scope is always allowed |
| 403 | `SCOPE_NOT_AVAILABLE_ON_PORTAL` | The new list adds a scope that is not granted on this Bitrix24 account. The message names such scopes |
| 403 | `SYSTEM_KEY_REACTIVATE_FORBIDDEN` | The request switches to `ACTIVE`, or extends the expiry of, a key that the platform issues through its own endpoint: a Cowork/Code desktop app key, an agent key, a project deploy key. The response message says where to reissue this key |
| 403 | `COWORK_PLATFORM_DISABLED` | A key billed to the Cowork/Code subscription is being switched to `ACTIVE` or extended, and Cowork/Code is disabled at the platform level |
| 403 | `COWORK_ACCESS_REQUIRED` | The same for a subscription key: the key owner has no access to Cowork/Code |
| 403 | `COWORK_EXTERNAL_CLIENTS_DISABLED` | The same for a subscription key: the Bitrix24 account administrator has forbidden third-party clients |
| 403 | `COWORK_SUBSCRIPTION_INACTIVE` | The same for a subscription key: the Cowork/Code subscription is suspended or cancelled |
| 403 | `COWORK_SEAT_KEY_MODE_CABINET_ONLY` | The request changes `mode` on a Cowork/Code desktop app key. This is the mode of the whole seat. Change it in the Vibecode dashboard, which shows what else narrows along with it |
| 403 | `COWORK_KEY_MODE_ABOVE_SEAT` | The request raises `mode` on a third-party agent key billed to the Cowork/Code subscription above the seat mode. Widen the seat first; within its limits the edit goes through. The same code is returned if the seat was narrowed while the request was running |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The management key that sent the request works in `READONLY` mode |
| 403 | `MANAGEMENT_SCOPE_REQUIRED` | The management key does not carry the `vibe:mgmt:keys` scope |
| 404 | `KEY_NOT_FOUND` | There is no key with this `id`, it belongs to another user, or it is a management key |
| 409 | `REISSUE_IN_PROGRESS` | Authorization key (`vibe_app_`) only: the request changes `mode`, `status` or `expiresAt`, and another operation is already running on this application's key — a rotation, an update or a deletion. The key is not changed; retry the request once that operation finishes |
| 409 | `KEY_NOT_ACTIVE` | Authorization key (`vibe_app_`) only: the key is no longer active or has changed since the request started — for example, it was revoked or deleted. Changing `mode` on a revoked authorization key also returns this code. The key is not changed. Re-read it with [`GET /v1/keys/:id`](/docs/management-keys/get) |
| 409 | `KEY_MANAGES_FOREIGN_SERVER` | Revoking a key that manages a live server of another owner, a server without an owner, or a server of the same owner on another Bitrix24 account. Identify the server's owner and its Bitrix24 account, then rebind the server to a key of that owner on the same Bitrix24 account and retry the revocation |
| 409 | `KEY_OPERATION_IN_PROGRESS` | A transfer, revocation or concurrent scope edit of the key has not finished yet. Re-read the key and retry the edit against its current scope set |
| 409 | `PORTAL_ADDRESS_CHANGED` | A self-hosted Bitrix24 portal has moved to a new address, while the key's webhook is issued for the previous one. No request is sent to the Bitrix24 account, and the key's scopes change neither on the Vibecode platform nor in Bitrix24. Reconnect the key and repeat the edit — the steps are in [Authorization, keys and permissions](/docs/errors/auth#portal_address_changed-409) |
| 410 | `STALE_DEVELOPER_KEY` | The owner's developer key is invalid and is not re-issued automatically. The key's scopes do not change. Reconnect the account |
| 502 | `RECOVERY_FAILED` | Reissuing the developer key failed. The failure is temporary — retry the request |
| 502 | `DEVKEY_SCOPE_SYNC_FAILED` | Bitrix24 did not accept the new scopes of the key's webhook. Diagnostics are in `error.details`. The key's scopes do not change |
| 502 | `BITRIX_UNAVAILABLE` | The key status change could not be passed to Bitrix24 |
| 401 | `WRONG_KEY_TYPE` | The request was sent with a Bitrix24 account key — a personal `vibe_api_` key or an authorization key `vibe_app_`. The endpoint accepts only a management key |
| 401 | `KEY_INACTIVE` | The management key is revoked or blocked |
| 401 | `KEY_EXPIRED` | The management key has expired |
| 401 | `INVALID_API_KEY` | No key with the provided value was found |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |

The `OWNER_DELETED`, `OWNER_BLOCKED` and `ACCOUNT_PENDING_ERASURE` refusals depend on the key owner's account — see [Owner account state](/docs/management-keys#owner-account-state).

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

## Known specifics

**The access mode is changed with the `mode` field.** The `accessMode` field from the response is not accepted in the request body: a request with it returns `200`, and the key mode does not change.

**A value equal to the current one is not a change.** A client may send the whole key record to rename it: the same `mode`, the same `rateLimit` and the same `scopes` set go through without the checks that run when these fields change.

**Scopes and status change in Bitrix24 as well.** If the key's scopes are checked on the Bitrix24 side, the new set is first passed to the key's webhook and only then stored in Vibecode. If the Bitrix24 account refuses, the key keeps its previous scopes. On revocation the platform deletes the key's webhook in Bitrix24 or disables its credentials.

**Revocation cancels the access tokens issued by the key.** Together with the switch to `REVOKED`, the server [access tokens](/docs/infra/access-tokens) issued by this key are revoked.

**Platform-issued keys are checked only when returned to service or extended.** Shortening the expiry, revoking and editing other fields of such keys work without the issuance checks. Ordinary dashboard keys are not affected by these checks.

**The mode of Cowork/Code keys lives on the seat.** A seat is a pair of an employee and a Bitrix24 account, shared by all of the employee's devices. So the `mode` of a desktop app key cannot be changed here, and on a third-party agent key billed to the subscription it is capped by the seat mode.

## See also

- [List Bitrix24 account API keys](/docs/management-keys/list)
- [Create an API key](/docs/management-keys/create)
- [Get an API key](/docs/management-keys/get)
- [Delete an API key](/docs/management-keys/delete)
- [Rotate an API key](/docs/management-keys/rotate)
- [Access mode](/docs/keys-auth/access-mode)
- [Scopes](/docs/scopes)
- [Management keys](/docs/management-keys)
