For AI agents: markdown of this page — /docs-content-en/changelog/2026-08-26.md documentation index — /llms.txt
API changes: August 26, 2026
FIX-0826-1: socnetGroupId now works on the nested resources of workgroup lists
Before
The socnetGroupId parameter was honoured only on the lists themselves — GET /v1/lists and GET /v1/lists/{iblockId}. The nested resources accepted it and dropped it silently: GET /v1/lists/{iblockId}/elements, fields, sections, property files and every delete reached Bitrix24 without the workgroup id when iblockTypeId=lists_socnet. Bitrix24 looked the infoblock up outside the workgroup, failed to find it and answered with a wrong-infoblock-type error, so the client saw a 422 even though it had supplied the group.
After
socnetGroupId reaches Bitrix24 from every endpoint of the /v1/lists family: in the query string on reads and deletes, in the request body on creates and updates. The elements, fields and sections of a workgroup list come back exactly as they do for an ordinary list.
Impact on integrators
No request changes are needed. If a workgroup-list traversal was built on direct lists.* calls because of this defect, it can now be assembled from the platform endpoints.
BC-0826-2: exec into a Galaxy app answers CONTAINER_NOT_READY instead of a false success
Old format supported until: not provided
Before
POST /v1/infra/servers/{id}/exec on a Galaxy app whose container was not up yet answered 200 with success: true, while carrying exitCode: 1 and the container engine's own text in the stderr field. The command had not run, the answer looked successful, and a caller had to string-match the error text to learn why.
After
Such a call answers 502 with the code CONTAINER_NOT_READY and a hint that leads to deploying the application. Container engine details no longer travel in the response. Clients that expected 200 must handle CONTAINER_NOT_READY as a signal to deploy the application first and then retry the command. No string matching is needed: the code names the cause. If the host agent does not yet support safe container_exec, the platform does not dispatch a legacy command and answers 502 EXEC_FAILED; retry after the host agent is upgraded. Successful commands on a supported agent version are unchanged.
FIX-0826-3: 404 responses for Bitrix24 method names now point to the V1 route
Before
Requests to GET /v1/catalog.product.list, GET /v1/crm.deal.list, GET /v1/crm.user.list, and GET /v1/crm.deal.search returned the generic 404 ROUTE_NOT_FOUND response with only a pointer to GET /v1/guide. An agent had to find the replacement among the V1 routes on its own.
After
These requests still return 404 ROUTE_NOT_FOUND and do not call the Bitrix24 method, but error.details now contains the BITRIX_METHOD_AS_PATH reason, the original method name, a suggestedEndpoint object with the correct HTTP method and path, and a guide object pointing to GET /v1/guide. The hints lead to GET /v1/catalog-products, GET /v1/deals, GET /v1/users, or POST /v1/deals/search.
Impact on integrators
Do not build V1 paths from Bitrix24 method names. When error.details.reason = BITRIX_METHOD_AS_PATH, retry the request using suggestedEndpoint and read guide for the parameter requirements.
FIX-0826-4: Neutral offset in the English createdDate description
Before
GET /v1/task-time/fields used a timezone offset example specific to one region for createdDate.
After
The English description uses the neutral +00:00 offset.
Impact on integrators
No action is required. Only the example in the field description changed.
NEW-0826-5: creating an application from the Cowork/Code desktop — two new endpoints
An application on the Vibecode platform can now be created straight from the desktop, with no trip to the dashboard for a key.
GET /v1/cowork/applications/defaults returns everything the wizard needs before it asks the person anything: the presets for "what Bitrix24 data does the application need", the access mode the account gives new keys by default, the remaining key quota and the server parameters for the later POST /v1/infra/servers call. The endpoint only reads and creates nothing. A preset carries an identifier and a set of scopes but no labels: the platform owns what a preset consists of, while the client localises the wording by the stable identifier. The placement field has three values rather than two: galaxy-preferred is the ordinary verdict for an account whose policy allows both placements, and it is also where galaxy is demoted for an account on the free tier. When creation is switched off by a platform setting the endpoint answers 200 with available: false instead of a refusal, so the wizard hides its menu entry up front instead of hitting a refusal after the name has been typed.
POST /v1/cowork/applications creates a personal application and mints its personal key, which is returned once. No server is created: a personal application has none by definition — it is grown by publishing, and the server then attaches itself to the card. The card in the response carries the same set of fields the applications catalog returns, so the client still models a single "application" object. Some of the signs are not filled in by this endpoint — read pinning, saved source versions and the running operation from the catalog.
The Idempotency-Key header is required. A repeat with the same body answers 201, the header Idempotent-Replayed: true and rawApiKey: null — the raw key is stored irreversibly and is never re-issued. A lost key cannot be re-minted with the same Cowork/Code key — the response carries no identifier for the issued key, so store it immediately and, if it is lost, create the application again with a new header value. The same header with a different body answers 409 IDEMPOTENCY_KEY_BODY_MISMATCH; the fingerprint is taken over a normalised body, so re-ordered fields and re-ordered scopes still replay.
The Bitrix24 scopes are required and have no default. The issued key carries infrastructure and storage rights plus the Bitrix24 scopes that were asked for, and deliberately does NOT carry AI or web-search rights: an application created by this endpoint does not spend the platform wallet on AI.
Both endpoints require the vibe:cowork scope and an active Cowork/Code subscription. A subscription key issued for third-party agent software is not admitted to them — 403 COWORK_HARNESS_KEY_FORBIDDEN.
FIX-0826-6: work schedule answers with a clear error when the required id is missing
Before
GET /v1/workday/schedule without the required id was forwarded to Bitrix24 and returned 422 BITRIX_ERROR carrying the Bitrix24 text about a missing parameter. The response named neither the parameter in a readable form nor this endpoint, and the machine-readable description did not declare id as required, so a generated client would build such a call itself.
After
A request without id is refused before Bitrix24 is contacted and returns 400 MISSING_REQUIRED_PARAMS, stating that the schedule id is needed, not a user id. The machine-readable description declares id as a required query parameter.
Impact on integrators
A request with id behaves as before. A call made without id now returns 400 instead of 422 — the response was already an error, so working requests need no changes.
NEW-0826-7: an app is no longer granted the `vibe:infra` scope on accounts with infrastructure disabled
Before
POST /v1/apps with vibe:infra in the scope list created the app and its key
with that scope regardless of whether infrastructure was enabled in the account.
POST /v1/apps
{ "title": "My app", "scopes": ["crm", "vibe:infra"] }
HTTP 201
{ "success": true, "data": { "scopes": ["crm", "vibe:infra"] } }
After
When the account admin has turned server management off, a request carrying that
scope returns 403 INFRA_DISABLED_FOR_PORTAL and no app is created.
POST /v1/apps
{ "title": "My app", "scopes": ["crm", "vibe:infra"] }
HTTP 403
{
"success": false,
"error": {
"code": "INFRA_DISABLED_FOR_PORTAL",
"message": "Infrastructure is disabled on this portal — the vibe:infra scope cannot be granted"
}
}
The successful path is untouched: when infrastructure is enabled, the response remains HTTP 201 for the same request. A request without that scope keeps working on a closed account too — the scope is simply not appended by default, and no error is returned.
NEW-0826-8: the `vibe:infra` scope can no longer be added to an app by editing its scopes
Before
PATCH /v1/apps/:id with vibe:infra appended to the scope list wrote that scope
onto the app's paired keys regardless of whether infrastructure was enabled on the
account. That path handed a key server access on accounts where creating such a key
is refused.
PATCH /v1/apps/{id}
{ "scopes": ["crm", "vibe:infra"] }
HTTP 200
{ "success": true, "data": { "scopes": ["crm", "vibe:infra"] } }
After
When the account admin has turned server management off, adding the scope
returns 403 INFRA_DISABLED_FOR_PORTAL and neither the app nor its keys change.
PATCH /v1/apps/{id}
{ "scopes": ["crm", "vibe:infra"] }
HTTP 403
{
"success": false,
"error": {
"code": "INFRA_DISABLED_FOR_PORTAL",
"message": "Infrastructure is disabled on this portal — the vibe:infra scope cannot be granted"
}
}
The successful path is untouched: when infrastructure is enabled, the response remains HTTP 200 for the same request. Editing an app that already carries the scope keeps working on a closed account too, and removing the scope is always allowed.
NEW-0826-9: managing a galaxy server is blocked while galaxies are disabled for the account
Before
The galaxy flag was checked on creation only. An already created galaxy server —
POST /v1/infra/servers/:id/wake, PATCH /v1/infra/servers/:id/sleep and the
other mutating operations — could still be managed after the account admin had
turned galaxies off.
POST /v1/infra/servers/{id}/wake
HTTP 200
{ "success": true }
After
While galaxies are disabled for the account, mutating operations on such a server
return 403 GALAXY_DISABLED.
POST /v1/infra/servers/{id}/wake
HTTP 403
{
"success": false,
"error": {
"code": "GALAXY_DISABLED",
"message": "Galaxy feature is not enabled for this portal"
}
}
When galaxies are enabled, the response remains HTTP 200. Reading (GET), status
refresh (POST /v1/infra/servers/:id/refresh) and server deletion stay available
at all times: leaving the pilot and cleaning up is possible after the switch-off
too. Regular servers are not affected.
NEW-0826-10: the `vibe:infra` scope is no longer granted on accounts with infrastructure disabled
Before
POST /v1/keys and PATCH /v1/keys/:id granted the vibe:infra scope
regardless of whether infrastructure was enabled in the account — availability
was checked by the dashboard UI only.
PATCH /v1/keys/{id}
{ "scopes": ["crm", "vibe:infra"] }
HTTP 200
{ "success": true, "data": { "scopes": ["crm", "vibe:infra"] } }
After
When the account administrator has turned server management off, adding the scope
returns 403 INFRA_DISABLED_FOR_PORTAL.
PATCH /v1/keys/{id}
{ "scopes": ["crm", "vibe:infra"] }
HTTP 403
{
"success": false,
"error": {
"code": "INFRA_DISABLED_FOR_PORTAL",
"message": "Infrastructure is disabled on this portal — the vibe:infra scope cannot be granted"
}
}
The successful path is untouched: when infrastructure is enabled, the response remains HTTP 200 for the same request. Editing a key that already carries the scope keeps working even on a closed account: the gate looks at the scope being added, not at its presence in the request body. Removing the scope is always allowed. On key creation without an explicit request the scope is simply not appended by default — no error is returned.
NEW-0826-11: scope requirements map in the key self-description
GET /v1/me now returns a scopeRequirements field inside data.api — a map of the key's scopes. Until now the only way to learn a key's boundary was to make the call: the request went out and came back with a 403 SCOPE_DENIED refusal naming the missing scope. The list of available entities showed only what was open, while what was closed was simply absent, and absence could not tell "no such entity in the product" from "it exists but your key cannot reach it".
The granted field lists the scopes the key holds, split between Bitrix24 and Vibecode. The missing field lists the absent ones and, for each, which entities and which paths it would open, plus howToObtain — how to get it: Bitrix24 binds scopes to a key when the key is issued, so the only way to gain one is to reissue the key. Path lists are cut at five items and the remainder is reported in unlocksRemaining next to a truncated flag. The unobtainable field lists scopes a personal webhook key can never carry. The aliases field shows spellings Bitrix24 treats as one scope.
The coverage field declares the completeness of the map itself: entities is always complete, while paths is partial for now — some addresses still lack a machine-checked verdict, so the path lists under-report. Absence of an address from unlocks does not prove the address needs no scope: if a call still answers with a refusal, trust the refusal, not the map. Scopes the platform mints itself and a user cannot obtain go to unobtainable, not into missing with impossible advice.
The map describes the platform-side scope check only, as _note warns. It does not promise the call will succeed: a scope granted in the Vibecode account after the key was issued shows up in the map, but Bitrix24 does not honour it and answers BITRIX_ACCESS_DENIED. Refusals by key kind, ownership, read-only mode, account freeze and plan are separate axes and are not described in the map.
Refusals changed in neither code nor text: 403 SCOPE_DENIED still names the missing scope. This adds a pre-flight check, it does not replace the refusal.
FIX-0826-12: bracket-form sorting of task comments, `?sort[field]=direction`
Before
GET /v1/tasks/{taskId}/comments?sort[id]=desc answered 500 INTERNAL_ERROR. The bracket sort form is accepted by /v1/tasks and /v1/deals, and the flat spelling of the same request — ?sort=id:desc — already worked here too, so the failure looked arbitrary. Every bracket sort failed, including an unsortable field: ?sort[createdAt]=desc also answered 500, while the flat ?sort=createdAt returned a clear 400 INVALID_SORT_FIELD listing the sortable fields.
After
The bracket form is parsed like the flat one and goes through the same field-name check. ?sort[id]=desc sorts by ID and answers 200; the flat ?sort=id:desc is unchanged — its response remains HTTP 200. An unsortable field in brackets answers 400 INVALID_SORT_FIELD with the same field list as the flat form, and the error text names the field — Unsupported sort 'createdAt:desc'. A sort value that cannot be read unambiguously (a repeated parameter, mixed flat and bracket forms, nested or malformed brackets, an array, or more than one colon) also answers 400 instead of being silently reinterpreted or dropped. The same bracket-shaped sort on the task-checklist and platform-portals lists now returns a controlled 400 instead of 500. This parameter no longer produces 500 in any form.
FIX-0826-13: waking an app on a failed Galaxy host now ends with an explicit error
Before
POST /v1/infra/servers/:id/start and POST /v1/infra/servers/:id/wake could appear successful for a Galaxy app even after the shared host guest OS had been classified as unable to boot. The client kept waiting for a startup that could never finish.
After
Both requests now return HTTP 422 with code GUEST_NOT_BOOTING for that Galaxy app. The client can stop waiting immediately and prompt the user to replace the failed host.
FIX-0826-14: Bitrix24 registration failures no longer expose the vendor's internal text
Before
When Bitrix24 refused registration while issuing a key or an application, its
internal wording was passed straight through in error.message — for example
Cannot register webhook: Failed to register webhook in portal. That text is
always English, is not covered by the documentation, and could change on the
Bitrix24 side at any time. One family of these failures (incoming-webhook
registration) also returned the Bitrix24 code directly instead of a Vibecode one.
After
error.message now carries Vibecode wording, and the details of the Bitrix24
reply stay in the logs. A webhook registration refusal is classified the same way
as an application registration refusal and returns REST_REGISTRATION_FAILED.
The response gains error.details.incidentCode — a six-character support code
that lets support locate the log record. HTTP statuses and error codes are
unchanged, so no client action is required.