For AI agents: markdown of this page — /docs-content-en/changelog/2026-09-14.md documentation index — /llms.txt
API changes: September 14, 2026
BC-0914-1: channel recovery may refuse to protect a running operation
Old format supported until: not provided
Before
POST /v1/infra/servers/:id/unstick without force could interrupt a long-running operation that the pre-reset check did not detect.
After
The method checks server activity more thoroughly. It returns 409 OPERATION_IN_PROGRESS when an operation lock is detected, or 503 LOCK_STATE_UNAVAILABLE if the check is unavailable. Neither response resets the channel. force=true or force=1 still allows an intentional interruption.
What integrators should do
Handle both refusals. On 409 OPERATION_IN_PROGRESS, check the operation's state and wait for it to finish. On 503 LOCK_STATE_UNAVAILABLE, retry later. Add force=true or force=1 only after a deliberate decision to interrupt the operation, never as an automatic retry after a refusal.
BC-0914-2: storage object delete and list received a per-account request limit
Old format supported until: not provided
Before
DELETE /v1/storage/objects/{key} and GET /v1/storage/objects accepted requests with no
frequency limit. A client repeating the same call in a loop could sustain thousands of
requests per minute for hours, slowing the API down for every Bitrix24 account on the same site. A
HEAD request to the object list was served as a full GET: the whole set was read and
only the headers were returned.
After
Each of the two operations carries a limit of 600 requests per minute per Bitrix24 account; all
API keys of one account share one limit, and it is counted separately for each of the two
operations. Take the value actually in force from the X-RateLimit-Limit response header
rather than from the number in this text: it can turn out to be lower. Over the limit the
Vibecode API
answers 429 RATE_LIMITED with the X-RateLimit-Remaining, X-RateLimit-Reset and
Retry-After headers; the delay is not in the response body — take it from the header. The
HEAD method on the list address is no longer served — use GET with limit=1 instead.
Successful responses of both operations, their status codes and data format are unchanged,
and the behaviour of every other storage method is unchanged.
What integrators should do
- Handle
429on delete and list. Both operations received a limit they did not have. If your code deletes objects in bulk or in a loop, or re-reads the list often, add handling for429 RATE_LIMITEDwith a pause based on theRetry-Afterheader. The budget is shared by the account, so issuing a second key does not widen it. - Do not hard-code the ceiling. Read
X-RateLimit-Limitfrom the response. - Replace
HEADon the list withGET /v1/storage/objects?limit=1. - Check your retry loop. Deleting an already deleted object answers
410 STORAGE_OBJECT_DELETED— that means the object is gone, not that the operation should be repeated. Code that retries on410will now hit the limit as well.
FIX-0914-3: updating and deleting a smart process answer the Bitrix24 refusal code, not an internal error
Before
PATCH /v1/smart-processes/{id}, DELETE /v1/smart-processes/{id} and the batch update or delete via POST /v1/smart-processes/batch (action: update / delete) ask Bitrix24 for the smart process's internal id by its entityTypeId before writing. When Bitrix24 refused that request — the call limit was exceeded, Bitrix24 was unavailable or did not answer in time — the client got the code INTERNAL_ERROR with a status repeating the Bitrix24 one (429, 502, 503 or 504) and no Retry-After header. The same Bitrix24 refusal one step later in the same operations arrived as 429 RATE_LIMITED, 502 BITRIX_UNAVAILABLE or 503 BITRIX_TIMEOUT — a client that retries on those codes did not retry on INTERNAL_ERROR.
After
A Bitrix24 refusal at this step answers the same way as on any other call to Bitrix24: 429 RATE_LIMITED (including the limit Bitrix24 sends with status 503) and 503 BITRIX_TIMEOUT — with a Retry-After header, 502 BITRIX_UNAVAILABLE — without one. On such a refusal the write is not sent to Bitrix24. The successful response remains 200 (204 for DELETE /v1/smart-processes/{id}). 404 SMART_PROCESS_NOT_FOUND for an entityTypeId Bitrix24 does not know and 400 for an entityTypeId that is not a positive integer (INVALID_ENTITY_TYPE_ID on the single-record operations, BATCH_ITEM_VALIDATION on the batch) are unchanged. Code details — on the Errors page.
NEW-0914-4: creating a lead now warns when Bitrix24 converted it by itself
On a Bitrix24 account running CRM in simple mode (no leads) Bitrix24 converts the lead right on creation: it comes back CONVERTED and closed, with a contact and a deal created from it that the request never asked for — the requested stage is not kept. Vibecode changes nothing in the request: this is Bitrix24's own behaviour. POST /v1/leads now adds a LEAD_AUTO_CONVERTED warning to meta.warnings in that case, with the ids of the contact (contactId) and deal (dealId) Bitrix24 created; null when the record was not created or not found: a contact you bound via contactId is reused by Bitrix24. The response stays 201 with the created record; a lead that stays open leaves the response unchanged. There is no warning when CONVERTED was requested explicitly.
BC-0914-5: access-policy refusal identifies the required key
Old format supported until: not provided
Before
PATCH /v1/infra/servers/:id/access-policy returned 404 NOT_FOUND when a key was bound to the application and server but another key managed the server.
After
The method now returns 403 SERVER_MANAGING_KEY_REQUIRED in this case and directs the caller to use the server managing key or the cabinet. Permissions are unchanged; unrelated keys still receive 404 NOT_FOUND.
What integrators should do
Handle SERVER_MANAGING_KEY_REQUIRED separately from a missing server and retry the policy change with the managing key.
BC-0914-6: company search rejects the service index and contacts support category filtering
Old format supported until: not provided
Before
Company filters using searchContent were accepted with HTTP 200 and suggested by UNKNOWN_FILTER_FIELD, although the service index is not intended for plain-text search. Contact filters using categoryId returned HTTP 400 despite Bitrix24 supporting them.
After
Company filters using searchContent return 400 UNKNOWN_FILTER_FIELD, and the field is excluded from the list of accepted filters. Reading the field and requesting it through select are unchanged. Contact filters using categoryId are accepted and listed under Also filterable in the error hint.
What integrators need to do
Replace text searches using searchContent with a title filter using $contains. The restriction also applies to requests using a prepared service index string. For contact filters, use the exact spelling categoryId, for example { "filter": { "categoryId": 0 } }.
Affected endpoints: GET /v1/companies, POST /v1/companies/search, GET /v1/contacts, POST /v1/contacts/search. These rules also apply to filters in batch requests and aggregation.
BC-0914-7: storage object listing no longer counts the full set by default
Old format supported until: not provided
Before
GET /v1/storage/objects returned a required exact total field on every page. A list with prefix was ordered by descending id, and an app key without a user token could include employees' personal objects.
After
By default, the response contains only data and cursor. The exact total field is returned only with withTotal=true. Without prefix, descending id order is preserved; with prefix, the bytewise order is ascending key and descending id. The new opaque cursor is bound to the owner, prefix, and ordering mode. An app key without a user token lists only the app's shared objects, while a key with a user token lists only the objects of the corresponding Bitrix24 employee.
What integrators need to do
Finish a walk only when cursor is null, and pass a non-null cursor without parsing or modifying it. Restart a prefixed walk that began with an old cursor by omitting the cursor. Send withTotal=true only on requests that need an exact count. Request an employee's personal objects with that employee's user token.
BC-0914-8: creating a document template from a Disk file requires the disk scope
Old format supported until: not provided
Before
POST /v1/doc-templates accepted a Disk object ID in fileId with only the documentgenerator scope and returned 201, but the created template could not generate a document: the subsequent call returned 422 BITRIX_ERROR with b24Code=FILE_NOT_PROCESSABLE.
After
The fileId variant creates a renderable document template and requires both documentgenerator and disk on the key. The file may be up to 2 MiB. The base64 .docx content variant in file does not require disk and continues to work with the documentgenerator scope.
What integrators should do
Add the disk scope to keys that create templates through fileId. Keys used with base64 file need no change.
NEW-0914-9: Vibe+ trials grant agent access on the international platform
An active Vibe+ trial grants agent and managed-bot access with one shared VM limit. Paid Vibe+ retains access. Managed bots also require the platform bot feature to be enabled. After the trial ends, access is revoked, the entity is retained, and the VM is frozen during the scheduled check. Starting, waking, rebooting, repairing, resizing or restoring a demo VM, including creating a VM from its backup, can return VIBE_DEMO_EXPIRED (HTTP 403). Other regions and existing VMs without demo provenance retain their access model.
FIX-0914-10: open line queue fields refuse clearly instead of surfacing a Bitrix24 error
Before
The field catalogue and the session-less agent discovery path both listed all 95 fields of an
open line configuration, including queue, queueFull, queueUsersFields and queueOnline.
Naming one of those four in select, filter or sort on GET /v1/openline-configs
or POST /v1/openline-configs/search travelled to Bitrix24 and
came back as the Bitrix24 answer 422 BITRIX_ERROR reading An unknown field 'QUEUE' is passed in the PARAMS field 'select' — in a spelling the client never sent, and with no hint of where
the field can actually be read.
After
Both endpoints refuse before the Bitrix24 call with 400 UNSUPPORTED_LIST_FIELD. The message
names the spelling the client sent, the position (select, filter or sort), all four fields
of the boundary and the route that does serve them — GET /v1/openline-configs/:id.
The same boundary is now stated in those fields' descriptions in GET /v1/openline-configs/fields
and in the entity section of GET /v1/guide. The field set of the list and search responses is
unchanged: those four were never in it.
Impact on integrators
No action required. A request that used to receive 422 now receives 400 carrying the address
of the working route; successful calls are untouched.
FIX-0914-11: partner NFR licenses are recognized as commercial
Before
When Bitrix24 license sources disagreed, GET /v1/me could return a free-plan value in data.tariff.code and data.tariff.isCommercial: false for a partner NFR license. Commercial capabilities were then reported as unavailable.
After
GET /v1/me recognizes this license by the nfr code, returns data.tariff.isCommercial: true, and evaluates capabilities as a commercial plan.
Impact on integrations
No client change is required. Refreshing the tariff snapshot automatically removes the incorrect restriction.
NEW-0914-13: the external application API response carries X-Vibe-Request-Id
A response from ANY /v1/applications/{id}/api/** may now carry an X-Vibe-Request-Id header
with the end-to-end identifier of the call — the same one the platform writes to its own log.
Quote its value when contacting support.
The header is present exactly when the identifier was issued, that is when the call reached
the tunnel and the tunnel answered: on the application's own response with any status it
returns, and on the 503 APP_API_UNAVAILABLE and 502 APP_API_RESPONSE_TOO_LARGE refusals
that came as the tunnel's answer, and on 502 APP_API_BAD_ENVELOPE.
The header is absent where the identifier did not exist yet or the tunnel's answer never
arrived: 401 and 403 for the key, 429 APP_API_RATE_LIMITED, 409 APP_API_NOT_ENABLED,
403 APP_API_NOT_GRANTED, 404 APP_API_APP_NOT_FOUND, 400 APP_API_BAD_PATH,
413 APP_API_PAYLOAD_TOO_LARGE, and also 504 APP_API_TIMEOUT and the
503 APP_API_UNAVAILABLE / 502 APP_API_RESPONSE_TOO_LARGE refusals the platform decided on
its own (the application is unreachable, the channel is saturated, the tunnel is silent, the
answer did not fit the cap on our side).
Hence the rule for a client: it is the presence of the header that tells them apart, not the
response code — the very same 503 APP_API_UNAVAILABLE arrives both with it and without.
The header is optional, so treat its absence as a normal case.
Everything else in the response is unchanged — the status, the body and the remaining headers are the same, and a client needs no changes.
BC-0914-14: `Idempotency-Key` on server creation now has a 15-minute replay window
Old format supported until: not provided
Before
POST /v1/infra/servers replayed a create for an Idempotency-Key indefinitely: as long as the server row existed, the same key returned 201 with the Idempotent-Replayed header no matter how much time had passed. A replay skips the creation-policy pre-check entirely — including refusals that do not depend on machine count: unsupported region, an unreadable Bitrix24 plan, a plan outside the allowed list. An account that had since lost the right to create servers still received 201 for an old key.
After
A replay is valid for 15 minutes from the moment the machine was created. Past that window the same key no longer replays: the request runs as a new create and goes through every policy check — so an account without creation rights now gets a normal refusal (402 / 403) instead of a machine.
Re-using an expired key is not possible even when the rights are fine: the key is spent and answers 409 IDEMPOTENCY_KEY_ALREADY_USED. The message says which case you are in: the server was deleted — pick a new key; the server exists — locate it with GET /v1/infra/servers first, or you will pay for a second machine next to the first.
One limitation is unchanged and unrelated to the window: a FIRST create on galaxy placement is not protected by the key — it is not reserved there at all. That is a separate known gap, present before this change too. A key already spent by an earlier standalone create is now refused on the galaxy path with 409 instead of being silently ignored.
What to do: when retrying after a long pause, check GET /v1/infra/servers first to see whether the original request already created the server, and retry only if it is not there. If you do retry blind, send THE SAME Idempotency-Key rather than a fresh one: for a standalone create it returns either the server itself or 409 IDEMPOTENCY_KEY_ALREADY_USED, whose message tells you whether the server exists or was deleted. ⚠️ On galaxy placement even that is not enough: a first create there does not reserve the key, so a retry with the same key can still produce a second resource — for galaxy the GET check is mandatory, not advisable.
FIX-0914-15: OpenAPI now separates a personal key from an OAuth application key
Before
Every operation in GET /v1/openapi.json carried a single authorization scheme, security: [{ apiKey: [] }], whose own description says the X-Api-Key header accepts a personal key (vibe_api_…), an OAuth application key (vibe_app_…) and a management key (vibe_live_…) alike. For the routes Bitrix24 ties to the APPLICATION that is untrue: the operations of the bizproc-templates, bizproc-robots and bizproc-activities entities answer a personal key with 403 OAUTH_REQUIRED, and GET /v1/triggers answers 403 BITRIX_ACCESS_DENIED. The refusal codes were already named in the spec, but the key family stayed machine-indistinguishable, so a client generated from the spec learned it only from the refusal.
After
Those operations declare an authorization requirement of their own — the pair of schemes oauthAppKey (the OAuth application key vibe_app_… in the X-Api-Key header) and oauthSession (the vibe_session_… token from POST /v1/oauth/token in the Authorization: Bearer header); both schemes sit in one requirement object, so both headers are needed on the same call. Operations a personal key may call keep the previous scheme, POST /v1/triggers/fire and GET /v1/workflows of the same bizproc scope among them. The 403 description of POST /v1/triggers/fire is corrected alongside: it claimed that firing a trigger also needs an application context, while a personal key works there.
Impact on integrators
API behaviour is unchanged: the same calls answer with the same codes as before, and the HTTP 200 response is unchanged. Only the machine contract moved, so a regenerated client asks for the app key with its session token at build time rather than at run time. GET /v1/me lists the entities in this class under api.entityApi.oauthOnlyEntities.
FIX-0914-16: native user-field names remain in narrow selections
Before
When a CRM entity was requested with select=id,UF_CRM_..., the user-field value could be absent from the response even though it was stored in Bitrix24. The rule in GET /v1/me did not explain that dynamic names are not checked as unknown schema fields.
After
A native UF_CRM_... name is translated to the spelling accepted by the selected Bitrix24 method and projects the corresponding user-field key. This includes the digit-suffixed names created by the Bitrix24 interface: in camelCase, the underscore before the digits is kept (UF_CRM_1698325419 → ufCrm_1698325419). GET /v1/me lists the dynamic and method-specific name classes that cannot be checked against the static schema; an absent such key in a narrow selection alone does not mean its stored value is empty or its spelling is valid for the method.
Impact on integrators
No request changes are required. A narrow selection using a native UF_CRM_... name now returns the stored field value; the response key continues to use the spelling accepted by the selected Bitrix24 method.
FIX-0914-17: Connect app authorization on self-hosted portals
Before
Connecting an app through Connect to a self-hosted portal without a Bitrix24.Network link stopped with PORTAL_NOT_LINKED.
After
Self-hosted portals issue keys through their portal connector or the user's developer key, without Bitrix24.Network. If the developer key is not configured, the consent screen explains what to configure. Key scopes match the user's consent. Cloud portals retain Bitrix24.Network issuance; vibe:*-only scopes require no webhook.
Impact on integrators
No changes to Connect app settings or the OAuth flow are required. A self-hosted portal user may need to configure their own developer key in Vibecode.
Affected endpoints: GET /v1/connect/authorize, POST /v1/connect/device/authorize, POST /v1/connect/token.
FIX-0914-18: the dedicated server card returns the installed runtime after a successful deploy
Before
After a successful POST /v1/infra/servers/:id/deploy with a runtime field on a dedicated server, GET /v1/infra/servers/:id returned data.runtimeId: null even though the runtime step had passed and the application responded. The documentation already promised that field to be filled, so a second deploy "to install the runtime" looked necessary even though the runtime was already in place. A galaxy application filled the same field on success.
After
After a successful deploy to a dedicated server, GET reflects the runtime from that request, for example python311. The runtime field stays optional on a dedicated server, and a request without it does not clear the previous value. A failed deploy still leaves the field empty, even when the runtime step did pass. The deploy response remains HTTP 200, the step list is unchanged, and runtimeStatus stays deprecated and empty. Values that are already empty are not backfilled by this fix — the next successful deploy carrying runtime fills them.
BC-0914-19: the chat model field no longer matches models by substring
Old format supported until: not provided
Before
POST /v1/chat/completions accepted part of an identifier in model and picked the first model in catalog order whose identifier contained that substring. A request could run and be billed on a different model than the one named, and only the model field of the response revealed the substitution.
After
model is matched against the catalog only as a whole. It takes the full identifier or the same identifier without the provider prefix: bitrixgpt-5.5 finds bitrix/bitrixgpt-5.5. A model found by its short name is flagged in the response with the X-Model-Resolved header carrying the full identifier. An identifier that is only part of a longer one, and a short name that matches several models, get 404 ai_model_not_found.
What integrators should do
Pass the full identifier from GET /v1/models in model. If responses carry the X-Model-Resolved header, replace the short name with its value.
FIX-0914-20: smart-process custom fields answer the Bitrix24 refusal code, not "not found"
Before
The five custom-field operations of a smart process — GET, POST /v1/items/{entityTypeId}/userfields and GET, PATCH, DELETE /v1/items/{entityTypeId}/userfields/{id} — ask Bitrix24 for the smart process's internal id by its entityTypeId before acting. When Bitrix24 refused that request — the call limit was exceeded, Bitrix24 was unavailable or did not answer in time — the client got 404 SMART_PROCESS_NOT_FOUND, as if the smart process did not exist. A "not found" answer is not one clients retry, and a client could conclude the smart process had been deleted and create it again.
After
A Bitrix24 refusal at this step answers the same way as on any other call to Bitrix24: 429 RATE_LIMITED (including the limit Bitrix24 sends with status 503) and 503 BITRIX_TIMEOUT — with a Retry-After header, 502 BITRIX_UNAVAILABLE — without one. On such a refusal the field request is not sent to Bitrix24. The successful response remains 200 (201 for POST, 204 with no body for DELETE). 404 SMART_PROCESS_NOT_FOUND means Bitrix24 does not know this entityTypeId or did not return its internal id — not that Bitrix24 was unavailable. The /v1/userfields/invoices alias (Smart Invoices) never asks for an internal id and is unchanged. In addition, on every operation that asks for a smart process's internal id (including PATCH, DELETE /v1/smart-processes/{id} and the batch update or delete via POST /v1/smart-processes/batch), a Bitrix24 answer with a 5xx status is no longer taken for "not found" even when its text contains such words — for example the "page not found" page served by the proxy of an unavailable on-premise portal: such an answer arrives as 502 BITRIX_UNAVAILABLE. Code details — on the Errors page.
BC-0914-21: the quote response drops Bitrix24 service fields, the contacts field is marked as not returned
Old format supported until: not provided
Before
GET /v1/quotes/{id} (and the list, search and include) returned 17 fields that are in neither the description nor the reference: Bitrix24's full-text index string searchContent (carrying the transliterated title and the responsible's name), display copies of dates (dateCreateShort, dateModifyShort, begindateShort, closedateShort), the internal codes contentType, termsType, commentsType, entityTypeId, an empty hasProducts and seven client-requisite columns clientTitle, clientAddr, clientContact, clientEmail, clientPhone, clientTpId, clientTpaId — through the API they stay empty even on a quote with a bound company and contact, and a sent value is dropped. The declared contacts field never arrived, while select=contacts was accepted and answered 200 without that key. GET /v1/invoices/{id} carried the service entityTypeId, and lastActivityTime came with a +03:00 offset while every other date of the record was in UTC.
After
Seventeen service fields of the quote are excluded from the response; the read response remains 200. The contacts field is marked in the description and the reference as not returned (notReturned): the Bitrix24 item API never returns it for quotes, the bound contacts are in contactIds; a write of contacts still answers 400 READONLY_FIELD, and select=contacts now answers 400 SELECT_FIELD_NOT_RETURNED instead of 200 without the key. On the invoice, entityTypeId is excluded from the response and lastActivityTime is declared as a read-only field returned in UTC like every other date of the record; as before, it is not accepted in filter or order, and a value sent on write — which Bitrix24 never stored — is now refused: create and update answer 400 READONLY_FIELD, import 400 IMPORT_ITEM_VALIDATION, entity batch 400 BATCH_ITEM_VALIDATION, and the global batch READONLY_FIELD under the call in data.errors.
What integrators should do
If you read the quote's service fields (searchContent, *Short, contentType, termsType, commentsType, entityTypeId, hasProducts, client*) — they are gone; run full-text search through the title filter and take the client requisites from the bound contact and company by contactId and companyId. If the quote select included contacts — remove it (in batch sub-calls too): the field was never returned, the bindings are in contactIds. If you sent the invoice's lastActivityTime — drop it from the body: Bitrix24 sets it. Sending client* on create or update is ignored by Bitrix24 as before — the platform flags it with the UNRECOGNIZED_WRITE_FIELD hint.
Affected endpoints: GET /v1/quotes/{id}, GET /v1/quotes, POST /v1/quotes/search, GET /v1/quotes/fields, GET /v1/invoices/{id}, GET /v1/invoices, POST /v1/invoices/search, GET /v1/invoices/fields, POST /v1/invoices, PATCH /v1/invoices/{id}, POST /v1/{entity}/batch, POST /v1/batch.
NEW-0914-22: reasoning from earlier responses in the chat completion history
POST /v1/chat/completions accepts the reasoning_content field on assistant messages — the model's reasoning from an earlier response, sent back into the conversation history. Some reasoning models in function-calling dialogs read the reasoning of earlier assistant turns and lose the thread between calls without it. Previously the field was silently dropped.
The field reaches the model when its owned_by in GET /v1/models is bitrix, openrouter or vibecode. It is not sent to models of OpenAI, Anthropic and other OpenAI-compatible providers: their APIs do not accept such a field. On messages with other roles the field is ignored, null is the same as omitting the field, and an empty string is accepted. A model that reads the reasoning counts it as input tokens. A non-string value or one longer than 4,000,000 characters is rejected with 400 invalid_request.
FIX-0914-23: rate limit descriptions state the platform-wide cap and point at the header with the effective value
Before
Documentation pages and the machine-readable GET /v1/openapi.json schema stated a rate limit as a single number — 60 requests per minute for POST /v1/search, 20 for POST /v1/research, 30 for POST /v1/batch, 600 and 120 for reading notifications, 120 for calendar settings, 30 for workday records, 20 for booking resources, 10 and 30 for AI provider keys, 10 for SSH access, the app icon, the port, wake schedules and Deploy API operations, 6 for force-releasing a stuck lock, 60 for polling operation status, 20 for ticket comments and 60 for the public storage link. Requests are served by several platform processes, each holding its own share of the cap, so none of those numbers ever reached the client: the x-ratelimit-limit header returned less, and a client that pinned the number from the description hit 429 earlier than expected. Partner Connect stated a single number the same way: 30 requests per minute for GET /v1/connect/authorize, 60 for POST /v1/connect/token and 60 for POST /v1/connect/revoke. The external application API (ANY /v1/applications/:id/api/*) stated a single number the same way — 120 requests per minute per key — both in the limits table on its documentation page and in the agent hints of /v1/guide and /v1/me.
After
Every such description states the number as a platform-wide total and points at the source of the effective value — the x-ratelimit-limit response header — and says that the cap is divided across platform processes. The same correction was applied to the 429 refusal descriptions in the machine-readable schema. The limit that is NOT divided and reaches the client exactly as stated is marked separately: access token minting TOKEN_MINT_RATE_LIMIT (50 per hour per API key). The Marketplace trial activation limit carries no such marker and needs none by construction: its cap is multiplied by the number of platform processes, so the client receives exactly the printed 3 per hour whatever that number is. The schema words it two ways — "3 per hour per portal" and "3 per hour per Bitrix24 account". The Partner Connect descriptions above now point at the header as well, on the documentation page and in the schema, key revocation included. The external application API received the same note, in all three places at once. One more cap that is NOT divided across processes is marked alongside them: the edge rate zone (nginx) on POST /v1/connect/token — 20 requests per minute per caller address. It counts before a request is distributed across processes, answers the RFC 6749 envelope and sets no x-ratelimit-* header, which is how that header's absence tells it apart from the route's own cap.
Impact on integrators
Endpoint behaviour did not change and the responses are the same — the description that disagreed with them was corrected. A client that read x-ratelimit-limit changes nothing. A client that pinned the number from the description in code should switch to the header: the platform-wide number is divided across processes and changes without a journal entry.
FIX-0914-24: the default reasoning step is sent to the model explicitly
Before
When a request to POST /v1/chat/completions carried none of reasoning_effort, reasoning and chat_template_kwargs, nothing was added to the call of a model with a reasoning declaration, and the model provider decided the mode. An update of the model on the provider's side could change that mode. The response's reasoning field still reported the default step from the declaration.
After
The platform sends the model the default step from the reasoning field of the GET /v1/models response explicitly, so the behavior of a request without the parameter does not depend on updates on the provider's side. An explicitly requested step still takes precedence over default. The response's reasoning field and the X-Reasoning-Applied and X-Reasoning-Native headers describe the step that was sent. Nothing changes for models with reasoning: null.
Impact on integrators
No action is needed. To enable reasoning in a request, pass reasoning_effort or the reasoning object. The model's reasoning.default shows the step applied without the parameter.
BC-0914-25: the application external API answers a timeout with 503 instead of 504
Old format supported until: not provided
Before
The application failed to answer within the overall call ceiling and ANY /v1/applications/{id}/api/** returned 504 with the code APP_API_TIMEOUT and no Retry-After header.
After
The same outcome arrives as 503 with the code APP_API_TIMEOUT and a Retry-After header in seconds. The refusal code is unchanged, so a timeout is still distinguishable from APP_API_UNAVAILABLE, which means an unreachable or saturated channel. This address no longer answers 504 at all: seeing one means it came from an intermediate node on the way to the platform, not from the platform.
What integrators should do
Move the timeout branch from the status to the refusal code: read error.code rather than 504. A client that already branches on error.code needs no change. A client that treated 503 as unconditionally retryable now gets a Retry-After on a timeout — but retrying a non-idempotent call stays risky: the application may have completed the work after the channel stopped waiting.