For AI agents: markdown of this page — /docs-content-en/cowork/applications-create.md documentation index — /llms.txt

Create an application from Cowork/Code

POST /v1/cowork/applications

Creates a personal application and issues its key, which is returned exactly once. The endpoint does not create a server: a personal application has none by definition. Your deployment creates the server, which is then linked to the card automatically. The Idempotency-Key header is required.

Scope: vibe:cowork (Cowork/Code key) | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key

Take the request field values from the application creation parameters. The same endpoint also returns the scope presets and the access mode that the Bitrix24 account assigns to new keys.

Parameters

Parameter Type Req. Description
Idempotency-Key (header) string yes A string of 1 to 255 characters from the set [A-Za-z0-9_.:-]. It is scoped to the calling key, so two different clients may send the same string. It does not expire and remains valid for as long as the application exists. See Idempotency for details

Request fields (body)

Field Type Req. Description
name string yes Application name, 2 to 100 characters. Control characters are not allowed. Leading and trailing whitespace is removed before the length is measured, so a request with a one-character name returns 400 even if the name is surrounded by spaces
type string yes Application type. The only supported value is personal. The schema accepts external, but the endpoint returns 400 APP_TYPE_NOT_AVAILABLE
b24Scopes array yes Bitrix24 scopes for the key being issued. The array must not be empty; there is no default. Take the values from the scopePresets set in the creation parameters
mode string no Key access mode: READONLY or READWRITE. If omitted, the account's default mode is used; the same value is returned in the mode field of the creation parameters. If the account assigns read-only access to new keys, a request with READWRITE returns 403 — the account policy overrides the request
expiresInDays number | null no Key lifetime in days, as an integer of 1 or greater. If omitted or set to null, the key is issued with no expiry. The expiry policy from the creation parameters does not apply automatically; see "Known specifics"

The schema is strict: an extra field in the body returns 400 VALIDATION_ERROR, and the response names the field. The body size is limited to 64 KB.

Examples

The endpoint accepts only a Cowork/Code key, so only two examples are provided. A request made with a key that lacks the vibe:cowork scope receives 403 INSUFFICIENT_SCOPE.

curl — Cowork/Code key

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/cowork/applications \
  -H "X-Api-Key: YOUR_COWORK_KEY" \
  -H "Idempotency-Key: create-app-2026-08-25-01" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Deal report",
    "type": "personal",
    "b24Scopes": ["crm"]
  }'

JavaScript — Cowork/Code key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/cowork/applications', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_COWORK_KEY',
    'Idempotency-Key': 'create-app-2026-08-25-01',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Deal report',
    type: 'personal',
    b24Scopes: ['crm'],
  }),
})

if (!res.ok) {
  const { error } = await res.json()
  throw new Error(`${res.status} ${error.code}`)
}

const { data } = await res.json()

// The raw key is returned only once — save it immediately
if (data.rawApiKey === null) {
  // This is a retry: the application already exists, so the key is not issued again
} else {
  saveKey(data.rawApiKey, data.keyExpiresAt)
}

Response fields

Field Type Description
success boolean Always true on success
data.application object Application card in the same shape returned by GET /v1/applications/:id. The fields populated immediately after creation are listed below. See the card page for the full list
data.application.id string Application identifier
data.application.name string The name you passed
data.application.type string PERSONAL for an application created by this endpoint
data.application.server object | null null in the initial response because a personal application has no server yet. On a retry, the field reflects the state AT THE MOMENT OF THE RETRY, so it contains a server object if the application has since been deployed
data.application.openUrl string | null null in the initial response because there is nothing to open yet. On a retry, it contains the current application URL if one has already been issued
data.applicationId string Repeats application.id. Returned separately so you can link your local record to the card without parsing the card itself
data.rawApiKey string | null Raw application key. It is returned ONCE and cannot be recovered. The format is vibe_api_, followed by 32 Latin letters and digits, _, and 6 lowercase hexadecimal characters, for a total of 48 characters. null on a retry
data.keyExpiresAt string | null Key expiry, ISO 8601. null means the key has no expiry. On a retry, the field is ABSENT rather than empty
data.mode string Access mode of the issued key — READONLY or READWRITE. On a retry the field is ABSENT
data.warnings array Human-readable warning messages. Empty when there are none
data.warningCodes array Warning codes. Contains KEY_NOT_REPLAYABLE on a retry. Both warnings and warningCodes are always present, even when empty, so the response shape is the same in every case

Response example

JSON
{
  "success": true,
  "data": {
    "application": {
      "id": "cmt8ht5u40005ensk4fp45ebx",
      "name": "Deal report",
      "description": null,
      "type": "PERSONAL",
      "iconUrl": null,
      "createdAt": "2026-08-25T09:59:01.324Z",
      "updatedAt": "2026-08-25T09:59:01.324Z",
      "viewerState": "owner",
      "pinned": false,
      "author": { "name": "Application author" },
      "isEmbedded": false,
      "openUrl": null,
      "openTarget": null,
      "server": null,
      "sources": { "hasVersions": false, "latestVersionId": null, "latestSavedAt": null },
      "activeOperation": null
    },
    "applicationId": "cmt8ht5u40005ensk4fp45ebx",
    "rawApiKey": "vibe_api_ge5crx6rXOgoFikYi7G2inWA6dx7VO1V_9bcf92",
    "keyExpiresAt": null,
    "mode": "READWRITE",
    "warnings": [],
    "warningCodes": []
  }
}

Error response example

409 — the key quota is exhausted:

JSON
{
  "success": false,
  "error": {
    "code": "KEY_LIMIT_REACHED",
    "message": "Maximum number of API keys reached",
    "details": { "used": 1, "limit": 1, "requested": 1 }
  }
}

Deleting the issued key in your Vibecode account does NOT cancel idempotency: the application remains, and a retry with the same idempotency key still returns 201 with the Idempotent-Replayed: true header and warningCodes: ["KEY_NOT_REPLAYABLE"]. That retry does not issue a new key — the raw key is returned exactly once, during initial creation. To get a working key for an existing application, use POST /v1/keys/:id/rotate.

Errors

The endpoint-specific error list is exhaustive: the endpoint does not return codes that are not listed here. Key issuance goes through Bitrix24 Network, whose errors are propagated verbatim and are also included in the table. For a self-hosted Bitrix24 account, key issuance uses a separate channel and can return its own codes, covered in Keys and authorization. The response shape is the same; branch on error.code.

HTTP Code Description
400 IDEMPOTENCY_KEY_REQUIRED The Idempotency-Key header is missing
400 INVALID_IDEMPOTENCY_KEY The header is present but does not meet the length or character-set requirements
400 VALIDATION_ERROR The request body fails validation because of the length of name, control characters in name, an unknown mode value, expiresInDays below one, an empty b24Scopes, or an extra field. The message names the field
400 APP_TYPE_NOT_AVAILABLE The request contains type: "external", which is unavailable in this version
400 INVALID_SCOPES b24Scopes contains a scope that is not in the Bitrix24 catalog. The message lists the rejected values
400 PORTAL_NOT_LINKED The Bitrix24 account is not connected to Bitrix24 Network, so no channel is available for issuing the key
400 PERSONAL_KEY_WEBHOOK_SCOPES_INVALID None of the scopes left in b24Scopes can be bound to the account. Returned when ONLY the placement, entity, or userfieldtype scopes are provided, because a personal key does not support them. Add at least one data-access scope, such as crm
401 MISSING_API_KEY The X-Api-Key header is missing
401 INVALID_API_KEY The key was not found or has been revoked
401 KEY_INACTIVE The key is disabled
401 KEY_EXPIRED The calling key has expired
402 ACCOUNT_FROZEN The account balance is exhausted — top it up
402 INT_TARIFF_REQUIRED The portal is on a free Bitrix24 plan — creating an application requires a commercial plan, and a trial plan grants limited access. For accounts where access is restricted to Vibe+ plans, key issuance requires a Vibe+ plan, and an account on an ordinary commercial plan receives INT_VIBE_PLUS_REQUIRED. The response body includes the upgrade URL. Retrying without changing the account state returns the same response
403 INSUFFICIENT_SCOPE The key lacks the vibe:cowork scope
403 COWORK_HARNESS_KEY_FORBIDDEN The call was made with a third-party agent key issued for the subscription. Such a key cannot create applications — see Your own agent on the subscription
403 COWORK_NOT_ACTIVATED No active Cowork/Code subscription for the user and portal
403 WRITE_BLOCKED_READONLY_KEY The calling Cowork/Code key was issued in read-only mode, but creating an application is a write operation. This error is returned before the remaining checks
403 APP_CREATION_RESTRICTED The account policy restricts who can create applications, and the key owner is not allowed to do so. See Rights to create keys and apps
403 KEY_POLICY_READONLY_REQUIRED The account assigns read-only access to new keys, but the request body contains mode: "READWRITE". The refusal is unconditional because this key has no administrative override
409 KEY_LIMIT_REACHED The key quota is exhausted. error.details contains used, limit, and requested
409 IDEMPOTENCY_KEY_BODY_MISMATCH The same Idempotency-Key was used with a different request body
409 IDEMPOTENCY_KEY_ALREADY_USED The idempotency key has been consumed: it belongs to an application that has since been deleted, OR the attempt reached Bitrix24 and failed there. In the second case, the key deliberately remains claimed because a retry could issue a second key in addition to the first. This state is permanent; use a new idempotency key
409 IDEMPOTENCY_CONCURRENT_RETRY A concurrent request with the same idempotency key is still running. This is the only idempotency error for which a retry makes sense. The idempotency key is claimed BEFORE the application key is issued, so this error is returned before any key exists: no second application or key is created, no matter how many requests are sent concurrently
415 FST_ERR_CTP_INVALID_MEDIA_TYPE The request uses a content type that this route does not parse. Send Content-Type: application/json
429 RATE_LIMITED The rate limit for the combination of Bitrix24 account and key owner has been exceeded. The platform-wide limit is 6 requests per minute. The limit currently in force 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
429 QUOTA_EXCEEDED The daily free-call quota is exhausted while the prepaid balance is zero
413 PAYLOAD_TOO_LARGE The request body is larger than 64 KiB. For example, an unusually long b24Scopes can reach this size. The limit is checked before the body is parsed, so neither the claim nor the key is created
500 APPLICATION_CREATE_FAILED A write failed. TWO outcomes are possible, and the response cannot distinguish them: either the key was issued but the application card could not be written, or the claim itself failed and nothing was created. In the first case, an extra key appears in your Vibecode account; revoke it. In both cases, retry with a NEW idempotency key. Reusing the old one may return 409 IDEMPOTENCY_KEY_ALREADY_USED
502 BITRIX_UNAVAILABLE Bitrix24 Network rejected the call or was unavailable while the key was being issued. Neither the application nor the key was created, but the idempotency key is SPENT: the error is returned after Bitrix24 has already been called, so the claim deliberately remains in place. Otherwise, a retry could issue a second key in addition to the first. Retry with a NEW idempotency key; reusing the old one deterministically returns 409 IDEMPOTENCY_KEY_ALREADY_USED. This code also covers a terminal case: the key owner's authorization in Bitrix24 Network has expired, and only the owner can resolve it by signing in to Bitrix24 Network again. The response does not distinguish the two cases and provides no separate field. Make ONE retry with a new idempotency key. If the same error occurs again, stop and tell the user that the key owner must sign in again
503 COWORK_FEATURE_DISABLED Cowork/Code is disabled at the platform level
503 APP_CREATE_DISABLED Creating applications from Cowork/Code is disabled. The available field of the creation parameters reports this in advance

See Errors for the full list of common API errors.

Idempotency

Unlike creating a server, this endpoint requires the Idempotency-Key header. It issues a key and consumes a quota slot, so without idempotency, retrying after a network interruption could create a second application and a second key.

A retry with the same key and request body returns 201, adds the Idempotent-Replayed: true response header, and returns the same card. The raw key is then null, and KEY_NOT_REPLAYABLE appears in warningCodes: the platform stores only the key hash, so the raw key cannot be recovered.

A lost key is not returned on a retry, and this Cowork/Code key cannot reissue it — the response contains no identifier for the issued key, and the /v1/keys section accepts only a management key. The only practical option is to create the application again with a NEW Idempotency-Key value, obtain a fresh key, and then remove the extra card and its key from your Vibecode account. Save rawApiKey immediately in the same response handler.

The fingerprint is calculated from a canonicalized request body. The order of fields and the order of values in b24Scopes do not affect the comparison, so reordering either still counts as the same request. Leading and trailing whitespace in name also has no effect, and expiresInDays: null is equivalent to omitting the field. Using the same key with a different body returns 409 IDEMPOTENCY_KEY_BODY_MISMATCH instead of a result for a different request.

Repeat the same request body without modifying it. Omitting an optional field and explicitly providing the value that the account would supply produce DIFFERENT fingerprints. For example, if the first request omitted mode and the retry includes it, the response is 409 IDEMPOTENCY_KEY_BODY_MISMATCH. For the same reason, ["crm"] and ["crm", "crm"] differ: the scopes are sorted before comparison, but duplicates are not removed.

Known specifics

The default key lifetime does not apply — the keyExpiresInDays field in the creation parameters is a hint, not a default. If expiresInDays is omitted, the key is issued with no expiry, and the response contains keyExpiresAt: null. To limit the lifetime, pass the number of days explicitly. You can present the value from the creation parameters as a suggestion to the user.

The placement, entity, and userfieldtype scopes are not included in the issued key. In a mixed set, they are dropped without an error because a personal key does not support them. An error is returned only when b24Scopes contains no other scopes. Check the scopes on the issued key rather than relying on the request you sent.

The issued key cannot call AI or web search. It carries vibe:infra, vibe:storage, and the requested Bitrix24 scopes, while vibe:ai and vibe:search are absent from both the scope string and the runtime scopes. An application created this way cannot spend the account wallet on AI models or web search.

The order of errors matters: first the calling key's permissions, then the product state, then the cost. The checks run in this order: the key's existence, expiry, read-only mode, and account balance freeze; the vibe:cowork scope and key class, whether Cowork/Code is enabled, whether the subscription is active, and whether the application creation wizard is enabled; idempotency and the request body schema; and finally the account's platform access, application creation policy, and key quota. When multiple conditions fail at once, the first error in this sequence is returned.

A 500 APPLICATION_CREATE_FAILED refusal means the key has already been issued. The quota slot is taken and there is no card. Retry with a new idempotency key and revoke the extra key — revoking frees the quota slot, deleting the key is not required.

Some card fields are not populated by this endpoint — retrieve them from the application catalog. The field set matches GET /v1/applications/:id, but pinned is always false here, and sources and activeOperation are always empty, even if the application has been deployed and the user has pinned it in their Vibecode account. Read those fields from the application catalog; use the creation response for the identifier, name, and key.

The server is linked to the card automatically. After creating the application, create the server by calling POST /v1/infra/servers with the parameters from the server block of the creation parameters. No separate call is needed to link the server to the card.

See also