For AI agents: markdown of this page — /docs-content-en/changelog/2026-07-21.md documentation index — /llms.txt
API changes: July 21, 2026
FIX-0721-1: built-in search engine name and description, cloud provider name
The public name of the platform search engine now matches the product name: GET /v1/search/providers
and /v1/me return Bitrix24 AI Search in the name field (latin locales). The provider identifier
bitrix-search is unchanged — no client action is required.
The source-citation claim was removed from the same provider's description: the capability depends on
the engine bound to your instance and is declared machine-readably in capabilities.output.citations
of the same response.
GET /v1/infra/providers on the international segment now returns the Bitrix24 Cloud brand in the
name field instead of Bitrix Cloud. The provider identifier bitrix-cloud is unchanged.
Before
"name": "Bitrix AI Search" · "description": "Platform AI search with agentic mode and source citations" · "name": "Bitrix Cloud"
After
"name": "Bitrix24 AI Search" · "description": "Platform AI search with agentic mode" · "name": "Bitrix24 Cloud"
FIX-0721-2: creating a business-process template now accepts the template file
Before
POST /v1/bizproc-templates answered 422 Incorrect field TEMPLATE_DATA! for any body — creating a template was impossible: the field holding the .bpt file content was not in the entity schema and never reached Bitrix24.
After
The templateData field (a .bpt file as a [filename, base64 content] array) is accepted and forwarded to Bitrix24, and the template is created. The field is required on create: without it the request is rejected with 400 MISSING_REQUIRED_FIELDS before Bitrix24 is called (previously the raw Incorrect field TEMPLATE_DATA! error came back). It is write-only and surfaces in the field reference at GET /v1/bizproc-templates/fields, but is not returned on reads.
NEW-0721-3: Aggregated source registry — GET /v1/me/sources
A new endpoint GET /v1/me/sources — the programmatic twin of the dashboard "Application sources" page. It returns source snapshots across every server and application the key owns (an account-admin key sees the whole account), with pagination (page/limit/search) and the standard { success, data, total, page, limit } envelope. Each row carries a drill-in pointer — listEndpoint and latestDownloadEndpoint — plus reachableViaApi and, for server rows, blackholeStatus. Unlike GET /v1/infra/servers, which is scoped to the calling key's own servers, this registry also spans a server bound to another key of the same owner.
The server-scoped source endpoints (POST /v1/infra/servers/:id/sources and the sibling list/download/tag/cleanup routes) are now documented, and the versions[].serverContext field ({ serverId, serverName, serverDisplayName, linkedApp }) is formalized in the contract.
NEW-0721-4: optional error.b24Code field in 422 BITRIX_ERROR responses
422 BITRIX_ERROR responses now include an optional error.b24Code field — the raw Bitrix24 error code for programmatic handling (for example, PERIOD_REQUIRED, INVALID_FILTER). The change is additive: existing clients that parse only error.code and error.message are not affected.
NEW-0721-5: Open Channels statistics — 6 dashboard methods
A new API section for contact-center dashboards: POST /v1/openlines/stats (period aggregates), GET /v1/openlines/operators (real-time operator load), POST /v1/openlines/sessions/search, POST /v1/openlines/sessions/stats, POST /v1/openlines/sessions/transfers, POST /v1/openlines/ratings/search. Requires the imopenlines scope and the report_open_lines plan feature (otherwise 403 B24_TARIFF_RESTRICTION).
Rolling out — the methods ship with the Bitrix24 update imopenlines 26.700.0 and are not yet available on every account. Until the update reaches your account, the methods return 422 METHOD_NOT_YET_AVAILABLE with the target version in the response — this indicates the rollout, not an integration error.
FIX-0721-6: a Bitrix24 plan refusal is returned as 403 B24_TARIFF_RESTRICTION on every endpoint
Before
A Bitrix24 refusal caused by a plan restriction arrived as 422 BITRIX_ERROR with an opaque message — there was no way to tell it apart from other Bitrix24 errors programmatically.
After
Such a refusal is returned as 403 with the B24_TARIFF_RESTRICTION code. The rule is platform-wide, not limited to Open Channels: any endpoint that calls a Bitrix24 method unavailable on the Bitrix24 account plan now answers with this code.
Impact on integrators
Clients with generic error handling keep working unchanged — the refusal is still an error, only a more precise one. If you branched on 422 specifically for plan refusals, move that branch to 403 and error.code === 'B24_TARIFF_RESTRICTION'. This code does not mean the integration is broken: the capability is not included in the Bitrix24 account plan, and retrying is pointless until the plan changes.
FIX-0721-7: Versioned deploy runtimes install the advertised version on Ubuntu 24.04
Before
The node20 runtime installed Node.js 18 (Ubuntu 24.04 has no Node 20 package), and python311 plus the RAG runtimes (node20-rag, python311-rag) failed at the install step because the packages are absent from the distribution. The GET /v1/infra/runtimes packages field advertised postgresql-14 while PostgreSQL 16 was installed.
After
node20 now installs Node.js 20 (with a major-version check), python311 installs Python 3.11, and the RAG runtimes install PostgreSQL 16 with the pgvector extension in the application database. The packages field reflects the real version (postgresql-16). Runtime identifiers and the /deploy request format are unchanged.
FIX-0721-8: server repair status is correct when polled
Before
Polling GET /v1/infra/servers/:id/repair-status on a multi-node backend could briefly return idle even while the repair was still running — when the request landed on a different serving node than the one running the repair. A client polling the status in a loop could therefore wrongly conclude the repair had finished before it even started.
After
The endpoint reliably returns the real repair progress (running / done / failed) regardless of which node the poll lands on.
Impact on integrators
The response shape is unchanged and no client action is required.
FIX-0721-9: apps on a standalone server no longer run with administrator privileges
Before
An app deployed to a standalone Black Hole server ran with administrator privileges and no isolation. Any vulnerability in the app itself (remote code execution, for example) immediately meant full control of the whole virtual machine: the server's connection keys, its service configuration and system files.
After
The app runs under a dedicated unprivileged account and sees only its own directory (extractTo, /opt/app by default), which it owns. System directories are read-only to it and privilege escalation is blocked. Ports below 1024 still work — the platform grants the specific permission needed.
Deploy commands (install, preStart) and /exec still run with administrator privileges. Nothing changed there and no sudo is needed.
No action required: if your app genuinely needs administrator privileges to start, the deploy automatically restores the previous mode, finishes successfully and adds a warning explaining why. To skip that attempt outright — relevant for nginx as the start command, MySQL over the root system socket, and Docker-driven starts — pass "hardening": "off" in the deploy body.
Two new step values appear in data.steps[]: service_user for handing the deploy directory to the unprivileged account, and hardening for the warning that the app was restored to the previous mode. Clients that switch on step names should account for them.
BC-0721-10: a broken image_url candidate no longer fails the whole request
Old format supported until: 21.01.2027
Before
A content array could carry several image_url parts. If any one of them held
something other than an image — for example a Base64-encoded HTML error page
declared as image/png — the platform forwarded it to the model unchanged. The
model could not decode it and the entire request failed with 502 and code
ai_provider_unavailable, even when the remaining images were valid.
Separately, parts with an unsupported MIME type, malformed Base64, or above the
20 MiB limit were rejected with 400 invalid_image_payload — also for the whole
request.
After
Before calling the model, the platform inspects the actual content of every
image_url part by its byte signature rather than its declared MIME type. A part
whose content is a web response (HTML, XML, JSON, an HTTP response) or does not
decode is replaced in place with the text placeholder
[image unavailable: <reason>]. The remaining images are processed normally and the
request succeeds.
Positions are preserved: the length of the content array does not change, so any
candidate numbering on your side stays correct.
Rejected parts are visible in the response — warnings gains an entry with code
IMAGE_CONTENT_REJECTED, and the X-Image-Parts-Rejected header carries their
count. For streaming responses the header arrives with the start of the stream.
400 is now returned only for structural errors: a missing url field, a string
that is neither a URL nor a data URI, an unsupported scheme, and http:// in
production.
What integrators should do
If your code relied on 400 invalid_image_payload to detect a rejected image, read
warnings or the X-Image-Parts-Rejected header instead. The request now succeeds,
and no image is dropped silently — every substitution is reflected in the response.
Model-side failures changed too. Previously any non-2xx provider response arrived as
502; now the status reflects the cause:
- a model response of
400or422→400with codeai_provider_rejected. Retrying such a request unchanged will not help; - a model-side rate limit (
429) →429with aRetry-Afterheader. Retry it after the stated delay. A streaming response cannot carry the header, so the delay arrives as aretryAfterfield in the error frame; - a model-side timeout (
408) →503with codeai_provider_timeout.
Responses 401, 403 and 5xx still arrive as 502. This affects
POST /v1/chat/completions and
POST /v1/embeddings.
Model-side errors now additionally carry a providerStatusCode field — the raw
HTTP status of the model response. It tells a model-side 429 apart from the
platform's own rate-limit 429 (which has no such field): both keep the same
rate_limit_exceeded code so SDKs retry uniformly, and the new optional field is
the distinguisher.
Data URIs may now also carry parameters between the type and ;base64 —
data:image/jpeg;name=photo.jpg;base64,... is no longer rejected.