For AI agents: markdown of this page — /docs-content-en/changelog/2026-07-08.md documentation index — /llms.txt
API changes: July 8, 2026
FIX-0708-1: GET /v1/doc-templates and POST /search now honour order and offset
Before
The order and offset parameters on GET /v1/doc-templates and POST /v1/doc-templates/search were silently ignored: the list always came back sorted ascending by id, and offset did not move the window. The underlying Bitrix24 method returns templates as an id-keyed object, and the requested order was lost while unwrapping the response.
After
Sorting (order[field]=asc|desc, including multi-field) and windowing (offset/limit) are applied on the Vibecode side: the full template set is fetched, sorted, and sliced to the requested window. total and hasMore are computed from the actually collected set.
Impact on integrators
If you relied on the implicit ascending-by-id order at offset=0 with no sort, nothing changes — that stays the default. POST /v1/doc-templates/batch (batch list) is unaffected. String order (name, region) is byte-wise, not locale-aware.
NEW-0708-2: GET /v1/apps/:id/sources — new linkedServerSources field
GET /v1/apps/:id/sources now additionally returns a linkedServerSources field — source versions stored under a server (via POST /v1/infra/servers/:id/sources or auto-save on deploy), grouped by server, each with its own serverContext. Such versions previously did not appear in this response when saved under a personal key — they are now visible.
The field is additive: versions, totalVersions, currentVersionId and totalSizeBytes are unchanged and still list only app-scoped versions. Alongside it come linkedServerSourcesTruncated (a truncation flag for very large histories) and linkedServerHint, which points to GET /v1/infra/servers/:serverId/sources — the authoritative full list and download for those versions. The section is populated for the app author (personal key) and the Bitrix24 account administrator; it is empty when called with an OAuth application key, and is not computed on a ?sha256= probe.
NEW-0708-3: preemptible field on the server plans list response
The GET /v1/infra/providers/:id/plans response now formally documents the preemptible field on each plan. A preemptible plan is cheaper, but the cloud force-restarts such a machine roughly once a day — it is not suitable for continuous 24/7 workloads. For a server, agent or bot that must run without interruption, pick a non-preemptible plan (preemptible is false or absent).
The field was already returned by the runtime — this entry formalizes it in OpenAPI and the docs; no change to existing integrations is required.
NEW-0708-4: GET /v1/models/:id now reports a retired model's successor price and a replaced_by field
For a model that has been retired, the by-id detail request now returns a replaced_by field with the identifier of the successor model that actually serves the calls, and the pricing field shows that successor's price — the price the request is billed at. Previously pricing showed the retired row's own zero price, making the model look free while a paid successor served the calls. Ordinary models and existing calls are unchanged.
FIX-0708-5: list auto-pagination preserves row order for limits above 550
Before
Auto-paginated list reads — GET /v1/{entity}?limit=… and POST /v1/{entity}/search — returned rows out of order when limit exceeded ~550: internal result pages were merged in the wrong sequence relative to what Bitrix24 returned, so the order parameter was not honored across the final array. When the collection held more rows than limit, the window trim could drop rows from the middle of the sorted set while keeping later ones.
After
Pages are merged strictly in Bitrix24 return order: rows arrive in the requested sort for any limit, and the limit trim no longer drops rows from the middle of the set because of wrong merge order.
Impact on integrators
No changes required. If you re-sorted large result sets on your side as a workaround, that is no longer needed.
FIX-0708-6: auto-pagination no longer silently drops a page when a batch sub-request fails
Before
With limit > 50 the list is assembled from batch sub-requests of 50 records each. If Bitrix24 rejected one sub-request (most often on its request limit — QUERY_LIMIT_EXCEEDED), that page silently fell out of the middle of the set: the response stayed 200 with an undetectable 50-record hole in the data (e.g. records 1–200 and 251–600 without 201–250), while meta.total and meta.hasMore looked self-consistent.
After
For lists, plain search, batch sub-calls and aggregations the result is always a contiguous prefix of the set: records past the failed page are dropped, meta.hasMore stays true, and the response carries meta.pageErrorSample { code, message } with the failure reason — mirroring windowed search's meta.windowErrorSample. The field is added to list responses (e.g. GET /v1/deals), to POST /v1/{entity}/search (e.g. deals), to per-sub-call meta of POST /v1/batch and to data.meta of POST /v1/{entity}/aggregate (where it explains why recordsProcessed is below totalRecords). In windowed search (a wide date range) the set is assembled from windows, so a page lost inside one window can leave that window's tail missing — there the incompleteness signal is meta.pageErrorSample itself, not meta.hasMore. In all cases the field appears only when the returned page is actually shorter than limit: a full page is never flagged with a false alarm. Incomplete responses are never cached: a retry goes straight to Bitrix24.
Impact on integrators
No client changes required: result sets that could previously contain an invisible hole are now correct, and the shortfall reason is visible in meta.pageErrorSample. Fetch the remainder by retrying with offset equal to your original offset plus the number of records received — except for windowed searches over a wide date range (offset is not supported there: narrow the range or retry later).
BC-0708-7: structured output: a truncated or empty result now returns 422 instead of an empty 200
Old format supported until: 08.07.2026
Before
POST /v1/chat/completions with response_format (json_object or json_schema) could return 200 with content: null (or a truncated, unparseable JSON string) plus a warning that clients ignored, when generation was cut off. This happened most often on reasoning models: the reasoning phase consumed the whole max_tokens budget before the model produced the JSON. The response looked successful but could not be parsed.
After
Such a request now returns 422 with code: "structured_output_truncated", plus finishReason, suggestedMaxTokens (a larger max_tokens to retry with), and param: "max_tokens". In streaming mode a {"error":{"code":"structured_output_truncated"}} frame is emitted before data: [DONE] — read the stream through to [DONE]. Additionally, for free reasoning models given a too-small max_tokens the platform raises the budget to a safe minimum and tags the successful response with a MAX_TOKENS_RAISED warning. The truncated attempt still consumes and bills tokens.
What integrators should do
Handle 422 structured_output_truncated in your error branch and retry with a larger max_tokens (you can use the suggestedMaxTokens value). For strictly deterministic JSON, set a generous max_tokens or use a non-reasoning model.