For AI agents: markdown of this page — /docs-content-en/apps/placements/list.md documentation index — /llms.txt
Bound placements
GET /v1/placements
Returns the placements that are listed as bound for the application. When a session token is passed together with the application key, Vibecode reconciles this list with the Bitrix24 account and reports the outcome of that reconciliation in a dedicated field — matched, diverged, or not checked.
Call preconditions — what is required before binding.
Examples
curl — OAuth application
curl https://vibecode.bitrix24.com/v1/placements \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/placements', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
console.log('Confirmed by the account:', data.handlers)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.placements |
string[] | Placement codes bound by the application |
data.appId |
string | Application identifier. List of applications — GET /v1/apps |
data.appTitle |
string | Application name |
data.handlers |
array | Handler data received from the account. The field is optional — it is returned when the account response was obtained. Read the reconciliation outcome from data.portalSync, not from the presence or the length of this array |
data.handlers[].placement |
string | Placement code |
data.handlers[].handler |
string | Handler address registered on the account |
data.handlers[].misbound |
boolean | true when the handler is registered to the technical address of the application server. Such a placement will not pass authorization inside Bitrix24 |
data.handlers[].title |
string | Placement caption on the account |
data.handlers[].options |
array | object | Placement settings. An empty array when there are no settings |
data.handlers[].langAll |
object | Placement captions by language. The key is the language code, the values are TITLE, DESCRIPTION, GROUP_NAME |
data.portalSync |
string | Reconciliation outcome against the account. ok — the account returned every bound code, drift — the account did not return some of the codes, unknown — no reconciliation was performed. Returned in every successful response |
data.portalSyncReason |
string | Why portalSync is not ok. no_oauth_session — no session token was passed, empty_vibe_list — the application has no bound placements, b24_unreachable — the account response could not be obtained, unpublished — the application is withdrawn from the catalog, removed placements are not treated as a divergence, missing_on_portal — the account did not return some of the codes. Absent when ok |
data.missingOnPortal |
string[] | Codes that are listed as bound in Vibecode and were not returned by the account. Returned only when portalSync equals drift |
warnings |
string[] | Appears when at least one placement has misbound equal to true or when portalSync equals drift |
Response example
A session token was passed and the account returned both bound codes — portalSync equals ok:
{
"success": true,
"data": {
"placements": ["LEFT_MENU", "CRM_DEAL_DETAIL_TAB"],
"appId": "3d5f7a91-2b4c-4e8f-9a01-6c7d8e9f0a1b",
"appTitle": "Sales dashboard",
"handlers": [
{
"placement": "CRM_DEAL_DETAIL_TAB",
"handler": "https://example.com/tab",
"misbound": false,
"title": "Deal documents",
"options": [],
"langAll": {
"en": { "TITLE": "Deal documents", "DESCRIPTION": "", "GROUP_NAME": "" },
"ru": { "TITLE": "Deal documents", "DESCRIPTION": "", "GROUP_NAME": "" }
}
},
{
"placement": "LEFT_MENU",
"handler": "https://example.com/menu",
"misbound": false,
"title": "Sales dashboard",
"options": [],
"langAll": {}
}
],
"portalSync": "ok"
}
}
The account did not return a bound code — a divergence, and the code is named in missingOnPortal:
{
"success": true,
"data": {
"placements": ["LEFT_MENU"],
"appId": "3d5f7a91-2b4c-4e8f-9a01-6c7d8e9f0a1b",
"appTitle": "Sales dashboard",
"handlers": [],
"portalSync": "drift",
"portalSyncReason": "missing_on_portal",
"missingOnPortal": ["LEFT_MENU"]
}
}
No session token was passed — no reconciliation happened and handlers is absent:
{
"success": true,
"data": {
"placements": ["LEFT_MENU"],
"appId": "3d5f7a91-2b4c-4e8f-9a01-6c7d8e9f0a1b",
"appTitle": "Sales dashboard",
"portalSync": "unknown",
"portalSyncReason": "no_oauth_session"
}
}
Error response example
400 — the request was made with a personal key:
{
"success": false,
"error": {
"code": "OAUTH_APP_REQUIRED",
"message": "Placement management is only available for OAuth app keys"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | OAUTH_APP_REQUIRED |
The request was made with a personal vibe_api_ key |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not passed |
| 401 | INVALID_API_KEY |
Invalid key |
| 404 | APP_NOT_FOUND |
No application is linked to the key |
Full list of common API errors — Errors.
Known specifics
- A divergence is determined by
portalSync, not by the presence or the length ofhandlers. An absenthandlersfield and an emptyhandlersarray are different states. The empty array is returned when the account response was obtained and none of the bound codes were in it. An absent field means the account response was not read. Take the verdict fromportalSyncin both cases rather than from the array: for an application withdrawn from the catalog an emptyhandlerscomes withunknown, not withdrift. unknownis not equivalent took. The value means that the binding is not confirmed, and it splits into two cases. The account was not read — reasonsno_oauth_session,empty_vibe_list,b24_unreachable, and thehandlersfield is absent from the response. The account was read but its state is not matched against our list — reasonunpublished, and thenhandlersis present.- An application withdrawn from the catalog is not treated as a divergence. With
unpublishedthe verdict is suppressed: removed placements are the expected consequence of the operation. The account is still queried, because unpublishing does not guarantee that every placement was actually removed, sohandlersand themisboundflag stay in the response. What remains inplacementsafter a withdrawal, and how to remove the leftovers, is covered on the operation's own page. - A divergence is resolved by binding again. The codes from
missingOnPortalare returned to the account by calling Bind a placement. - Codes that are absent from
data.placementsare not treated as a divergence. The account may hold placements of other applications, and that does not affectportalSync. - A placement with
misboundequal totrueis a separate state, not a divergence. The account did return such a placement, so it never lands inmissingOnPortalandportalSyncstaysok— orunknownwith theunpublishedreason when the application is withdrawn from the catalog. A call to Bind a placement replaces the technical address of the application server with the platform handler address.