[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-07-16":3,"docs-tabs-changelog\u002F2026-07-16":6},{"content":4,"lastmod":5},"# API changes: July 16, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [July 2026](\u002Fdocs\u002Fchangelog\u002F2026-07)\n\n### BC-0716-1: json_object on a reasoning model recovers JSON; the 422 body is refined\n\n> Old format supported until: 15.01.2027\n\n**Before**\n\nA [POST \u002Fv1\u002Fchat\u002Fcompletions](\u002Fdocs\u002Fai\u002Fchat\u002Fcompletions) request with a `json_object` `response_format` on a reasoning model (e.g. `bitrix\u002Fbitrixgpt-5.5-agent`) consistently returned `422 structured_output_truncated`, even when the model finished on its own (`finish_reason: \"stop\"`) and placed a complete valid JSON into the service `reasoning_content` channel — the answer was lost. Every such error body carried `error.suggestedMaxTokens` and `error.param`, and the text claimed \"finish_reason=length\" regardless of the real stop reason.\n\n**After**\n\nIf a model on `json_object` finished on its own and valid JSON sits in `reasoning_content`, the platform recovers it and returns `200` with that JSON in `content` (in streaming mode — as a `content` chunk before the terminal `finish_reason` chunk). The `422` body is now truthful: `error.suggestedMaxTokens` and `error.param` are present **only** on a genuine truncation (`finish_reason: \"length\"`); on any other stop reason (`stop`, etc.) those fields are **omitted** and the text names the actual `finish_reason`. `json_schema` behaviour is unchanged — there the strict schema is enforced model-side.\n\n**What to do**\n\nNothing, if you handle `422` by `error.code`. If your code **unconditionally** reads `error.suggestedMaxTokens` or `error.param` on a `structured_output_truncated` error, make the read optional: those fields are now absent when `finish_reason !== \"length\"`. Streaming clients using `response_format` should accumulate `content` across all deltas up to `data: [DONE]`.\n\n### FIX-0716-2: env sent as a file in a multipart deploy is no longer silently ignored\n\n**Before**\n\nIn `multipart\u002Fform-data` for [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy\u002Fdeploy), an `env` field sent as a file or Blob was silently ignored — the deploy reported success but the app started without environment variables.\n\n**After**\n\nSuch a request returns 400 with code `VALIDATION_ERROR` and a hint to send `env` as a text field containing a JSON string.\n\n**Impact on integrators**\n\nThe correct approach (a text `env` field with a value like `{\"KEY\":\"value\"}`) is unaffected. Anyone who sent `env` as a file or Blob now gets an explicit error instead of a false success.\n\n### FIX-0716-3: large source.content deploys no longer fail with Gateway HTTP 413\n\n**Before**\n\nOn some accounts [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy\u002Fdeploy) with `source.content` (a base64 archive) failed at the `download` step with `{ \"code\": \"DEPLOY_FAILED\", \"message\": \"Gateway HTTP 413\", \"step\": \"download\" }` whenever the base64 body exceeded ~1 MB (about 768 KB of raw `tar.gz`) — despite the documented 500 MB limit. The workaround was uploading via `source.url`.\n\n**After**\n\nThe 500 MB inline-upload limit (`source.content` and `multipart`) applies on all accounts. `source.url` keeps working as before.\n\n### BC-0716-4: POST \u002Fv1\u002Finfra\u002Fservers rejects unknown body fields\n\n> Old format supported until: 15.01.2027\n\n**Before**\n\nAn unknown field in the request body was silently ignored. A request with `deployMode: \"STANDALONE\"` (a non-existent field) returned `201` and created a galaxy app instead of the expected dedicated server — the real field is `placement: \"dedicated\"`.\n\n**After**\n\n[POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) rejects a body that carries an unknown field with `400 UNKNOWN_PARAM`. `details.unknownFields` lists the extra fields, `details.suggestions` proposes the correct name (`deployMode` → `placement`), and `details.validParams` is the full list of accepted fields.\n\n**What integrators should do**\n\nRemove fields that are not in the create parameter list, or fix the typo using `details.suggestions`. The placement model is set via the `placement` field (`auto` by default, `dedicated` for a dedicated virtual machine).\n\n### NEW-0716-5: \u002Fv1\u002Fsites\u002Ffields now describes the allowed values of the type field\n\n`GET \u002Fv1\u002Fsites\u002Ffields` now returns the allowed values of the `type` field in `type.enum` with labels: `PAGE` (landing), `STORE` (online store), `KNOWLEDGE` (Knowledge Base 2.0), plus `VIBE` (a site from the constructor) and `SMN` (a link with the \"Site Management\" module). The `VIBE` and `SMN` values appear in responses only and are read-only — a site of that type cannot be created through the API.\n\n### NEW-0716-6: Task favorite and pin without edit permission\n\nFour new endpoints for per-user task actions that Bitrix24 allows with read access only (not edit): `POST \u002Fv1\u002Ftasks\u002F:taskId\u002Ffavorite` adds the task to favorites, `DELETE \u002Fv1\u002Ftasks\u002F:taskId\u002Ffavorite` removes it, `POST \u002Fv1\u002Ftasks\u002F:taskId\u002Fpin` pins the task in the current user's task list, and `DELETE \u002Fv1\u002Ftasks\u002F:taskId\u002Fpin` unpins it. Previously the only way to change a task was `PATCH \u002Fv1\u002Ftasks\u002F:id`, which requires edit permission and returned \"No access to edit the task\", so an allowed per-user action was unreachable.\n\n### NEW-0716-7: preemptible-plan advisory in scheduled-wake responses\n\nThe [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fwake-schedules](\u002Fdocs\u002Finfra\u002Fwake-schedules\u002Fcreate) and [PATCH \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fwake-schedules\u002F:scheduleId](\u002Fdocs\u002Finfra\u002Fwake-schedules\u002Fupdate) responses now also carry two additional top-level fields: `preemptibleAdvisoryCode` and `preemptibleAdvisory`. When the server runs on a preemptible plan, `preemptibleAdvisoryCode` is `\"PREEMPTIBLE_BEST_EFFORT\"` and `preemptibleAdvisory` is a short English explanation of the same fact: waking such a server by the window's moment is not guaranteed, and the window may be skipped when no free capacity is available. For a server on a non-preemptible plan, both fields are `null`. The advisory does not block window creation or updates — it follows the same non-blocking pattern already used by the `tzWarning`\u002F`tzWarningCode` fields. Existing integrations that don't read the new fields keep working unchanged.\n",null,{},1794739470973]