For AI agents: markdown of this page — /docs-content-en/changelog/2026-07-21.md documentation index — /llms.txt

API changes: July 21, 2026

← Changelog · July 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 400 or 422 → 400 with code ai_provider_rejected. Retrying such a request unchanged will not help;
  • a model-side rate limit (429) → 429 with a Retry-After header. Retry it after the stated delay. A streaming response cannot carry the header, so the delay arrives as a retryAfter field in the error frame;
  • a model-side timeout (408) → 503 with code ai_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.