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

Bind a placement

POST /v1/placements/bind

Registers the application at the selected interface point of a Bitrix24 account — a card tab, a menu item, a chat panel. After the call the point appears in the interface with the title passed in the request.

Call preconditions — what is required before binding.

Request fields (body)

Field Type Req. Description
placement string yes Placement code. The list of codes available to the account — Available placements
handler string yes Absolute URL of the application page that opens at this placement
title string yes Placement title in the account interface, from 1 to 255 characters
options object no Placement settings. Besides the fields listed below, any other fields are accepted — for example context, role, extranet for chat widgets. The value of each field is a string, a number or a boolean. Nested objects and arrays are not accepted
options.iconName string no Font Awesome icon name with the fa- prefix — for example fa-comment. Bitrix24 rejects a name longer than 50 characters. The list of names — the Font Awesome 6 gallery. An icon is required for the IM_SIDEBAR, IM_NAVIGATION, IM_TEXTAREA placements, but the platform fills one in when the field is absent and reports it in the optionsDefaulted response field. Your own value always wins over the filled-in one. The IM_CONTEXT_MENU placement needs no icon
options.errorHandlerUrl string no Error page URL for the PAGE_BACKGROUND_WORKER placement. If the field is not passed, the platform substitutes the current handler URL
options.iconSvg string no Icon in SVG format, up to 10,000 characters
options.width number no Width of the IM_TEXTAREA panel, in pixels. A positive integer
options.height number no Height of the IM_TEXTAREA panel, in pixels. A positive integer
options.color string no Icon color for the IM_TEXTAREA and IM_SIDEBAR placements, from the Bitrix24 chat palette: RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK, LIME, BROWN, AZURE, KHAKI, SAND, ORANGE, MARENGO, GRAY, GRAPHITE. Not a hexadecimal code

Examples

curl — OAuth application

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/placements/bind \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "placement": "CRM_DEAL_DETAIL_TAB",
    "handler": "https://example.com/deal-tab",
    "title": "Deal analytics"
  }'

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/placements/bind', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    placement: 'CRM_DEAL_DETAIL_TAB',
    handler: 'https://example.com/deal-tab',
    title: 'Deal analytics',
  }),
})

const { data } = await res.json()
console.log('Registered handler URL:', data.handler)

Response fields

Field Type Description
success boolean true on a successful binding
data.placement string Code of the bound placement
data.handler string Handler URL registered on the account
data.title string Placement title in the account interface
data.options object Effective set of placement settings. Returned when the settings are passed in the request or substituted by the platform
data.alreadyBound boolean true when the placement was already listed as bound and the registration was performed again
data.handlerRewritten boolean true when the passed handler URL was replaced with the platform one
data.requestedHandler string Handler URL from the request. Returned together with handlerRewritten

Response example

The passed handler URL was replaced with the platform one:

JSON
{
  "success": true,
  "data": {
    "placement": "CRM_DEAL_DETAIL_TAB",
    "handler": "https://vibecode.bitrix24.com/v1/bitrix-handler",
    "title": "Deal analytics",
    "requestedHandler": "https://app-a1b2c3d4.vibecode.bitrix24.com/deal-tab",
    "handlerRewritten": true
  }
}

Repeated binding of the same code:

JSON
{
  "success": true,
  "data": {
    "placement": "CRM_DEAL_DETAIL_TAB",
    "handler": "https://example.com/deal-tab",
    "title": "Deal: summary",
    "alreadyBound": true
  }
}

Binding the PAGE_BACKGROUND_WORKER placement without options — the platform substituted the error page URL:

JSON
{
  "success": true,
  "data": {
    "placement": "PAGE_BACKGROUND_WORKER",
    "handler": "https://example.com/worker",
    "title": "Background worker",
    "options": {
      "errorHandlerUrl": "https://example.com/worker"
    }
  }
}

Error response example

400 — a required field is missing in the request body:

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

Errors

HTTP Code Description
400 OAUTH_APP_REQUIRED The call was made with a personal key. Binding works only with an application authorization key
400 VALIDATION_ERROR The request body failed validation — a required field is missing or the placement code is not in the list of allowed ones
400 PLATFORM_HANDLER_UNRESOLVABLE The passed URL points to the technical URL of the application server, and the platform handler could not be resolved. The placement is not registered
400 APP_NOT_REGISTERED The application has no Bitrix24 application identifier
400 BOX_NO_DEVELOPER_KEY The application author has no developer key configured
401 SESSION_REQUIRED The Authorization: Bearer header with a session token is missing
403 PLACEMENT_SCOPE_MISSING The key has no placement scope
403 WRITE_BLOCKED_READONLY_KEY The key works in read-only mode. Switch it to read and write
403 BOX_WEBHOOK_NOT_DEVELOPER_KEY The developer key used for the binding lacks the rest.developer scope. A key's scopes are fixed when it is issued — reconnect the account so the key is issued again. Returned before the account-access checks: a missing scope is not a question of the account's plan
403 SESSION_REQUIRES_ADMIN The developer key belongs to a user without account administrator rights
403 PLACEMENT_APP_GRANT_MISSING The placement is not available to the Bitrix24 application: its grant lacks the required scope. details carries the required scope in requiredScope, the placements available to the application (availablePlacements, availablePlacementsTotal) and the way to widen the grant in remediation. An application's scopes are fixed when it is installed — widening them requires re-issuing the authorization key or creating an application that requests the scope up front. Vibecode key scopes do not affect this
400 PLACEMENT_OPTIONS_REQUIRED The placement has a required option that is absent from the request and that the platform could not fill in. details carries missing — the list of those fields
400 PLACEMENT_NOT_REST_BINDABLE The placement cannot be bound over the API: Bitrix24 does not declare it an embedding point. Pick another code from available placements — placements like this one are marked there with restBindable: false
403 INT_TARIFF_REQUIRED The account gets access through its Bitrix24 plan — a commercial plan is required. error.details.upgradeUrl is not returned. On .com, infrastructure and key issuance additionally require a Vibe+ plan (INT_VIBE_PLUS_REQUIRED)
404 APP_NOT_FOUND No application is linked to the key
404 B24_EMBEDDING_APP_NOT_FOUND Bitrix24 does not know the application ID: the local application was deleted or reinstalled on the account. Create the local application again and call POST /v1/apps/:id/relink-oauth with the new bitrixClientId and bitrixClientSecret. Not to be confused with APP_NOT_FOUND, which is about the key-to-application link on the Vibecode side
413 PAYLOAD_TOO_LARGE The body was not sent as JSON and is longer than one byte. Set the Content-Type: application/json header
415 FST_ERR_CTP_INVALID_MEDIA_TYPE The body was not sent as JSON and is exactly one byte — the same cause, a different validation branch
502 BITRIX_UNAVAILABLE Bitrix24 rejected the placement registration and the reason could not be named. The Bitrix24 response code and status are returned in details, alongside placementInAppList when the placement is available to the application, and diagnostics"placement_list_skipped" when the reason could not be checked with the account, or "placement_list_empty" when it answered with an empty list, which proves nothing
503 NETWORK_DEVKEY_REQUIRED The developer key for the application author has not been issued yet

The full list of common API errors — Errors.

Known specifics

  • A placement can require a scope on the Bitrix24 application, not on the key. Bitrix24 offers an embedding point only to applications whose grant covers the module that placement belongs to: task card tabs need the tasks scope, profile menu items need the users scope, and so on. The scope each code requires is returned per placement in available placements as requiredScope, and the summary of the gates in key self-description as placements.bindPrerequisite. An application's scopes are fixed when it is installed: they cannot be changed on a live application — re-issue the authorization key instead.
  • The platform fills in the options a placement requires. A chat widget's icon and the background worker's error page URL are filled in when you omit them. The list of filled-in fields is returned as optionsDefaulted.
  • Repeated binding re-registers the placement. A call for an already bound code is not rejected: the platform removes the previous registration and binds the placement again, so the new handler URL and title take effect. This is the only way to change the title of an already bound placement.
  • The technical URL of the application server is replaced with the platform one. If handler points to the technical URL of the application server, the platform application handler is registered on the account. External URLs are registered unchanged.
  • Bitrix24 augments options with its own values. For chat widgets the account stores its own settings alongside the passed ones — display area, role and the extranet flag. They are returned in bound placements even when you did not pass them.
  • One title for all interface languages. The title value goes to the account as a single label. A separate translation is not set by this call. In bound placements the langAll field returns the same title for every language.
  • A successful response means the account accepted the write, not that the record stayed in place. The actual account state at any moment after binding is checked with the portalSync field in bound placements: ok — the account returned the code, drift — the code is listed in Vibecode but the account does not have it.
  • One placement can be occupied by several applications. Bitrix24 distinguishes registrations by application, so binding the same code from a second application of the account is not rejected and does not remove the first registration. Sharing the same platform handler URL across applications does not change that.

See also