[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-07-05":3,"docs-tabs-changelog\u002F2026-07-05":6},{"content":4,"lastmod":5},"# API changes: July 5, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [July 2026](\u002Fdocs\u002Fchangelog\u002F2026-07)\n\n### FIX-0705-1: Chat message send — a clear error when the text is empty\n\nThe message text goes in the `message` field. Previously a call to [POST \u002Fv1\u002Fchats\u002F{dialogId}\u002Fmessages](\u002Fdocs\u002Fchats\u002Fmessages\u002Fsend) that carried the text under an unknown field name (e.g. `{\"text\": \"hi\"}`) silently dropped that field, and Bitrix24 returned a `422 BITRIX_ERROR` about an empty message — even though content was supplied.\n\n**Before**\n\n`{\"text\": \"hi\"}` → `422 BITRIX_ERROR` about an empty message, with no hint at the cause.\n\n**After**\n\nThe same call now returns `400 MESSAGE_REQUIRED` right away and lists the unrecognized field(s), pointing at the `message` field. Empty text is still allowed together with an `attach` block (attachment-only message).\n\n**Impact on integrators**\n\nCorrect calls that use the `message` field are unchanged. The error for a wrong field name is now precise.\n\n### FIX-0705-2: API key in the Authorization: Bearer header — a clear error instead of INVALID_SESSION\n\nThe API key goes in the `X-Api-Key` header. Previously, if the key was mistakenly placed in `Authorization: Bearer` (that slot is for an OAuth application session token), the server returned `401 INVALID_SESSION`, so integrators chased an OAuth-session problem when the real cause was the wrong header.\n\n**Before**\n\nA `vibe_app_*` key in `Authorization: Bearer` → `401 INVALID_SESSION`.\n\n**After**\n\nThe same request now returns `401 WRONG_AUTH_SCHEME` with a hint: an OAuth application key (`vibe_app_*`) goes in `X-Api-Key`, and `Authorization: Bearer` carries the session token (`vibe_session_*`) from [POST \u002Fv1\u002Foauth\u002Ftoken](\u002Fdocs\u002Fkeys-auth); a client that can only send Bearer can use a personal key (`vibe_api_*`). Session tokens and personal keys in Bearer are unaffected.\n\n**Impact on integrators**\n\nCorrect calls with the key in `X-Api-Key` and the session in `Authorization: Bearer` are unchanged.\n\n### FIX-0705-3: multipart\u002Fcreate rejects XSS-prone content types for PUBLIC objects\n\n**Before**\n\nFor `PUBLIC` objects the content types `text\u002Fhtml`, `application\u002Fjavascript`, `application\u002Fx-javascript` and `image\u002Fsvg+xml` were rejected on direct and presigned uploads, but not when starting a multipart upload. Calling [POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate](\u002Fdocs\u002Fstorage) with `visibility` = `PUBLIC` and such a type created a session, and once completed the object was served inline in the browser.\n\n**After**\n\n[POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate](\u002Fdocs\u002Fstorage) with `visibility` = `PUBLIC` and an XSS-prone content type now returns `415 STORAGE_FORBIDDEN_CONTENT_TYPE`, the same as direct and presigned uploads. No multipart session is opened. `PRIVATE` objects still accept any content type.\n\n**Impact on integrators**\n\nBehavior now matches what the Storage reference documents: XSS-prone content types are not allowed for `PUBLIC` objects on any upload path. To multipart-upload such a file, use `visibility` = `PRIVATE` or a safe content type.\n\n### FIX-0705-4: binding a placement to a server's technical URL now routes through the platform handler\n\n**Before**\n\nPOST \u002Fv1\u002Fplacements\u002Fbind accepted a `handler` pointing at the app's technical Black Hole URL (app-*.vibecode…) and registered it with Bitrix24 verbatim. Bitrix24 posted the placement iframe straight to that URL, bypassing the platform: no session was minted, and on a server restricted to Bitrix24 users the placement looped on the login gate (on a public server the app returned its own 404 error).\n\n**After**\n\nSuch a `handler` is automatically rewritten to the app's platform handler (\u002Fv1\u002Fbitrix-handler) — the placement opens and authenticates normally. The response gains `handlerRewritten: true` and `requestedHandler` with the original value. External (non-Black Hole) handlers are left unchanged. If the app's platform handler cannot be resolved, the bind is rejected with code `PLATFORM_HANDLER_UNRESOLVABLE` instead of registering an unusable URL. Additionally GET \u002Fv1\u002Fplacements flags an already-misbound handler: `data.handlers[].misbound: true` plus a textual `warnings[]`.\n\nAdditionally, if the placement is already registered in Bitrix24 but missing from the app's list (drift — e.g. after an unpublish that didn't unbind on Bitrix24), the bind no longer fails with \"Handler already binded\": the platform clears the stale binding and retries the request once, healing the drift. If the bind fails for another reason (for example a commercial Bitrix24 plan is required), the working placement is left in place.\n\n### NEW-0705-5: New 402 error code ai_quota_exhausted on AI endpoints\n\nWhen the account monthly AI quota control is active, [POST \u002Fv1\u002Fchat\u002Fcompletions](\u002Fdocs\u002Fai\u002Fchat\u002Fcompletions), [POST \u002Fv1\u002Fembeddings](\u002Fdocs\u002Fai\u002Fembeddings) and [POST \u002Fv1\u002Faudio\u002Ftranscriptions](\u002Fdocs\u002Fai\u002Faudio\u002Ftranscriptions) may return 402 with `{ success: false, error: { code: \"ai_quota_exhausted\", type: \"insufficient_quota\", reason, resetAt? } }`. The `reason` field distinguishes three cases: `breaker` — the hourly over-quota spending limiter fired, `wallet_empty` — the quota is exhausted and the account balance has no funds, `wallet_off` — over-quota usage is not available for this account. `resetAt` is when requests will pass again (may be absent for a permanently disabled account). While the account quota is not exhausted, endpoint behavior is unchanged.\n",null,{},1794739469572]