# API changes: July 20, 2026

[← Changelog](/docs/changelog) · [July 2026](/docs/changelog/2026-07)

### NEW-0720-1: Application responses now return the publication status

Application responses — [list](/docs/apps/list), [app data](/docs/apps/get), [create](/docs/apps/create), [publish](/docs/apps/publish), and [unpublish](/docs/apps/unpublish) — now carry two new fields: `catalogStatus` (`PRIVATE` / `PUBLISHED` / `UNPUBLISHED`) and `publishedAt` (the publication date, ISO 8601, or `null`). Previously the publication status could not be read via V1 — you had to guess from the `placements` array, which is unreliable: an unpublished application may keep its previously bound codes, and `PRIVATE` and `UNPUBLISHED` are indistinguishable by `placements`. The fields are additive — existing calls keep working.

### FIX-0720-2: chat rename no longer reports a false success to a non-participant

**Before**

[PATCH /v1/chats/:chatId](/docs/chats/management/rename) called by a Bitrix24 account administrator who is not a member of the chat returned `{ "success": true, "data": true }` even though the chat title never changed: Bitrix24 answered such a call with a false success. The response gave no way to tell it apart from a real rename, so an integrator treated the operation as done. The caller could not even read that chat.

**After**

Membership is now checked before the rename. If the caller is not a member, the response is `404 CHAT_NOT_FOUND_OR_NO_ACCESS` — the same as for any other non-participant — and no rename is attempted. The false success is gone. A rename by a member who has the rights works exactly as before.

### NEW-0720-3: streaming chat-completions now ends a stalled upstream response with an explicit error

When a streaming call ([POST /v1/chat/completions](/docs/ai/chat/streaming) with `stream: true`) receives headers but the upstream model then goes silent mid-response and sends no new data for longer than the idle window, the proxy now terminates the call and emits a terminal error frame before `data: [DONE]`:

`data: {"error":{"code":"stream_idle_timeout","type":"server_error","retryable":true,"retryAfter":<seconds>}}`

Previously such a call hung indefinitely (the agent stayed in a "receiving stream response" state). The error is retryable — read the stream through to `[DONE]` and retry, honoring `retryAfter`. Normal (non-stalled) streams and reasoning models that continuously emit thinking tokens are unaffected.

### NEW-0720-4: tasks: new timeSpentInLogs field

The `timeSpentInLogs` field (actual tracked time in seconds, summed from the time-tracking log) is now declared in the tasks schema — available in `select`, filter, and sort on [GET /v1/tasks](/docs/entities/tasks/list) and `POST /v1/tasks/search`, and present in [GET /v1/tasks/fields](/docs/entities/tasks/fields).

Previously the field was returned only when `select` contained BOTH spellings at once (`timeSpentInLogs` and `TIME_SPENT_IN_LOGS`); either one alone now works. The field is read-only — recorded via the time-tracking endpoint, not via a task update.

### FIX-0720-5: GET /v1/files/:id?include=folder now returns the folder

**Before**

[GET /v1/files/:id](/docs/entities/files/get) with `?include=folder` answered `200` but without the `_included` block, even though [GET /v1/files/fields](/docs/entities/files/fields) advertised `folder` as includable — the include silently did nothing.

**After**

`?include=folder` attaches the folder under `_included.folder`, as `/fields` promises.

**Impact on integrators**

No action required. Clients reading `_included.folder` now get the object instead of nothing.

### FIX-0720-6: /v1/me: infra block now accurate for server cap, provider id, and breakdown

**Before**

`GET /v1/me` returned `infra.limits.max: 3` regardless of the enforced per-key server cap; `infra.providers` could return an internal provider id (disagreeing with `GET /v1/infra/providers`) with possible duplicates; `infra.limits.breakdown` counted managed-bot VMs under `direct` instead of `bots`.

**After**

`infra.limits.max` reflects the enforced per-key server cap; `infra.providers` returns the public provider id, consistent with `GET /v1/infra/providers`, with duplicates removed; `infra.limits.breakdown` counts bot VMs under `bots`. No integration change is needed — the values are simply correct now.

### FIX-0720-7: deal-categories: unknown filter fields are rejected, sort by id respects direction

**Before**

`GET /v1/deal-categories` with a filter on an unknown field silently returned the WHOLE pipeline table with `200` — Bitrix24 ignores unknown filter keys of the legacy method and returns the entire list. And the sort `?sort=id&order=desc` ignored the direction, always returning the same order.

**After**

A filter on an unknown or unsupported field (as well as operator prefixes `>`/`>=`/`!`/… and operator objects) is rejected before the Bitrix24 call with `400 UNSUPPORTED_FILTER`; the message lists the filterable fields (`id`, `name`, `sort`). Exact-match and `$in` filters on those fields work as before. The sort `?sort=id` now correctly respects `asc`/`desc`.

### FIX-0720-8: openline-configs: unrecognised fields in a write body no longer vanish silently

**Before**

`POST /v1/openline-configs` (and `PATCH`) silently ignored unrecognised body fields — Bitrix24 drops unknown keys of the `imopenlines.config.*` method. A body of only unknown fields then created a configuration with default values and returned `200`.

**After**

If the body has NO known field, the request is rejected with `400 VALIDATION_ERROR` before the Bitrix24 call, and the message lists the unrecognised fields. If a known field is present but some fields are unrecognised, the write proceeds as before, and the response carries `meta.warnings` listing the ignored fields (previously they disappeared without a trace). Read-only fields (`id`, `queue`, `dateCreate` and others) in a write body are now rejected with `400 READONLY_FIELD` — previously they passed as "known" and could lead to a configuration created with default values.

### FIX-0720-9: GET /v1/{entity}/fields signals partial metadata on a Bitrix24 failure

**Before**

When the dynamic field fetch to Bitrix24 (`*.fields`) failed (rate limit, `QUERY_LIMIT_EXCEEDED`, queue timeout), the endpoint silently returned 200 with only the static schema fields — many of which have no human-readable `label`. The response looked complete, so a client could not tell it apart from a correct one and built non-deterministic field mappings.

**After**

On a field-fetch failure the response is still 200 with the static fields, but now carries `meta.warnings: [{ "code": "fields_partial", "message": "..." }]` so the client can detect the incomplete set and retry. The warning is an object `{ code, message }` — the same channel and shape as `meta.warnings` on list/search, so a single `warning.code` parser works across every endpoint. The failure is now also logged on the Vibe side.
