[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-07-07":3,"docs-tabs-changelog\u002F2026-07-07":6},{"content":4,"lastmod":5},"# API changes: July 7, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [July 2026](\u002Fdocs\u002Fchangelog\u002F2026-07)\n\n### FIX-0707-1: smart-processes: linkedUserFields accepts Y\u002FN and boolean values\n\n**Before**\n\n[POST \u002Fv1\u002Fsmart-processes](\u002Fdocs\u002Fentities\u002Fsmart-processes\u002Fcreate) and [PATCH \u002Fv1\u002Fsmart-processes\u002F:entityTypeId](\u002Fdocs\u002Fentities\u002Fsmart-processes\u002Fupdate) with `linkedUserFields` only worked when the flag value was strictly `\"true\"`\u002F`\"false\"`. A value in the `\"Y\"`\u002F`\"N\"` convention (used by every other smart-process field) or a boolean `true`\u002F`false` was silently ignored: the request returned `success: true`, but the display in the user field was not enabled.\n\n**After**\n\n`linkedUserFields` values are normalized the same way as the nested `relations[].isChildrenListEnabled` flag: `true`\u002F`\"Y\"`\u002F`\"yes\"`\u002F`1` → enabled, `false`\u002F`\"N\"`\u002F`\"no\"`\u002F`0` → disabled. Existing calls with `\"true\"`\u002F`\"false\"` keep working unchanged.\n\n**Impact on integrators**\n\nNo action needed — calls that previously \"silently did nothing\" with `\"Y\"` are now applied correctly.\n\n### BC-0707-2: Order-card nested fields normalized\n\n> Old format supported until: 06.01.2027\n\n**Before**\n\n`GET \u002Fv1\u002Forders\u002F{id}` returned the nested `clients`, `payments`, `basketItems` arrays in raw Bitrix24 shape: boolean fields as `\"Y\"` and `\"N\"` strings (`payments[].paid`, `clients[].isPrimary`, `basketItems[].vatIncluded`, and others), dates inside `payments` and `basketItems` with a `+03:00` offset, and `companyId` set to `0` when no company is bound. The `accountNumber` field was silently ignored on create and update.\n\n**After**\n\nNested Y\u002FN fields now arrive as boolean (`true` or `false`); nested dates are normalized to UTC (ending in `Z`); `companyId` is `null` when no company is bound instead of `0`; `accountNumber` became read-only — sending it on create or update returns `400` with code `READONLY_FIELD`.\n\n**What integrators should do**\n\nRead nested Y\u002FN fields as boolean instead of comparing to the string `\"Y\"`; treat `null` instead of `0` as \"no company bound\"; stop sending `accountNumber` in the create and update body — the number is assigned automatically.\n\n### FIX-0707-3: The \u002Fv1\u002Fopenapi.json spec now matches actual runtime\n\n**Before**\n\nThe machine OpenAPI spec was generated from static entity metadata and drifted from real responses: no field was marked nullable, nested order-card arrays were typed as a string, list methods were missing `filter` and `select`, and operations declared only success codes and `403`.\n\n**After**\n\nThe spec now reflects the contract. Nullable fields are emitted as `type: [\"\u003Ctype>\", \"null\"]`. Object and array-of-object fields are typed honestly, including the nested `clients`, `payments`, `basketItems`, `propertyValues` of `GET \u002Fv1\u002Forders\u002F{id}`. List methods declare the `filter` and `select` query params. Operations carry the standard error codes `400`, `401`, `404`, `422` in the single `{ success:false, error:{ code, message } }` envelope. `*Input` schemas declare create-required fields. Additionally `GET \u002Fv1\u002Forders\u002Ffields` returns `clients` as an array instead of object. An SDK generated from the spec now types responses correctly.\n\n### BC-0707-4: \u002Fsearch: auto-windowed search now returns the real Bitrix24 error on total failure\n\n> Old format supported until: 07.09.2026\n\n**Before**\n\nAny failed auto-windowed `POST \u002Fv1\u002F{entity}\u002Fsearch` returned `502 { \"error\": { \"code\": \"WINDOWED_SEARCH_FAILED\" } }` with a generic \"add autoWindow:false\".\n\n**After**\n\nThe response matches the same query at a narrow range — the real code and message: a rejected filter\u002Fsort field → `400 UNKNOWN_FILTER_FIELD` \u002F `400 INVALID_PARAMS`; no access → `403`; request limit \u002F queue overload → `429` + `Retry-After`; timeout → `503`; Bitrix24 unavailable → `502 BITRIX_UNAVAILABLE`. Partial window failure (status `200`) now carries `meta.windowErrorSample` `{ code, message }`.\n\n**What integrators must do**\n\nIf you branched on `error.code === \"WINDOWED_SEARCH_FAILED\"` (e.g. to retry with `autoWindow:false`) — branch on the real codes instead. The `autoWindow:false` workaround remains; it is useful where it actually helps (the `429 QUEUE_TIMEOUT` hint names it). The total-failure response no longer carries the `meta` block (`autoWindowed`\u002F`windowCount`\u002F`windowErrors`) — the signal is now in the error code\u002Fmessage itself; `meta.windowErrorSample` remains on partial failure (status `200`).\n\n### FIX-0707-5: lists on an account without the module return 409 consistently, not 429\n\n**Before**\n\nOn an account where the Universal Lists module is disabled, calls to [\u002Fv1\u002Flists](\u002Fdocs\u002Flists) returned the clear `409 LISTS_MODULE_NOT_ENABLED` only for the first few requests. After that the built-in error-loop protection tripped and every subsequent call returned `429 ERROR_LOOP_DETECTED`, hiding the real cause (the module is not installed).\n\n**After**\n\nThe \"method unavailable on this account\" signal is no longer counted by the error-loop protection, so `lists.*` calls on a module-off account return `409 LISTS_MODULE_NOT_ENABLED` consistently no matter how many times they repeat. The response stays actionable: enable the module in the account and retry.\n\n### NEW-0707-6: error.hint on the 400 for a server create missing source and provider\u002Fplan\u002Fregion\n\n[POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate), when rejected with `400 INVALID_REQUEST` because `provider`\u002F`plan`\u002F`region` are missing (and no `source` was passed) on a galaxy-placement account, now additionally returns an `error.hint` object with `reason` (why the request was rejected on this account), `recovery` (the recommended one-shot path plus the working two-step alternative) and `example` (a paste-ready one-shot body skeleton). `error.code` and `error.message` are unchanged — the hint is strictly additive; accounts without galaxy placement get the previous response, without `hint`.\n\nThe hint is also returned on `400 RUNTIME_PARAM_REMOVED` (a create with `runtime` but no `source` on a galaxy-placement account), and a body carrying `placement: \"dedicated\"` gets a separate hint variant — for a dedicated server, keeping the intent and adding the missing `provider`\u002F`plan`\u002F`region` tuple, instead of steering the caller into a galaxy container.\n\n### FIX-0707-7: Galaxy deploy checklist in \u002Fv1\u002Fme now matches the actual contract\n\n**Before**: step 2 of `deployment.galaxyApp.checklist` instructed [POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) `{ name }` with no `source` and no `provider`\u002F`plan`\u002F`region` — that call always failed with `400 INVALID_REQUEST`. The CREATE rule did not explain that the two-step path requires the full `provider`\u002F`plan`\u002F`region` tuple, and `newAppPlacement.note` promised a dedicated standalone VM where the create actually returns a galaxy slot with `next: \"deploy\"`. The favicon guide pointed to the same broken order; the never-deployed-slot reap window was stated as \"~12-20 min\" versus the actual ~20-25.\n\n**After**: the recommended path is a single call — `POST \u002Fv1\u002Finfra\u002Fservers { name, source, runtime, start }` (omit `provider`\u002F`plan`\u002F`region`). The two-step path is documented truthfully: a create without `source` requires the full `provider`\u002F`plan`\u002F`region` tuple (values are informational for a galaxy — the app inherits its host), and on galaxy placement returns a slot with `next: \"deploy\"`; a never-deployed slot is reaped to ERROR after ~20 min (swept every 5 min). Favicon: the primary path is a self-hosted `\u002Ficon.svg` inside the archive (no id needed); the platform-hosted URL remains an alternative via the two-step order or a re-deploy. The status-polling step gained a `status=error` branch → `provisionError`\u002F`buildLog` → re-deploy.\n\n**Impact on integrators**: agents following the checklist now deploy on the first call. Endpoint behavior is unchanged — only the `\u002Fv1\u002Fme` texts and the `\u002Fv1\u002Fopenapi.json` description were updated; existing integrations keep working as is.\n\n### NEW-0707-8: Company AI quota is available via the API\n\nThe new [GET \u002Fv1\u002Fai\u002Fquota](\u002Fdocs\u002Fai\u002Fconsumption\u002Fquota) endpoint returns the monthly AI quota state of your Bitrix24 account: the percentage of the limit consumed (`pctUsed`, an honest value — above 100 on overspend), the exhaustion flag (`exhausted`), the reset date (`resetAt`, a rolling 30-day window), and a per-model breakdown — request counts, tokens, and each model's share of the monthly limit (`byModel[].pctOfLimit`). Absolute limit values in Vibe credits are not exposed — percentages only, same as the dashboard. Requires the `vibe:ai` scope.\n",null,{},1794739469841]