Für KI-Agenten: Markdown dieser Seite — /docs-content-en/errors/auth.md Dokumentationsindex — /llms.txt

Dokumentationsartikel sind derzeit auf Englisch verfügbar.

Authorization, keys and permissions

A detailed breakdown of the codes the Vibecode API returns when a key is not recognized, lacks the required permissions, or runs in read-only mode.

The summary table of all Vibecode API codes — Error codes.

`MISSING_API_KEY` (401)

The request carries no X-Api-Key header.

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_API_KEY",
    "message": "API key required. Pass via X-Api-Key header."
  }
}

Causes:

  • The X-Api-Key or Authorization header was not passed.
  • The header was passed with an empty value.

Fix:

  • Add the X-Api-Key: vibe_api_... or X-Api-Key: vibe_app_... header.
  • Verify that the environment variable holding the key is set correctly (for CLI tools and SDKs).

`INVALID_API_KEY` (401)

The platform found no such key string: the value passed matches none of the issued keys.

This code does not mean your key stopped working. A key that exists but is rejected returns a different code: revoked or blocked — KEY_INACTIVE, expired — KEY_EXPIRED, with credentials the Bitrix24 account rejects — PORTAL_CREDENTIALS_REJECTED. Those states call for different steps, so start from the code in the response. Code summary — Errors, key states and how to tell them apart — Keys and authorization.

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API key"
  }
}

Causes:

  • A typo or extra whitespace in the key.
  • The value was truncated while copying it or moving it into an environment variable.
  • The key is from a different environment — staging instead of production or the other way around.
  • The key was deleted by its owner or an administrator.
  • The prefix is not among the supported ones: vibe_api_, vibe_app_, vibe_live_.

Fix — in this order:

  1. Check the string the client actually sends: extra whitespace and line breaks, a truncated value, a key from another environment. Re-issuing does not fix a string mangled in transit.
  2. Find the key on the page for its type: a personal key (vibe_api_) on API Keys, an application auth key (vibe_app_) in the application card under Applications — or under Auth Keys when the application has no card in that section — a management key (vibe_live_) on Management Keys. The API Keys section lists personal keys only, so a missing application or management key there does not mean it was deleted.
  3. Create a new key — only if the key really was deleted. A key that is present on its own page and travels to the platform intact does not return this code, and a new key changes nothing.

`TOKEN_MISSING` (401)

The key carries no Bitrix24 credentials, so there is no way to call Bitrix24. The cause depends on the key type — these are two different scenarios.

A personal key (vibe_api_*) reaches Bitrix24 through a webhook. When the key has no webhook, the response on entity calls (/v1/{entity} and POST /v1/batch) carries a machine-readable reason in error.details. Other routes return the same code without details:

JSON
{
  "success": false,
  "error": {
    "code": "TOKEN_MISSING",
    "message": "This personal API key (vibe_api_*) has no Bitrix24 webhook credentials, ...",
    "details": {
      "reason": "INT_TARIFF_REQUIRED",
      "paywallCode": "INT_TARIFF_REQUIRED"
    }
  }
}

Values of details.reason:

Reason What it means What to do
INT_TARIFF_REQUIRED The Bitrix24 account is on a free plan Upgrade to a commercial plan, then reconnect the key
VIBE_SCOPES_ONLY The key requested no Bitrix24 scope at all — by design it gets no webhook Create a key with the Bitrix24 scopes you need
WEBHOOK_NOT_CONFIGURED Bitrix24 access is fine or undetermined, and the key carries no webhook Reconnect the key. When details.hint is present, re-check via GET /v1/me?refresh=tariff
WEBHOOK_MINT_REFUSED_BY_PORTAL Bitrix24 refused the key owner the right to create incoming webhooks — that right is denied by default and a regular employee cannot grant it to themselves A portal administrator must grant the right to create incoming webhooks; the platform then mints the webhook on its own within 15 minutes, no reconnect needed. More — Creation rights
WEBHOOK_MINT_FAILED The last webhook-mint attempt failed for an unrecognized reason No action needed — the platform retries automatically; check again via GET /v1/me?refresh=tariff

ReconnectingPOST /api/keys/:id/reconnect: issues a webhook for the key without changing the key string (no integration has to be reconfigured) and clears the auto-disable on linked bots. Not applicable to app keys, system-managed keys, or keys with no Bitrix24 scopes — those still need a new key.

Important: reconnecting is NOT available for every key: the platform refuses it with 400 RECONNECT_NOT_APPLICABLE for app keys, keys with a system-managed purpose (including the Cowork key), keys linked to a server, to a live agent or to a live managed bot, and keys with no Bitrix24 scopes. For these keys the error message does not offer reconnecting at all — the cause has to be resolved on the Bitrix24 account, and the platform then mints the webhook on its own.

paywallCode arrives only for the plan-related reason and repeats it. The upgradeUrl field — a link to the upgrade page in the Bitrix24 account — never comes with INT_TARIFF_REQUIRED.

The same condition also blocks app installation and placement binding — there it arrives as a standalone 403 code, covered in Billing and plans.

An app key (vibe_app_*) keeps the Bitrix24 tokens in a per-user session, not on the key. For a call with X-Api-Key alone and no Authorization: Bearer <session token>, TOKEN_MISSING is the correct answer — this branch carries no details, and message describes the missing OAuth step. Full flow — Keys and authorization.

How to check a key's state up front: GET /v1/me for a personal key returns a b24Credentials block (ready, and when ready: false the same reason plus actions), and GET /v1/keys returns a b24Ready flag on every key. The /v1/me response is cached for 30 seconds, so right after fixing the Bitrix24 side, request it as GET /v1/me?refresh=tariff — otherwise the previous state is returned for up to half a minute. GET /v1/keys is not cached.


`PORTAL_CREDENTIALS_REJECTED` (401)

Bitrix24 rejected the credentials the platform uses to call it on behalf of this key. The difference from TOKEN_MISSING: there the key has no credentials at all, here it has them but the account no longer accepts them — the webhook was revoked, deleted on the Bitrix24 side, or became invalid along with the owner's rights.

JSON
{
  "success": false,
  "error": {
    "code": "PORTAL_CREDENTIALS_REJECTED",
    "message": "Bitrix24 rejected the credentials this key calls the portal with",
    "hint": "The portal no longer accepts the webhook or token behind this key. Reconnect the key to the portal (or re-issue it) — Retrying will not help until the credentials are restored."
  }
}

Retrying does not help: until the credentials are restored, every call this key makes is refused the same way. The code arrives on any route that reads account data, and in a POST /v1/batch sub-error.

What to do: reconnect the key — POST /api/keys/:id/reconnect — or, when reconnection does not apply to the key, create a new one. The restrictions on reconnecting are the same as for TOKEN_MISSING above.

How to tell it from a permissions refusal: insufficient permissions arrive as SCOPE_DENIED (403) and BITRIX_ACCESS_DENIED (403) — there the credentials were accepted but the operation is not permitted. PORTAL_CREDENTIALS_REJECTED means the account did not recognize the credentials themselves, and no permission setting changes that.


`PORTAL_ADDRESS_CHANGED` (409)

The self-hosted portal moved to a new address, while the key's webhook is still issued for the previous one. The platform does not send the secret where the portal no longer is, so the call is refused before reaching the portal. The difference from PORTAL_CREDENTIALS_REJECTED: there the portal itself rejected the credentials, here the request never reaches the portal — the address the webhook is issued for is no longer the portal's address.

JSON
{
  "success": false,
  "error": {
    "code": "PORTAL_ADDRESS_CHANGED",
    "message": "Portal address changed: this credential is issued for the portal's previous address. Re-issue the key webhook to continue"
  }
}

Retrying does not help: while the webhook is issued for the previous address, every call this key makes to the portal is refused the same way.

What to do: reconnect the key — POST /api/keys/:id/reconnect. The platform re-issues the webhook for the portal's current address, the key string and its rights stay the same, and integrations need no reconfiguration. The restrictions on reconnecting are the same as for TOKEN_MISSING above.


`SCOPE_DENIED` (403)

The key lacks the required scope for the requested operation.

JSON
{
  "success": false,
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This endpoint requires 'crm' scope"
  }
}

Causes:

  • CRM entities require the crm scope, tasks require task, the bot platform requires imbot, the AI Router requires vibe:ai, infrastructure requires vibe:infra.
  • The key's scope was narrowed at creation time.

Fix:

  • Open the key page in your Vibecode account and issue a new key with a broader scope set.
  • The full list of scopes and their purpose is on the Keys and authorization page.

A key issued through Partner Connect is a separate case. Its scope set comes from the consent page rather than from the key form, so re-issuing adds nothing: the scope has to be requested and confirmed by the user again. On the application side — tick the scope on the application card and walk the user through consent once more; the new key arrives carrying it. An application ticks vibe:ai itself, while the other platform scopes are granted by a platform administrator — the procedure is in Platform scopes. Such a key is recognizable by its name in the key list: Connect: <application name>.


`BITRIX_ACCESS_DENIED` (403)

Bitrix24 returned ACCESS_DENIED: the user or app lacks permission for the entity or operation.

JSON
{
  "success": false,
  "error": {
    "code": "BITRIX_ACCESS_DENIED",
    "message": "ACCESS_DENIED"
  }
}

Causes:

  • The user lacks permission for the entity in CRM (e.g. another user's deal with restricted visibility).
  • The scope set in the Bitrix24 account is narrower than the key's own scope set. Bitrix24 scopes are fixed for the key at issue time, so a scope added to an already issued key shows up in GET /v1/me, while the key still accesses the account's data with its original set.
  • The requested module is disabled in the Bitrix24 account (no CRM, no bot platform, and so on).

The fix depends on the key type. When the refusal comes from the scope set, error.hint names the specific case. The hint is not always present: a bare ACCESS_DENIED with no explanation from Bitrix24 may arrive without it.

  • API key (vibe_api_). The scope set the key uses to call Bitrix24 is stored on the account side, separately from the set recorded on the key itself. Reissue the key, reconnect it, or create a new one with the scope selected — editing the app's permissions in the account changes nothing in this case.
  • Authorization key (vibe_app_). Recreate the application with the required scope and complete authorization again. Reissuing the key does not grant a scope here.
  • Chat and bot methods. For these methods the refusal is not explained by scopes alone: the key owner must be an administrator of the Bitrix24 account. Issue the key under an administrator account — widening the scopes will not help here.
  • If the cause is the employee's permissions rather than the key's scopes, check the user's permissions in the Bitrix24 entity card.

For the full description of how scopes are fixed to a key, and what to do if the refusal repeats after a reissue, see Keys and authorization.


`WRITE_BLOCKED_READONLY_KEY` (403)

The key is in read-only mode (accessMode: "READONLY"), but the request performs a write. The mode, how to switch it, and the Bitrix24 account policy are described in full in Access mode.

JSON
{
  "success": false,
  "error": {
    "code": "WRITE_BLOCKED_READONLY_KEY",
    "message": "Key is in read-only mode. Switch to read+write in /keys to enable writes.",
    "details": {
      "method": "crm.item.add",
      "keyName": "MCP key",
      "currentMode": "READONLY",
      "switchUrl": "/keys"
    }
  }
}

Important: switchUrl is not a constant. The example above shows a personal key, so the path points to the keys page. The API Keys section lists personal keys only, by design, so every other kind has a different path: for a management key (vibe_live_*) it is /management-keys; for an application auth key (vibe_app_*) it is one of TWO pages — the Applications page /applications when the application has a card there, otherwise the Auth Keys page /apps. Read the value from the response instead of hardcoding one.

details fields:

Field When returned Description
method Only when proxying to Bitrix24 The Bitrix24 method name that would have been called on a successful write (e.g. crm.item.add). Not returned for management keys — the block is based on the request's HTTP method
keyName Always The key name from your Vibecode account. If the key has no name, "unnamed" is returned
currentMode Always The key's effective mode — always "READONLY" for this error
switchUrl Always The path to the page that switches the mode FOR THIS key: "/keys" for a personal key, "/management-keys" for a management key, and either "/applications" or "/apps" for an application auth key, depending on where that application's card lives. Read it from the response instead of hardcoding one

Causes:

  • An API key or authorization key (vibe_api_, vibe_app_) in READONLY mode made a call that proxies to Bitrix24 as a write operation: create, update, delete, an action on an entity.
  • A management key (vibe_live_) in READONLY mode made a request with the POST, PATCH, PUT, or DELETE HTTP method — e.g. an attempt to create a key via POST /v1/keys or delete a feedback record.

Fix:

  • The owner of a personal key (vibe_api_) should open API Keys, select "Read and write" in the Access mode block of the relevant key's card, and save. The mode takes effect on the next request — no reissue needed.
  • The owner of a management key (vibe_live_) should open Management Keys and switch the mode in the key's card. The API Keys section never lists such a key, by design, so the step above does not apply to it.
  • The owner of an application auth key (vibe_app_) should switch the mode in the Access mode block of the application card. The API Keys section never lists such a key, by design, so the step above does not apply to it. The card lives on one of two pages: Applications when the application is registered in that section, otherwise Auth Keys, where the card opens from the row menu, item "Info". Do not guess: the address of the right page always arrives in details.switchUrl — follow it instead of a hardcoded path.
  • If the toggle in the card is unavailable, the Bitrix24 account administrator has restricted the mode. Ask the administrator to lift the restriction for this key.
  • When working through an AI agent, the effective mode is returned by GET /v1/me in the data.accessMode field. If writes are needed permanently, issue a separate key in "read and write" mode.

See also