For AI agents: markdown of this page — /docs-content-en/changelog/2026-08-14.md documentation index — /llms.txt
API changes: August 14, 2026
NEW-0814-1: thirty-one more live operations are now in the machine schema
Thirty-one V1 operations that were already live and documented are now included in GET /v1/openapi.json: smart-process custom fields, requisite links, CRM card configuration, configurable activities, mail, task time tracking, server icon and unstick operations, bot transfer and human-resources node search, plus app blueprints. The methods and their responses did not change — only the machine-readable descriptions were added for clients and agents that build integrations from the schema.
BC-0814-2: port pinning refuses instead of confirming falsely
Old format supported until: not provided
Before
On a pinned server PATCH /v1/infra/servers/:id/port wrote the requested port into the agent settings without checking whether any process on the machine was listening on it. The public address could stop answering entirely after such a change, and the only way back was the non-obvious port: 0. A verified: true reply meant no more than that the agent had come back online: an agent that came up with automatic port detection, that is without the pin in force, produced exactly the same confirmation. Two calls in a row could leave the agent on the port of the other request, and both answered with success.
After
A port nothing listens on is refused with 409 PORT_NOT_APPLIED before the settings are rewritten; the message lists the ports the agent sees listening. Entry NEW-0812-3 stated that a pinned server never receives this code — it does, in exactly this case and without the agentError field.
The confirmation is stricter: verified: true now means that the agent settings carry the requested port, that the agent really did restart, and that it came up with the pin in force rather than with automatic detection. The reply additionally carries data.pinned — whether the machine is still pinned after the call.
While a port change is still in progress, a second call for the same server receives 409 SERVER_BUSY. The endpoint itself now has a rate limit of 10 requests per minute.
What integrators should do
Start the process on the target port BEFORE changing the port: the order "pin the port first, launch the application on it afterwards" now answers with a refusal rather than a success. Do not send a port change in parallel with a deployment or with another port change of the same server — wait for the previous call to answer. Stay within 10 requests per minute.
FIX-0814-3: the dimensions parameter for the bitrix/embeddings model
Before
The dimensions parameter was declared in the POST /v1/embeddings schema, but any request carrying it for the bitrix/embeddings model received 400 ai_provider_rejected — whatever the value, including the dimensionality the model already returns.
After
For bitrix/embeddings the parameter works: an integer from 32 to 4096 is accepted, and the response carries a vector of that dimensionality re-normalised to unit length. A value outside the range is rejected with 400 invalid_request and a param field. Requests without the parameter are unchanged: the full dimensionality is 4096.
A smaller dimensionality neither reduces input-token usage nor speeds up processing — the saving is on the integrator's side, in index size and search speed. Vectors of different dimensionality must not be mixed in one similarity index. Details — Create embeddings.
FIX-0814-4: leading service markers are no longer included in model content
Before
After a tool call, the final answer from POST /v1/chat/completions sometimes started with service markers before the text. A response_format request whose answer was only those markers returned 200 and a non-empty content.
After
Leading service markers are removed from content. If no text remains, content is null — the same as a textless answer. For a response_format request this is the already documented empty-content case without tool_calls: HTTP 422 and code structured_output_truncated. If text remains after the markers are removed, the response stays 200 with the cleaned content.
Impact on integrators
In the common case no client change is required: the answer is the same minus the prefix, and stripping the prefix on your side stays safe. The change does affect you if you relied on a 200 for a response_format request whose answer carried no text: that response now comes back with 422 and structured_output_truncated, as described on the method page. The markers are removed in streaming mode as well. The usage field is not recalculated.
FIX-0814-5: the blocking server wake returns WAKE_TIMEOUT far less often on a cold start
Before
The blocking wake — POST /v1/infra/servers/:id/wake with ?wait=true, and the automatic wake of a sleeping server on POST /v1/infra/servers/:id/deploy — returned 503 WAKE_TIMEOUT in two cases that had nothing to do with how long it waited. When the cloud lost the start command, the platform never re-issued it and eventually reported that the machine had not come up. And when the agent connected its tunnel before the platform refreshed the server status, readiness was still not recognised, so a machine that was already up was put back to sleep.
After
While waiting for readiness, the platform now re-checks the machine state with the cloud and re-issues the start command if it never landed. A connected tunnel counts as proof of readiness on its own: the server moves to running and the response returns without waiting for the next status refresh. Error codes, the response shape and the wait window (~6.5 minutes, then 503 WAKE_TIMEOUT and the server returns to sleeping) are unchanged, so clients need to change nothing. A machine that genuinely did not come up still reports WAKE_TIMEOUT honestly.
FIX-0814-6: a fractional or malformed path id no longer returns a DIFFERENT record
Before
GET /v1/tasks/1.5 answered 200 and returned the record with id 1: the non-integer value was forwarded to Bitrix24 as-is, Bitrix24 truncated it, and the client got a DIFFERENT real record instead of an error. Update and delete behaved the same way — a write silently landed on the wrong record. This affected entities with an integer id; the wrong-record substitution was observed live on twelve of them (tasks, workgroups, users, departments, statuses, storages, sites, pages, folders, timelines, Open Channels configs, requisite presets), while for the rest Bitrix24 rejected the request itself. Some entities (deals, for example) already answered 400, so the behaviour differed inside one API.
After
A non-integer id is rejected with 400 INVALID_PARAMS before the Bitrix24 call — consistently on read, update and delete, in single requests and in batches (/v1/batch, /v1/<entity>/batch). The rule applies to every entity with a numeric id. Integer values work as before. Entities whose id is not a number (order statuses N/P/F, currencies, business-process codes) and chats, which accept the chat1 form, keep their previous behaviour.
NEW-0814-7: reading the notification feed and the unread counter
GET /v1/notifications is now available — it reads a user's notification feed together with the unread counter. Until now the Vibecode API could only send notifications, mark them read and delete them, so an inbox application had to keep a second, separate Bitrix24 integration just to read them.
The response carries the notification list, the cards of their authors, the total counter, the unread counter and a hasMore flag. Page size comes from limit (1 to 50, 50 by default); a value outside the range is brought to the nearest bound, and the size actually used is always visible in meta.appliedLimit. Paging walks the Bitrix24 cursor: lastId and lastType are sent together. To read the unread counter without pulling a page, call with limit=1.
The feed belongs to the token owner — the operation has no parameter selecting whose inbox to read, so a personal key returns its own owner's feed, while a given employee's feed requires an OAuth application key with an Authorization: Bearer header. The feed is not filtered by application: it also carries other applications' notifications and the Bitrix24 account's own system ones, so pick yours by notifyTag or notifyModule.
NEW-0814-8: Workday history in the V1 API
A new endpoint is available — GET /v1/workday/records returns one employee's workday history over a period. It reports the start and end of the day, seconds worked, break length and the approval flag, so lateness and overtime reports can be built through the Vibecode API without a separate integration with the account's time tracking.
userId is mandatory: the Bitrix24 account refuses the call without it. The period is set by the optional from and to in ISO-8601 with an explicit timezone offset or Z; with no period given, the last 7 days are returned. A bare date is rejected — a workday boundary depends on the timezone, and silently widening it to UTC would reclassify the very lateness the endpoint exists to report.
A single request returns at most 50 records; page deeper with offset or page. meta.hasMore signals a continuation. The meta.total field is present only when the page came back shorter than the requested limit: the size of the selection is known exactly in that case, whereas on a full page it is not, and no invented number is put there.
The scope is unchanged — timeman. Rights to read another employee's records are decided by the Bitrix24 account: they belong to an administrator or the employee's direct manager.
FIX-0814-9: the INT_VIBE_PLUS_REQUIRED refusal now points at the plan page inside the account
Before
For the INT_VIBE_PLUS_REQUIRED code, details.upgradeUrl and alternatives[0].url carried the generic Bitrix24 pricing page. A Vibe+ plan is enabled inside the account itself, so that page did not show what to actually do.
After
Both fields now carry an address on the customer account that opens the explanation for the required plan: https://<account domain>/online/?feature_promoter=limit_why_pay_tariff_vibe. The servers.create slot of GET /v1/me returns the same address — it used to disagree with the refusal body.
When the account domain cannot be recognised, both fields still carry the generic pricing page: no broken address is ever returned.
Impact on integrators
Nothing to change. The response shape is unchanged and both fields remain address strings. A client that sent the user to details.upgradeUrl now lands them on the plan they need instead of a generic price list. The refusal code, the field set and the response status are unchanged.
BC-0814-10: audio transcription accepts the file only in the file field, never truncates it silently, and returns a recognition refusal as 400
Old format supported until: not provided
Before
POST /v1/audio/transcriptions took the first multipart file part regardless of its field name and did not check the filename extension: an unknown extension was labelled audio/mpeg and forwarded for recognition. A file over the 25 MB limit was not rejected but silently cut at the limit: the answer was 200 with a transcript of only the beginning of the recording, and it was billed — nothing in the response indicated the cut. Any non-2xx from the recognition service came back as 502 ai_provider_unavailable, including a rejection of the request body.
After
The file part must be named file, otherwise 400 no_file — whatever the size of the file sent. That check runs before the recognition call. The filename extension is NOT checked: the recognition service detects the container from the content, so rare voice-recorder formats, a name without an extension and a part with no name are accepted exactly as before. A file the recognition service could not read comes back as 400 ai_provider_rejected. A file over 25 MB is rejected outright — 413 request_too_large, nothing charged; a truncated transcript no longer happens. A recognition refusal with HTTP 400 or 422 is returned as 400 ai_provider_rejected with a providerStatusCode field; rate limiting on its side is returned as 429 rate_limit_exceeded with a Retry-After header; unavailability and authentication errors stay 502 ai_provider_unavailable.
Integrator action
Name the file part file — a previous name such as audio no longer works. Split recordings above 25 MB before sending: such a request is now rejected rather than partly transcribed. If your code branched on the status, note that a body rejection now arrives as 400 rather than 502, and retrying such a request cannot help. There is no need to change extensions: the list includes the formats that used to be accepted silently. The old behaviour is not coming back.
NEW-0814-11: catalog product image metadata
Added GET /v1/catalog-products/:productId/images for a product-scoped snapshot of native images and GET /v1/catalog-products/:productId/images/:imageId to retrieve one image. The snapshot includes the detail picture, preview picture, and MORE_PHOTO gallery, but not files stored in other custom properties. Both methods require the catalog scope, return an untrusted detailUrl, and never expose the signed downloadUrl; server-side fetching requires the platform SSRF policy. Documentation.
NEW-0814-12: audio transcription can now draw on the Cowork/Code subscription quota
Calling POST /v1/audio/transcriptions with a key carrying the vibe:cowork scope used to consume nothing: transcription was metered against the Bitrix24 account AI quota, which subscription keys skip. A platform administrator can now price the transcription model per minute of audio, and such a call draws on the subscription quota, exactly like chat does.
Until a price is set the behaviour is unchanged: the call is free and no subscription limit applies to it.
Once a price is set and the quota window is exhausted, the endpoint answers 402 with code cowork_quota_exhausted — the same code chat already returns — plus a Retry-After header holding the seconds until the window resets. The body carries window (5h / week / month), resetAt and nextTier.
Response formats that carry no duration (text, srt, vtt) are billed at the per-call price, because the audio length is not reported for them.
FIX-0814-13: a wake schedule no longer shortens the auto-sleep you set
Before
When a server carried both an auto-sleep timeout (sleepAfterMinutes — 30, 60 or 240 minutes) and an enabled wake-schedule window, the idle threshold was silently replaced with the platform's short 15-minute one. The server fell asleep after 15 minutes instead of the value it was given, while GET /v1/infra/servers/:id and the server card kept reporting the chosen value — the divergence was not visible anywhere.
After
The value you set applies as set: a schedule only decides when the server wakes up. The short threshold stays exactly where it was introduced for — a server with no auto-sleep at all (sleepAfterMinutes: null), so that it still sleeps between windows. No integration change is needed; servers holding both an auto-sleep timeout and a schedule now stay up until their own threshold.
NEW-0814-14: a write with a lossy-charset value now reports it
Before
When a title or description arrived with its non-ASCII characters already replaced by question marks, the platform stored the value silently. The catalog card then showed ????????? ????????, and the only way to notice was to look at it.
After
The value is still stored, and the response now also carries a warnings array naming the fields that arrived with no non-ASCII character left, suggesting the text be re-sent as UTF-8. This applies to POST /v1/infra/servers and PATCH /v1/infra/servers/{id} (displayName, description), POST /v1/infra/servers/{id}/deploy (displayName, description), POST /v1/apps and PATCH /v1/apps/{id} (title), POST /v1/apps/{id}/publish (catalogTitle, catalogDescription). The warning is emitted only for a field the call actually applied: re-sending the same value, or a field the deploy dropped because it was already set, stays silent. The field is optional and absent when there is nothing to report, so existing clients keep working unchanged.