For AI agents: markdown of this page — /docs-content-en/cowork/deploy-key.md documentation index — /llms.txt
Project deployment key
POST /v1/cowork/deploy-key
A Cowork/Code key with the vibe:cowork scope can be used only for data access — chat and the Bitrix24 REST proxy — and cannot access the infrastructure control plane. Requests to create a server, deploy, execute commands, or manage its lifecycle all return 403 INFRA_FORBIDDEN_FOR_COWORK_KEY. This endpoint issues a separate project key with deployment rights: call it with the same Cowork/Code key, take the key field from the response — the body is flat, without a data wrapper — and use it as the X-Api-Key header for all operations under /v1/infra/*.
The returned key has the vibe:infra and vibe:storage scopes (without vibe:cowork), is valid for 7 days, and is bound to the same owner and Bitrix24 account as the Cowork/Code key. Each call issues a new key and revokes the previous project key — only one is active at a time.
Scope: vibe:cowork (the Cowork/Code key you call the endpoint with). The returned key is separate and has the vibe:infra + vibe:storage scopes.
Examples
curl
curl -X POST https://vibecode.bitrix24.com/v1/cowork/deploy-key \
-H "X-Api-Key: YOUR_COWORK_KEY"
JavaScript — get the key and deploy with it
// 1. Get the project key with the Cowork/Code key
const res = await fetch('https://vibecode.bitrix24.com/v1/cowork/deploy-key', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_COWORK_KEY' },
})
const deployKey = await res.json()
// 2. From here on, use the top-level key field for the infrastructure control plane
const deploy = await fetch('https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/deploy', {
method: 'POST',
headers: {
'X-Api-Key': deployKey.key, // NOT the Cowork/Code key
'Content-Type': 'application/json',
},
body: JSON.stringify({ /* ... */ }),
})
Response fields
| Field | Type | Description |
|---|---|---|
key |
string | The raw key. It is returned ONCE and cannot be recovered — save it. |
apiKeyId |
string | Identifier of the created key |
prefix |
string | Key prefix for display |
suffix |
string | Last characters of the key for identification |
scopes |
array | ["vibe:infra", "vibe:storage"] |
expiresAt |
string | Expiration (ISO 8601), 7 days from issuance |
howToUse |
string | A hint for the agent: how to use the key |
Response example
{
"key": "vibe_api_…",
"apiKeyId": "...",
"prefix": "vibe_api_…",
"suffix": "…xy3z",
"scopes": ["vibe:infra", "vibe:storage"],
"expiresAt": "2026-07-06T14:05:00.000Z",
"howToUse": "Use this key as the X-Api-Key header for all deploy / provision / exec / server-lifecycle calls under /v1/infra/*."
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 401 | MISSING_API_KEY |
The X-Api-Key header was not provided |
| 401 | INVALID_API_KEY |
Invalid API key |
| 402 | ACCOUNT_FROZEN |
The portal balance is exhausted — top it up |
| 403 | INSUFFICIENT_SCOPE |
The key lacks the vibe:cowork scope |
| 403 | COWORK_NOT_ACTIVATED |
No active Cowork/Code subscription for the user–portal pair |
| 403 | COWORK_HARNESS_KEY_FORBIDDEN |
The request used a third-party agent key issued for the subscription. Such a key cannot obtain a project deployment key — see Your own agent on the subscription |
| 409 | B24_USER_DELETED |
The Bitrix24 employee who owns the calling Cowork/Code key is no longer active on the Bitrix24 account — no key can be issued for them. This state is permanent: retrying will not help; the employee must be reactivated on the Bitrix24 account |
| 415 | FST_ERR_CTP_INVALID_MEDIA_TYPE |
The request body has a content type that this route does not parse. Send the request with no body, or with an empty body and the Content-Type: application/json header |
| 429 | RATE_LIMITED |
The per-portal, per-key-owner rate limit has been exceeded. The platform-wide limit is 3 requests every 5 minutes. The effective limit for your key is returned in the x-ratelimit-limit header. It is lower than the platform-wide limit because that limit is divided across replicas |
| 503 | COWORK_FEATURE_DISABLED |
Cowork/Code is disabled at the platform level |
| 503 | DEPLOY_KEY_DISABLED |
Self-service issuance of project keys is disabled at the platform level |
| 503 | INFRA_DISABLED |
Infrastructure is disabled at the platform level — the key would serve no purpose |
See Errors for the full list of common API errors.
Known specifics
The raw key (key) is returned only once, when it is issued. It cannot be recovered afterward. Each call issues a new key and revokes the previous project key, so call the endpoint once at the start of the deployment session and use the key you receive until the end.
Issuance moves everything that was bound to the previous keys onto the new key. Server ownership, the application card, live access tokens, and the visibility scope of running deployment operations are transferred in the same transaction that issues the key. Therefore, the server list, retrieving a specific server, publishing, and reading an operation's outcome all work under the new key immediately after the response, including for Galaxy container applications.
Bindings are transferred from more than just the currently active key. Issuance also transfers bindings from previously revoked project keys for the same owner and Bitrix24 account: up to five keys per call, starting with the most recent. If there are bindings on more keys, subsequent issuances transfer the rest; no separate action is required. Servers that disappeared from the list after earlier reissues therefore return after another key request, without manual action in your Vibecode account.
Exactly one application card moves per call. A key holds a single card slot, so if the owner–account pair has several cards, the first one takes the slot on the new key and the rest stay on their previous keys. The response does not indicate which card moved — check which card is visible under the new key.
Use the top-level key field from the response for deployment, NOT the Cowork/Code key. Continue using the Cowork/Code key for chat and Bitrix24 REST calls; use the project key for /v1/infra/*.
403 INFRA_FORBIDDEN_FOR_COWORK_KEY is returned for every write operation, not only for deployment. A Cowork/Code key cannot call any /v1/infra/* method except reads (GET). Outside infrastructure, it also cannot publish or unpublish an application or write to source storage. The restriction does not apply to reads, but a Cowork/Code key sees only resources it owns: issuance transfers server ownership to the project key, so the server list is empty and reading a specific server returns 404 NOT_FOUND. Source version history remains available to a Cowork/Code key because access there is determined per employee rather than per key. The Marketplace trial has two endpoints, and the restriction treats them differently. The Cowork/Code endpoint POST /v1/cowork/activate-market-trial requires the desktop key and never returns this code. Its twin, POST /v1/portals/:id/activate-market-trial, is blocked: an agent seat key receives this code, while a desktop key is rejected earlier with PURPOSE_KEY_FORBIDDEN.
The project key never appears in error.details.deployableKeys. The refusal includes error.details.requiredAction with the steps to take, while deployableKeys lists the owner's ordinary keys that can deploy — up to the five most recent, never the secret itself. The key issued by this endpoint has a special-purpose tag, and the filter selects only untagged keys, so an empty list does NOT mean that no project key can be issued. Keep using the project key you already have: another request issues a new one and revokes the previous one. The deployableKeys field is absent when the platform cannot resolve the key owner; this differs from an empty list.
A successful response (200) is the object itself, without a success wrapper. Errors arrive in the envelope { success: false, error: { code, message } }. Determine success by the HTTP status (res.ok).