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

Create an application

POST /v1/apps

Registers an OAuth application in your Bitrix24 account and creates a paired API key. The body is passed flat, without a wrapper.

Request fields (body)

Field Type Req. Description
title string yes Application name, from 1 to 255 characters
scopes array yes Set of application scopes — access to Bitrix24 account data, at least one. To publish the application later, the set must include placement. The platform vibe:* scopes are listed only when the request comes from a key with a fixed rights set. In every other case the paired key receives them on its own — see "Known specifics". The list — Scopes
description string no Application description, up to 2000 characters
appUrl string no Application URL, only http:// or https://. An empty string is saved as null
redirectUris array no OAuth redirect URLs. Defaults to the authorization completion URL and http://localhost
mode string no Access mode of the paired key: READONLY or READWRITE. Defaults to the Bitrix24 account policy
mobile boolean no The application supports the Bitrix24 mobile client — the account receives this flag at registration. Defaults to false. Can only be set at creation, see "Known specifics"

handlerUrl is set by the platform — it is not accepted in the body. OAuth callbacks and opening a placement go through it. For the difference between appUrl and handlerUrl, see the Applications section.

Examples

curl — personal key

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/apps \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Sales dashboard",
    "scopes": ["crm", "user", "placement"],
    "appUrl": "https://app-abc12345.vibecode.bitrix24.com"
  }'

curl — OAuth application

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/apps \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Sales dashboard",
    "scopes": ["crm", "user", "placement"],
    "appUrl": "https://app-abc12345.vibecode.bitrix24.com"
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/apps', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Sales dashboard',
    scopes: ['crm', 'user', 'placement'],
    appUrl: 'https://app-abc12345.vibecode.bitrix24.com',
  }),
})

const { data } = await res.json()
// Save data.rawKey immediately — it is returned only once
console.log('App ID:', data.id)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/apps', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Sales dashboard',
    scopes: ['crm', 'user', 'placement'],
    appUrl: 'https://app-abc12345.vibecode.bitrix24.com',
  }),
})

const { data } = await res.json()

Response fields

Field Type Description
data.id string Application identifier
data.title string Name
data.description string | null Description
data.scopes array Set of application scopes — exactly what you passed in the body. The paired key's scopes are wider — see "Known specifics"
data.handlerUrl string Handler URL, set by the platform
data.appUrl string | null Application URL
data.redirectUris array OAuth redirect URLs
data.bitrixClientId string | null OAuth client identifier in the Bitrix24 account
data.authorId string Author identifier
data.authorBitrixUserId integer | null Bitrix24 employee id of whoever created the app — the same identifier id carries in GET /v1/users. null when the id is unknown
data.authorBitrixUserIdSource string | null Where the id came from: member — the author's confirmed membership of the account, snapshot — a value captured when the app was created, null — no id
data.portalId string Bitrix24 portal identifier
data.createdAt string Creation date, ISO 8601
data.updatedAt string Modification date, ISO 8601
data.placements array Placements, empty before publishing
data.catalogStatus string Catalog status. For a new application — always PRIVATE
data.publishedAt string | null Publication date, ISO 8601. For a new application — null
data.mobile boolean The "Supports BitrixMobile" flag the platform actually sent to the Bitrix24 account at registration. false when the field was not sent or the flag could not be applied, in which case the reason arrives in warnings
data.rawKey string Ready-to-use authorization key vibe_app_…. This is the only vibe_app_… value in the response — use exactly this one as X-Api-Key. Returned only in this response and never shown again
warnings array<string> Returned only when there is something to report. Two reasons: a title that lost its non-ASCII characters on the way in, and a mobile flag that could not be applied on the account at registration (see "Known specifics"). The application is still created and the response stays 201

Response example

rawKey is shown with a truncated secret — this is not a working value.

JSON
{
  "success": true,
  "data": {
    "id": "33c4d5e6-f7a8-49b0-1234-5c6d7e8f9012",
    "title": "Sales dashboard",
    "description": null,
    "scopes": ["crm", "user", "placement"],
    "handlerUrl": "https://vibecode.bitrix24.com/v1/bitrix-handler",
    "appUrl": "https://app-abc12345.vibecode.bitrix24.com",
    "redirectUris": [
      "https://vibecode.bitrix24.com/oauth/complete",
      "http://localhost"
    ],
    "bitrixClientId": "local.7c3d4e5f6a7b80.55556666",
    "authorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "authorBitrixUserId": 42,
    "authorBitrixUserIdSource": "member",
    "portalId": "8b1f0e2a-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    "createdAt": "2026-06-24T09:12:45.781Z",
    "updatedAt": "2026-06-24T09:12:45.781Z",
    "placements": [],
    "catalogStatus": "PRIVATE",
    "publishedAt": null,
    "mobile": false,
    "rawKey": "vibe_app_local_7c3d4e5f6a7b80_55556666_…_6666"
  }
}

Error response example

400 — validation failed:

JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "title: Required"
  }
}

Errors

HTTP Code Description
400 VALIDATION_ERROR Body validation failed: missing title, empty scopes, invalid appUrl
400 REST_REGISTRATION_FAILED Bitrix24 refused to register the application or its webhook and gave no reason. The response carries error.details.incidentCode — a six-character support reference that locates the log entry. Quote it when you contact support
402 INT_TARIFF_REQUIRED The route checks account access to the platform before anything else. The account is on a free Bitrix24 plan, so creation never starts. The response carries userMessage, the ways to resolve the refusal in error.alternatives, and the current and required plans with the upgrade link in error.details. The same code appears in the 403 row below, and these are different checks: 402 comes from the account access check that runs before any work starts, 403 from the refusal to issue the paired key
402 INT_VIBE_PLUS_REQUIRED Account access is narrowed to a paid Vibe+ plan, and an ordinary commercial Bitrix24 plan is no longer enough. An account on a trial plan keeps its trial access and does not receive this code
403 INFRA_DISABLED_FOR_PORTAL scopes explicitly asks for vibe:infra and the Bitrix24 account administrator has turned server management off. The application is not created. A request without that scope goes through on such an account as well: the scope the platform appends by default is dropped there silently
403 INFRA_FORBIDDEN_FOR_COWORK_KEY The call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy
403 APP_CREATION_RESTRICTED The portal policy does not allow the caller to create applications: creation is disabled entirely, limited to Bitrix24 account administrators, or restricted to a list the caller is not on. A Bitrix24 account administrator grants the right. More — Creation rights
403 KEY_POLICY_READONLY_REQUIRED The portal policy allows only READONLY, but READWRITE was requested
403 WRITE_BLOCKED_READONLY_KEY The request comes from a key in read-only mode while the paired key is being created in READWRITE mode. Such a key can only create an application with mode: "READONLY". More — Access mode
403 INT_TARIFF_REQUIRED The account gets access through its Bitrix24 plan, and issuing the paired authorization key requires a commercial plan. error.details.upgradeUrl is not returned. The same code with 402 above is a different check — it runs earlier and concerns account access rather than key issuance
403 PORTAL_TARIFF_UNREADABLE The account plan could not be read, so the response does not name the plan that is missing: error.details.requiredTariffs is empty and the button points to support. Buying a plan does not clear this refusal
403 SCOPE_GRANT_REQUIRES_CONSENT The request comes from a key with a fixed rights set and declares a platform vibe:* scope that the calling key itself does not hold. The list of such scopes arrives in error.details.unconsented. The rights set is fixed for a partner key, for a Cowork project key, for a personal key issued by the Vibecode dashboard form (it grants exactly the rights that were ticked) and for a key issued with exactScopes: trueManagement keys. Scopes confirmed to the partner key on the consent page can be declared. How to identify such a key — "Known specifics"
403 CONNECTOR_APP_INSTALL_FORBIDDEN A Bitrix24 account administrator has barred this employee from installing applications. It arrives where the application is installed by the connector module: on a self-hosted account, and on a cloud account once that issuance path is enabled for it. Retrying does not change the state; the right is granted by an account administrator. More — Creation rights
409 KEY_LIMIT_REACHED The per-user key limit for the portal has been reached. error.details carries the quota state: limit — how many keys are allowed, used — how many are taken. used also counts application authorization keys and keys the platform issued itself, so the total can exceed what the key list in the dashboard shows — more
409 CONNECTOR_MODULE_NOT_INSTALLED The connector module is not installed on the Bitrix24 account — an application cannot be installed and a paired key cannot be issued through it. The state is permanent; retrying without installing the module will not help
409 B24_USER_DELETED The Bitrix24 employee who owns the paired key is no longer active on the account. The state is permanent: neither a retry nor freeing a key slot helps — the employee has to be restored on the account, or the application created under another user
502 CONNECTOR_APP_INSTALL_FAILED The connector module failed to install the application for another reason. Neither the application nor the paired key is created, and the request can be retried
502 CONNECTOR_REST_UNAVAILABLE The account's plan or trial period is active, but Bitrix24 refused to issue the paired key. It arrives where the other connector codes do — when the application is installed by the connector module. The original refusal reason arrives in error.details.reason, and error.details.retryable: true says the state is transient — retry the request, and contact support if it repeats. The response carries no upgrade offer: there is nothing to buy
502 CONNECTOR_PLAN_REQUIRED Bitrix24 refused to issue the paired key: the account plan does not include Vibecode. It arrives where there is nothing to offer — a self-hosted account, an account already on a paid plan, an unrecognised region. The human-readable cause arrives in error.userMessage. The state is permanent: retrying will not help until the Bitrix24 plan changes. Where access is sold, the same refusal arrives as 402 with a plan paywall code from the table above

The full list of general API errors — Errors.

Known specifics

  • The platform reports non-ASCII characters lost from the title. A value sent without explicit UTF-8 serialization arrives with question marks instead of letters: the bytes are lost on the client side, before the request is sent. Windows PowerShell sends values this way. The application is still created as is, and the response carries warnings naming the field — the title becomes the Bitrix24 catalog card name on publish, so fix it right away. A ready-to-run call with UTF8.GetBytesWindows / PowerShell and UTF-8.
  • The authorization key is returned only once. The rawKey field is present in the creation response and nowhere else — neither in application data nor in the list. If you did not save it at creation, recreate the application.
  • A pair is created: an application and an API key. Registration creates an application record and a paired authorization key in one step. This affects deletion: the key frees a slot in the per-user limit only after deleting the application.
  • Application scopes and paired-key scopes are different sets. In scopes you declare access to Bitrix24 account data — crm, user, placement. If the calling key's rights set is not fixed, the paired key receives that set plus four platform scopes: vibe:infra — servers and agents, vibe:ai — model calls, vibe:search — web search and research, vibe:storage — object storage. The authorization key can then create servers through POST /v1/infra/servers right away, even though vibe:infra was never in the create body. The data.scopes field of the response shows the application declaration, not the key's effective set — read the effective set from data.scopes of GET /v1/me called with that key.
  • A key with a fixed rights set grants the paired key exactly what was declared. The rights set is fixed for a partner key, for a Cowork project key, for a personal key issued by the Vibecode dashboard form and for a key issued with exactScopes: trueManagement keys. An application created with such a key gets a paired key holding exactly what is listed in scopes — no platform scopes are added to it. If you need infrastructure, list vibe:infra in scopes at creation time, otherwise POST /v1/infra/servers answers 403 INFRA_SCOPE_REQUIRED. The same goes for vibe:ai, vibe:search and vibe:storage. You can only declare a right that the calling key itself holds, otherwise the answer is 403 SCOPE_GRANT_REQUIRES_CONSENT. Adding the right later through updating the application does not work: vibe:* propagation never reaches a key with a fixed set.
  • You can identify a key with a fixed rights set before creating the application. Call GET /v1/me with the key you plan to create the application with. The set is fixed when data.scopes matches what was ticked when the key was issued. Other keys carry vibe:ai and vibe:search in the set even when those were not ticked.
  • The mobile flag can only be set at creation. Bitrix24 has no method for updating a local application, so PATCH /v1/apps/:id does not accept mobile — a sent value is ignored, see Update an application. For an existing application, turn the flag on in the application card on the Bitrix24 account, or create the application again.
  • The mobile flag may not be applied at registration. When the Bitrix24 account registers the application through a path that cannot carry the flag, the application is still created, data.mobile is false in the response, and warnings carries a line starting with mobile:. In that case, turn the flag on in the application card on the account.

See also