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 placement appears in the interface under the title passed in the request.

Call preconditions — what is required before binding.

On a cloud account, the platform first uses the transport selected for that account. If Bitrix24 rejects the developer key with a credential-only HTTP 401 and the app key is accompanied by a live Authorization: Bearer session, the bind is retried through OAuth automatically. A response that explicitly names a non-credential cause, such as an account-policy refusal or a missing scope, remains authoritative at every HTTP status and is never retried through OAuth. A successful response means one of these independent channels confirmed the write.

Request fields (body)

Field Type Required Description
Fieldplacement Typestring Requiredyes DescriptionPlacement code. The list of codes available to the account — Available placements
Fieldhandler Typestring Requiredyes DescriptionAbsolute URL of the application page that opens at this placement
Fieldtitle Typestring Requiredyes DescriptionPlacement title in the account interface, from 1 to 255 characters, not whitespace only
Fieldoptions Typeobject Requiredno DescriptionPlacement 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
Fieldoptions.iconName Typestring Requiredno DescriptionFont 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
Fieldoptions.errorHandlerUrl Typestring Requiredno DescriptionError page URL for the PAGE_BACKGROUND_WORKER placement. If the field is not passed, the platform substitutes the current handler URL
Fieldoptions.iconSvg Typestring Requiredno DescriptionIcon in SVG format, up to 10,000 characters
Fieldoptions.width Typenumber Requiredno DescriptionWidth of the IM_TEXTAREA panel, in pixels. A positive integer
Fieldoptions.height Typenumber Requiredno DescriptionHeight of the IM_TEXTAREA panel, in pixels. A positive integer
Fieldoptions.color Typestring Requiredno DescriptionIcon 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
Fieldsuccess Typeboolean Descriptiontrue on a successful binding
Fielddata.placement Typestring DescriptionCode of the bound placement
Fielddata.handler Typestring DescriptionHandler URL registered on the account
Fielddata.title Typestring DescriptionPlacement title in the account interface
Fielddata.options Typeobject DescriptionEffective set of placement settings. Returned when the settings are passed in the request or substituted by the platform
Fielddata.alreadyBound Typeboolean Descriptiontrue when the placement was already listed as bound and the registration was performed again
Fielddata.handlerRewritten Typeboolean Descriptiontrue when the passed handler URL was replaced with the platform one
Fielddata.requestedHandler Typestring DescriptionHandler 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
  }
}

Rebinding 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
HTTP400 CodeOAUTH_APP_REQUIRED DescriptionThe call was made with a personal key. Binding works only with an application authorization key
HTTP400 CodeVALIDATION_ERROR DescriptionThe request body failed validation — a required field is missing, title is whitespace only, or the placement code is not in the list of allowed ones
HTTP400 CodePLATFORM_HANDLER_UNRESOLVABLE DescriptionThe passed URL points to the technical URL of the application server, and the platform handler could not be resolved. The placement is not registered
HTTP400 CodeAPP_NOT_REGISTERED DescriptionThe application has no Bitrix24 application identifier
HTTP400 CodeBOX_NO_DEVELOPER_KEY DescriptionThe application author has no developer key configured
HTTP401 CodeSESSION_REQUIRED DescriptionThe Authorization: Bearer header with a session token is missing
HTTP403 CodePLACEMENT_SCOPE_MISSING DescriptionThe key has no placement scope
HTTP403 CodeWRITE_BLOCKED_READONLY_KEY DescriptionThe key works in read-only mode. In the Vibecode dashboard, open the page at the path from error.details.switchUrl and switch the mode to read and write there. Where the path leads for each kind of key — Access mode
HTTP403 CodeWRITE_BLOCKED_READONLY_KEY DescriptionThe key does not change Bitrix24 data, and the placement embeds into an employee work screen, or its handler after the Black Hole address rewrite is not the platform handler
HTTP403 CodeBOX_WEBHOOK_NOT_DEVELOPER_KEY DescriptionThe 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
HTTP403 CodeSESSION_REQUIRES_ADMIN DescriptionThe developer key belongs to a user without account administrator rights
HTTP403 CodePLACEMENT_APP_GRANT_MISSING DescriptionThe 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
HTTP400 CodePLACEMENT_OPTIONS_REQUIRED DescriptionThe 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
HTTP400 CodePLACEMENT_NOT_REST_BINDABLE DescriptionThe 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
HTTP403 CodeB24_ACCESS_DENIED DescriptionBitrix24 rejected the developer-key credential with HTTP 401, and either no OAuth session was supplied or the OAuth retry also failed. This is a credential refusal, not a plan paywall. The safe error.details fields are documented below; the raw Bitrix24 response text and the developer-key URL are never returned
HTTP403 CodeINT_TARIFF_REQUIRED DescriptionThe account gets access through its Bitrix24 plan — a commercial plan is required. error.details.upgradeUrl is not returned. For accounts where access is narrowed to the Vibe+ plan line, infrastructure and key issuance additionally require a Vibe+ plan (INT_VIBE_PLUS_REQUIRED)
HTTP404 CodeAPP_NOT_FOUND DescriptionNo application is linked to the key
HTTP404 CodeB24_EMBEDDING_APP_NOT_FOUND DescriptionBitrix24 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
HTTP413 CodePAYLOAD_TOO_LARGE DescriptionThe body was not sent as JSON and is longer than one byte. Set the Content-Type: application/json header
HTTP415 CodeFST_ERR_CTP_INVALID_MEDIA_TYPE DescriptionThe body was not sent as JSON and is exactly one byte — the same cause, a different validation branch
HTTP422 CodeAPP_HOST_NOT_ALLOWED_HERE Descriptionhandler or options.errorHandlerUrl points at a named address of the platform app domain (<name>.<domain>, not app-…) whose name is not bound to a server of your Bitrix24 account. Nothing is stored and Bitrix24 is not called. A name of your own server is accepted and stored as that server's app-… address
HTTP502 CodeBITRIX_UNAVAILABLE DescriptionBitrix24 rejected the placement registration and the reason could not be determined. 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
HTTP503 CodeNETWORK_DEVKEY_REQUIRED DescriptionThe developer key for the application author has not been issued yet

`B24_ACCESS_DENIED` fields

Field Type Description
Fielderror.details.bitrixCode Typestring DescriptionSafe machine code from the rejected developer-key attempt
Fielderror.details.bitrixStatus Typenumber DescriptionHTTP status returned by Bitrix24
Fielderror.details.oauthFallback Typestring Descriptionunavailable when there was no OAuth session, or failed when the OAuth retry was also rejected
Fielderror.details.oauthCode Typestring DescriptionOptional safe machine code from the rejected OAuth retry
Fielderror.details.oauthStatus Typenumber DescriptionOptional HTTP status from the rejected OAuth retry

These fields are diagnostics, not a selector for another client-side transport attempt: the platform has already performed or declined the OAuth fallback. Clients branch on the outer error.code; the set of internal Bitrix24 codes is not a stable API enum.

The full list of common API errors — Errors.

The error table is segment-specific and documents the codes of this deployment. On the international surface, an account-access refusal is represented by INT_TARIFF_REQUIRED; do not copy codes from another deployment segment into a shared client enum.

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.
  • Rebinding 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.
  • LEFT_MENU adds a second menu item. The application appears in the account menu as soon as it is created. Binding LEFT_MENU adds a second item with its own URL rather than replacing the first one. To remove the extra item, unbind the LEFT_MENU code — the item that appeared at creation stays in place.
  • A credential-only developer-key HTTP 401 does not mean a different plan is required. It rejects that credential channel. With a live OAuth session the platform tries the independent channel; without one it returns B24_ACCESS_DENIED with the safe Bitrix24 machine code and status. A named account-policy or missing-scope refusal remains authoritative regardless of HTTP status and never enters the OAuth fallback.
  • 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. This call does not set a separate translation. 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. Check the actual account state at any moment after binding 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 on the same 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