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 on the 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. For future publishing the set needs placement. There is no need to list the platform vibe:* scopes, the platform grants them itself. 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

handlerUrl is set by the platform — it is not accepted in the body. OAuth callbacks and opening a placement go through it. The difference between appUrl and handlerUrl — in 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.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.rawKey string Ready-to-use authorization key vibe_app_…. The only vibe_app_… value in this response — use exactly this as X-Api-Key. Returned only in this response and never shown again

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",
    "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,
    "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: title missing, empty scopes, invalid appUrl
403 APP_CREATION_RESTRICTED Application creation on the portal is restricted to a list, and the author is not on it
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 issue an application with mode: "READONLY". More — Access mode
409 KEY_LIMIT_REACHED The per-user key limit for the portal has been reached
409 CONNECTOR_MODULE_NOT_INSTALLED The Vibecode Connector module is not installed on the portal — an authorization key cannot be issued. Retrying without installing the module will not help

The full list of general API errors — Errors.

Known specifics

  • 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. 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. That is why a fresh authorization key creates 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.

See also