For AI agents: markdown of this page — /docs-content-en/management-keys/create.md documentation index — /llms.txt
Create an API key
POST /v1/keys
Creates a personal API key on the specified Bitrix24 account on behalf of the management key owner. Fields are passed flat at the root of the JSON body.
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldportalId |
Typestring | Requiredyes | DescriptionBitrix24 account ID. List: GET /v1/portals. The management key owner must be a member of this Bitrix24 account |
Fieldname |
Typestring | Requiredyes | DescriptionKey name, up to 255 characters. A whitespace-only string is not accepted |
Fieldscopes |
Typearray | Requiredyes | DescriptionScopes of the new key, at least one. Without exactScopes: true, four platform scopes are added to them — see below |
FieldexactScopes |
Typeboolean | Requiredno | Descriptiontrue — store exactly the listed scopes, without the four platform ones. Default false |
Fieldmode |
Typestring | Requiredno | DescriptionKey access mode: READWRITE or READONLY. Without the field, the new-key mode set on the Bitrix24 account applies |
FieldipWhitelist |
Typearray | Requiredno | DescriptionAllowed IP addresses. Without the field or with an empty array — no restriction |
FieldexpiresAt |
Typestring | null | Requiredno | DescriptionExpiration date (ISO 8601). Without the field or null — never expires |
FieldrateLimit |
Typenumber | null | Requiredno | DescriptionOnly null is accepted. A number from 1 to 100,000 is rejected with 403 RATE_LIMIT_ADMIN_ONLY, a number outside this range with 400 VALIDATION_ERROR |
Fieldbilling |
Typestring | Requiredno | DescriptionOnly wallet is accepted, which is also the default. Keys billed to the Cowork/Code subscription are issued in your Vibecode account — see Your own agent on the subscription |
Four platform scopes are added to the requested ones: vibe:infra, vibe:ai, vibe:search, vibe:storage. The key from the examples below gets crm, task and these four.
On a Bitrix24 account where the administrator has turned server management off, vibe:infra is dropped from this set without an error — the key is issued with the other three. The 403 INFRA_DISABLED_FOR_PORTAL refusal arrives only for a scope explicitly listed in scopes.
To get a key with exactly the listed scopes, pass exactScopes: true. The body {"portalId": "…", "name": "Storage only", "scopes": ["crm", "vibe:storage"], "exactScopes": true} issues a key with only crm and vibe:storage, and it answers POST /v1/infra/servers and AI calls with 403. The scopes of such a key are final: the platform does not widen them at request time, so GET /v1/me returns exactly what was stored at issue time.
The placement, entity and userfieldtype scopes are unavailable to a personal key and are not stored: the scopes of the created key in the response do not contain them, even when they were in the request alongside data scopes. The userfieldconfig scope is stored.
Examples
This endpoint accepts only a management key — see Limitations.
curl — management key
curl -X POST "https://vibecode.bitrix24.com/v1/keys" \
-H "X-Api-Key: YOUR_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{
"portalId": "0d9f7744-f853-47c7-b06e-6f61f9dd1b7f",
"name": "Deal export",
"scopes": ["crm", "task"]
}'
JavaScript — management key
const res = await fetch('https://vibecode.bitrix24.com/v1/keys', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_MANAGEMENT_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
portalId: '0d9f7744-f853-47c7-b06e-6f61f9dd1b7f',
name: 'Deal export',
scopes: ['crm', 'task'],
}),
})
const { success, data } = await res.json()
// The key value arrives only once — save it to a secrets store
const apiKey = data.rawKey
console.log('Key created:', data.id, data.scopes)
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata.id |
Typestring | DescriptionKey record ID. It is accepted by GET /v1/keys/:id, PATCH /v1/keys/:id, DELETE /v1/keys/:id and POST /v1/keys/:id/rotate |
Fielddata.name |
Typestring | DescriptionKey name |
Fielddata.type |
Typestring | DescriptionKey record type, always APP |
Fielddata.userId |
Typestring | DescriptionKey owner ID — the management key owner |
Fielddata.portalId |
Typestring | DescriptionBitrix24 account ID |
Fielddata.clientId |
Typestring | null | DescriptionOAuth client ID, if one is recorded on the key. Otherwise null |
Fielddata.scopes |
Typearray | DescriptionScopes stored on the key: the requested ones plus the added platform ones, without those unavailable to a personal key |
Fielddata.ipWhitelist |
Typearray | DescriptionAllowed IP addresses. An empty array — no restriction |
Fielddata.expiresAt |
Typestring | null | DescriptionExpiration date (ISO 8601), null — never expires |
Fielddata.rateLimit |
Typenumber | null | DescriptionIndividual request limit for AI endpoints, null — the platform-wide limit |
Fielddata.status |
Typestring | DescriptionKey status, ACTIVE for a new key |
Fielddata.lastUsedAt |
Typestring | null | DescriptionDate of the last request made with this key (ISO 8601), null for a new key |
Fielddata.createdAt |
Typestring | DescriptionCreation date (ISO 8601) |
Fielddata.updatedAt |
Typestring | DescriptionLast modification date (ISO 8601) |
Fielddata.accessMode |
Typestring | DescriptionREADWRITE or READONLY |
Fielddata.totalDefault |
Typeboolean | null | DescriptionWhether meta.total is returned in lists requested with this key. null — the platform setting applies |
Fielddata.issuedVia |
Typestring | null | DescriptionChannel 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, the key carries only vibe:* scopes |
Fielddata.rawKey |
Typestring | DescriptionFull key value. Arrives only in this response — save it immediately |
Response example
{
"success": true,
"data": {
"id": "3c1f6a52-8e4b-4d07-9a1e-5b2d7f0c6e91",
"name": "Deal export",
"type": "APP",
"userId": "fafa9780-eed7-4d29-b040-2448d924f452",
"portalId": "0d9f7744-f853-47c7-b06e-6f61f9dd1b7f",
"clientId": null,
"scopes": ["crm", "task", "vibe:infra", "vibe:ai", "vibe:search", "vibe:storage"],
"ipWhitelist": [],
"expiresAt": null,
"rateLimit": null,
"status": "ACTIVE",
"lastUsedAt": null,
"createdAt": "2026-10-29T12:23:14.701Z",
"updatedAt": "2026-10-29T12:23:14.701Z",
"accessMode": "READWRITE",
"totalDefault": null,
"issuedVia": "cloud-shared",
"rawKey": "vibe_api_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
Error response example
400 — portalId not provided:
{
"success": false,
"error": {
"code": "MISSING_PORTAL_ID",
"message": "Field portalId is required"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeMISSING_PORTAL_ID |
DescriptionportalId is not specified in the request body |
| HTTP400 | CodeVALIDATION_ERROR |
DescriptionThe body failed validation: no name or scopes, empty scopes, an unknown scope, an invalid IP address or date. The field and the reason are in error.message |
| HTTP400 | CodeINVALID_JSON_BODY |
DescriptionThe request body is invalid JSON |
| HTTP400 | CodeBILLING_MODE_NOT_SUPPORTED |
DescriptionThe body carries billing: "subscription" |
| HTTP400 | CodePERSONAL_KEY_WEBHOOK_SCOPES_INVALID |
Descriptionscopes contains no data scope. A personal key is issued as a Bitrix24 incoming webhook, while the placement, entity and userfieldtype scopes require an application context and are unavailable to a personal key. Add at least one data scope, for example crm or user_brief, or register an OAuth application for application features |
| HTTP400 | CodeINVALID_SCOPES |
DescriptionSome of the requested scopes are unavailable on the Bitrix24 account |
| HTTP400 | CodePORTAL_NOT_LINKED |
DescriptionThe Bitrix24 account is not connected to Bitrix24 Network — the key cannot be created |
| HTTP400 | CodeBOX_NO_DEVELOPER_KEY |
DescriptionThe Bitrix24 account is self-hosted, the owner has no developer key configured, and scopes contains Bitrix24 scopes |
| HTTP402 | CodeINT_TARIFF_REQUIRED |
DescriptionThe Bitrix24 account is on a free Bitrix24 plan |
| HTTP402 | CodeSELFHOSTED_NOT_AVAILABLE |
DescriptionThe Bitrix24 account is self-hosted, and self-hosted Bitrix24 is not yet served on this installation. Buying a plan does not clear the refusal — contact support |
| HTTP402 | CodeACCOUNT_FROZEN |
DescriptionThe account's billing account is frozen due to a negative balance |
| HTTP403 | CodeNOT_PORTAL_MEMBER |
DescriptionThe management key owner is not a member of the Bitrix24 account with the specified portalId |
| HTTP403 | CodePORTAL_ACCESS_BLOCKED |
DescriptionThe owner's access to the Bitrix24 account is disabled: their membership is inactive or forbidden by the account's access policy |
| HTTP403 | CodePORTAL_TARIFF_UNREADABLE |
DescriptionThe account plan could not be read, and the response does not name the missing plan: the error.details.requiredTariffs field is empty and the button leads to support. Buying a plan does not clear the refusal |
| HTTP403 | CodeKEY_CREATION_RESTRICTED |
DescriptionThe Bitrix24 account policy does not allow the owner to create keys. The right is granted by the account administrator — see Creation rights |
| HTTP403 | CodeKEY_POLICY_READONLY_REQUIRED |
DescriptionThe Bitrix24 account policy allows creating only READONLY keys, and mode requests READWRITE |
| HTTP403 | CodeRATE_LIMIT_ADMIN_ONLY |
DescriptionrateLimit carries a number. An individual limit cannot be set through this endpoint |
| HTTP403 | CodeINFRA_DISABLED_FOR_PORTAL |
Descriptionscopes explicitly requests vibe:infra, and the Bitrix24 account administrator has turned server management off. The key is not created. A request without this scope goes through on such an account as well |
| HTTP403 | CodeSCOPE_NOT_AVAILABLE_ON_PORTAL |
Descriptionscopes contains a scope that is not enabled on this Bitrix24 account. The list of such scopes is in error.message |
| HTTP403 | CodeKEY_STORAGE_SCOPE_REQUIRES_PERSONAL_KEY |
Descriptionscopes explicitly requests vibe:storage, and the management key is not confirmed as the owner's personal key. The refusal arrives with exactScopes: true as well. A management key created in your account does not get this refusal |
| HTTP403 | CodeINT_TARIFF_REQUIRED |
DescriptionThe account's Bitrix24 plan does not grant access, so the webhook is not issued. The response carries no upgrade link |
| HTTP403 | CodeB24_INSUFFICIENT_SCOPE |
DescriptionThe owner's developer key lacks rights on the account. Reconnect the account so the developer key is issued again |
| HTTP403 | CodeB24_ACCESS_DENIED |
DescriptionBitrix24 did not issue the webhook because of the employee's rights |
| HTTP403 | CodeCONNECTOR_KEY_ISSUE_FORBIDDEN |
DescriptionThe account forbids this employee from issuing keys. The right is granted by the account administrator — see Creation rights |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe management key is in read-only mode |
| HTTP403 | CodeMANAGEMENT_SCOPE_REQUIRED |
DescriptionThe management key does not carry the vibe:mgmt:keys scope |
| HTTP409 | CodeCONNECTOR_MODULE_NOT_INSTALLED |
DescriptionThe connector module is not installed on the account, so a key cannot be issued through it. Retrying without installing the module will not help |
| HTTP410 | CodeSTALE_DEVELOPER_KEY |
DescriptionThe owner's developer key is invalid and is not re-issued automatically. Reconnect the account |
| HTTP502 | CodeCONNECTOR_PLAN_REQUIRED |
DescriptionThe Bitrix24 account plan does not include Vibecode, and there is nothing to offer — a self-hosted account, an account already on a paid plan, an unrecognized region. The human-readable reason is in error.userMessage. Retrying will not help until the plan changes |
| HTTP502 | CodeCONNECTOR_REST_UNAVAILABLE |
DescriptionThe account's plan or trial period is active, but Bitrix24 refused the issuance. The original reason is in error.details.reason, the state is transient |
| HTTP502 | CodeCONNECTOR_KEY_ISSUE_FAILED |
DescriptionAny other refusal from the connector module, or its transport is unavailable. The original reason is in error.details.reason |
| HTTP502 | CodeCONNECTOR_KEY_ISSUE_RESPONSE_LOST |
DescriptionThe connector module's response was lost, and the webhook may already exist on the Bitrix24 account. Do not retry the issuance right away |
| HTTP502 | CodeRECOVERY_FAILED |
DescriptionRe-issuing the developer key failed, the state is transient — retry the request |
| HTTP502 | CodeDEVKEY_MINT_FAILED |
DescriptionAny other issuance failure through the developer key. Diagnostics are in error.details.b24Code and error.details.b24Status |
| HTTP502 | CodeBITRIX_UNAVAILABLE |
DescriptionBitrix24 did not register the incoming webhook: it did not respond or refused without a stated reason. In the second case the response carries error.details.incidentCode — a six-character support reference that support uses to find the log entry |
| HTTP503 | CodeNETWORK_DEVKEY_REQUIRED |
DescriptionThe owner's developer key has not been issued yet, and on this Bitrix24 account issuance goes only through it. The human-readable text is in error.userMessage |
| HTTP503 | CodeCONNECTOR_KEY_ISSUE_TIMEOUT |
DescriptionThe connector module did not respond in time, and the webhook may already exist on the Bitrix24 account. Do not retry the issuance right away |
| HTTP401 | CodeWRONG_KEY_TYPE |
DescriptionThe 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 |
| HTTP401 | CodeKEY_INACTIVE |
DescriptionThe management key is revoked or blocked |
| HTTP401 | CodeKEY_EXPIRED |
DescriptionThe management key has expired |
| HTTP401 | CodeINVALID_API_KEY |
DescriptionNo key with the provided value was found |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
The OWNER_DELETED, OWNER_BLOCKED, ACCOUNT_PENDING_ERASURE and B24_USER_DELETED refusals depend on the key owner's account — see Owner account state.
Two platform access checks. The first is the Bitrix24 account access check. A commercial Bitrix24 plan grants full access, a demo plan grants a trial, and an account on a free plan gets 402 INT_TARIFF_REQUIRED. A self-hosted Bitrix24 account where self-hosted Bitrix24 is not yet served gets 402 SELFHOSTED_NOT_AVAILABLE. One more outcome of the same check comes with status 403 and means the platform has nothing to name: PORTAL_TARIFF_UNREADABLE. This check applies only to issuing a new key: rotation, automatic key recovery and ownership handover are not subject to it, and already issued keys keep working.
The second check runs later, and its reach is wider: Bitrix24 itself refuses the issuance because the account plan does not include Vibecode. It fires on everything that issues a key — creation, rotation, automatic key recovery and ownership handover. Where access can be purchased, the response is 402 INT_VIBE_PLUS_REQUIRED. Where there is nothing to offer — 502 CONNECTOR_PLAN_REQUIRED. Retrying a request with either code will not help until the Bitrix24 plan changes.
Refusals shared with rotation. The issuance refusals themselves also arrive on rotation — which ones exactly is listed in Rotate an API key. The body of an issuance refusal may carry an error.reason field with the exact cause in the platform's internal classification, while error.code stays the same. Branch on error.code, not on the message text.
Full list of common API errors — Errors.