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

Dokumentationsartikel sind derzeit auf Englisch verfügbar.

Application external API

The external API opens the HTTP surface of an application to whoever holds a key: an automation rule in a Bitrix24 business process or another application sends a request to the platform, the platform passes it to the application and returns the response as is.

Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key | Key: an application external API key

When you need it | What to turn on | The key | Address and methods | What the application receives | What the caller gets back | Examples | API for automation rules | Limits | Errors

When you need it

The channel serves two purposes.

An automation rule in a business process calls the application. A Bitrix24 business process reaches a step where something has to be computed, checked or sent by your own code. The automation rule sends an HTTP request to the platform address, the platform delivers it to the application and returns the application's response to the automation rule.

An application calls another application. Two applications on the same Bitrix24 account do not have to negotiate network access or invent their own authentication: the calling application sends a request to the platform address with the key of the called one.

The channel does not reach inside the Bitrix24 account: it is strictly a pass-through to your code. Requests for Bitrix24 data still go through the Entity API.

What to turn on in the application

The channel works under three conditions.

  1. The "External API" switch is on in the application card. It sits in the application card on the platform and takes the values "On" and "Off". Whoever manages the application manages the switch.
  2. The application has a server. Without a server the switch cannot be turned on, and a call returns 409 APP_API_NO_SERVER.
  3. The server does not fall asleep. Auto-sleep is off and no wake windows are set. Otherwise the switch will not turn on and a call returns 409 APP_API_NOT_ALWAYS_ON. How to disable auto-sleep — Configure auto-sleep. For a galaxy application that method returns 400 GALAXY_APP_USE_GALAXY_ROUTE — its sleep timer cannot be set through the API; turn auto-sleep off in the dashboard, on the application's server card.

Important: the switch, once on, publishes the whole HTTP surface of the application to key holders. The platform filters no routes — a key holder may address any path of the application. Authenticating and authorizing its own routes is up to the application: the platform keeps the Authorization header free for that and passes it through untouched.

The switch can be turned off at any time, with no preconditions. Turning it off closes the channel for every issued key at once.

The key

The external API accepts only a key issued for this application. A personal API key and an application authorization key do not work here: they get 403 APP_API_NOT_GRANTED. The reverse holds too — an external API key opens no other platform address, and calling anything else with it returns 403 APP_API_KEY_OUT_OF_SCOPE.

Where to get one. The application card on the platform, the "External API" block, the "Get an external API key" button. The secret is shown once — the platform does not hand it out again.

Who can issue one. The application owner, or an administrator of the Bitrix24 account. In both cases the issued key belongs to the application owner, who also pays for the calls.

How many keys. Up to 10 live keys per application. Issuing an eleventh key returns 409 APP_API_KEY_LIMIT with the limit and used fields. Revoking a key frees a slot immediately. The key does not expire — it works until it is revoked, until the switch is turned off, or until the application changes owner.

Changing the application owner revokes every external API key. Once you hand an application over to someone else, issue the keys again and update them in the automation rules and in the calling applications.

The key travels in one of two headers, and they are equivalent:

X-Api-Key: YOUR_APP_EXTERNAL_API_KEY
Authorization: Bearer YOUR_APP_EXTERNAL_API_KEY

The second form is for clients that can only send Authorization. When the application needs its own Authorization header, pass the platform key in X-Api-Key — then the Authorization header reaches the application untouched.

Address and methods

METHOD https://vibecode.bitrix24.com/v1/applications/:applicationId/api/<path inside the application>

GET, POST, PUT, PATCH, DELETE and HEAD are accepted. The method reaches the application exactly as it arrived.

Parameter Type Required Description
applicationId (path) string yes Application identifier. List: GET /v1/applications
<path inside the application> (path) string no Everything after /api/ becomes the request path the application sees. An empty path means the application root. The length limit is 2048 characters
query string string no Passed to the application verbatim; the platform does not parse it

What the path check rejects. The path is checked both in its raw form and in its once-decoded form, so percent-encoding does not bypass the check. 400 APP_API_BAD_PATH is returned for:

  • a . or .. segment anywhere, including one carrying a segment parameter after a semicolon
  • a path starting with // or with /@
  • a backslash
  • an absolute URL instead of a path
  • control characters
  • malformed percent-encoding
  • characters outside the set a path may carry — encode those

Dots inside a segment are legal: /files/report..v2 goes through.

What the query check rejects. A single set of allowed characters applies — the RFC 3986 one. Inside a parameter value .., // and ; are legal, while a backslash, a space and everything outside the set must arrive percent-encoded. Otherwise the same 400 APP_API_BAD_PATH is returned.

What the application receives

The application receives the original method, the path after /api/, the query string and the request body unchanged.

To these the platform adds headers that the application cannot get from anyone else — incoming headers carrying the X-Vibe- prefix are stripped, so a caller cannot forge them.

Header What it carries
X-Vibe-Request-Id Call identifier. The platform writes the same identifier into its log — quote it when you contact support
X-Vibe-Caller-Kind Caller kind. The only value today is external-api. This is the signal by which the application tells an external call apart from a user opening it in the Bitrix24 interface
X-Vibe-Caller-Portal-Id The Bitrix24 account the key belongs to
X-Vibe-Caller-Key-Id Identifier of the key the call was made with. Useful for logging and for authorization inside the application

Important: the X-Vibe-User-Id, X-Vibe-User-Name, X-Vibe-User-Role and X-Vibe-Authorization headers do not exist on this path. They appear only when a person opens the application through the Bitrix24 interface and holds a session — What the app receives. An external call carries no session, so the user identity is unavailable to the application: the Bitrix24 account and the key are known, the employee is not. Code written against the "What the app receives" page will see an anonymous visitor on an external call — read X-Vibe-Caller-Kind and branch on it.

What is stripped from the request. The platform key (X-Api-Key), Cookie, connection-level headers, Host, Content-Length, and whole families of proxy-trust headers: X-Forwarded, X-Original, X-Rewrite, CF, Fastly. Individual names that standard libraries read the client address from are stripped too: Forwarded, X-Real-Ip, Client-Ip, X-Client-Ip, True-Client-Ip, X-Cluster-Client-Ip, Forwarded-For, Appengine-User-Ip, X-Appengine-User-Ip. On an external call the caller sets any of those itself, so the application does not receive them and cannot trust a client address on this path.

Authorization is stripped by value, not by name: the platform removes it only when it carries the platform's own key. The application's own scheme — Authorization: Bearer eyJ…, Basic, anything else — arrives unchanged.

What the caller gets back

The status and the body of the application's response are passed to the caller as is. So are the response headers, except Set-Cookie, Content-Length, the connection-level ones and headers carrying the X-Vibe- prefix — that prefix belongs to the platform in both directions.

A 3xx response is passed through as is — the platform does not follow it; the caller decides.

A platform refusal is distinguished from an application response by the X-Vibecode-Proxy-Error header. It is present on every response the platform built and absent precisely when the response came from the application. The application cannot set it — that header is stripped from the application's response.

The body of a platform refusal is the V1 envelope:

JSON
{
  "success": false,
  "error": {
    "code": "APP_API_NOT_ALWAYS_ON",
    "message": "Application API is not reachable"
  }
}

So parse the response in this order: X-Vibecode-Proxy-Error first, the status second. A 503 carrying that header is a platform refusal; a 503 without it is the application's own response.

A response with neither that header nor the V1 envelope — an HTML page with status 400 to a request carrying two Content-Length headers, for example — came from an intermediate node on the way to the platform, not from the platform and not from the application.

The X-Vibe-Request-Id header is present on the response to the caller when the call reached the application tunnel: on the application's response and on refusals returned by the tunnel itself. Refusals before the tunnel — the key, the switch, the server, the path, the body size — as well as 503 APP_API_TIMEOUT and channel saturation carry no identifier: when you contact support, quote the applicationId and the time of the call.

Field Type Description
success boolean Always false — the envelope arrives only on a platform refusal
error.code string Refusal code from the Errors table
error.message string An English explanation. Branch on error.code, not on the text

Examples

Both examples use an external API key. This address has no second authorization axis: a personal key and an application authorization key return 403 APP_API_NOT_GRANTED because they are not bound to the application.

curl — external API key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/applications/7f3a1c40-0a2e-4b5d-9c11-2f8e6d3b0a55/api/score" \
  -H "X-Api-Key: YOUR_APP_EXTERNAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dealId": 741, "amount": 125000}'

JavaScript — external API key

javascript
const res = await fetch(
  'https://vibecode.bitrix24.com/v1/applications/7f3a1c40-0a2e-4b5d-9c11-2f8e6d3b0a55/api/score',
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_EXTERNAL_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ dealId: 741, amount: 125000 }),
  },
);

if (res.headers.get('x-vibecode-proxy-error') === '1') {
  const { error } = await res.json();
  throw new Error(`the platform refused: ${error.code}`);
}

const data = await res.json();

API for automation rules

An automation rule is the most frequent caller, and it has habits of its own. An application built for automation rules follows three rules.

Accept both application/x-www-form-urlencoded and JSON. An automation rule that sends an HTTP request puts the values into form fields and assembles no JSON. An application that reads JSON only will see an empty body on such a call. Parse both content types and reduce them to one structure.

Respond with flat JSON. An automation rule puts top-level values into business process variables; nested objects and arrays are out of its reach. A response shaped {"score": 82, "verdict": "approve"} is parsed by the automation rule in full, while {"result": {"score": 82}} is not.

Serve GET /openapi.json with the schema of your routes. A schema published by the application is reachable from the outside through the same channel, at …/api/openapi.json. That is how the calling side — a person, another application or an AI agent — learns the route set and the body shapes without reading your code.

Setting up the automation rule

In a Bitrix24 business process, add the automation rule that sends an HTTP request — "Outbound webhook". Fill in three fields:

URL:     https://vibecode.bitrix24.com/v1/applications/:applicationId/api/<your-path>
Method:  POST
Header:  X-Api-Key: YOUR_APP_EXTERNAL_API_KEY

From there the automation rule substitutes deal or task field values into the body and spreads the application's response across business process variables.

Calling from another application

The calling application needs the key of the called one. Put it into the environment variables at deploy time — POST /v1/infra/servers/:id/deploy — and read it from there:

javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/applications/${process.env.PARTNER_APP_ID}/api/score`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.PARTNER_APP_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ dealId: 741 }),
  },
);

On the called side such a request differs from an automation rule's request by the value of X-Vibe-Caller-Key-Id — issue a separate key per caller and the application will tell them apart.

Limits

Limit Value
Request body 4 MiB. Above that — 413 APP_API_PAYLOAD_TOO_LARGE
Application response body 4 MiB. Above that — 502 APP_API_RESPONSE_TOO_LARGE with no Retry-After: a retry will not fix that response
Application response time 25 seconds for the application to answer. Longer — 503 APP_API_UNAVAILABLE with Retry-After. The overall call ceiling is 30 seconds; beyond it — 503 APP_API_TIMEOUT
Call rate 120 requests per minute per key. The exact value arrives in the x-ratelimit-limit header (the cap is divided across replicas). Above that — 429 APP_API_RATE_LIMITED
Concurrent calls The channel caps how many calls run at once. On saturation — 503 APP_API_UNAVAILABLE with Retry-After
Path length 2048 characters
Live keys per application 10

Move long work outside the call: accept the task, answer the automation rule right away and deliver the result by another route. Twenty-five seconds is the ceiling of the channel, not a recommendation.

Response example

The application's response is passed through as is, so the application itself defines its shape. A response from an application written to the automation rule convention:

JSON
{
  "score": 82,
  "verdict": "approve",
  "checkedAt": "2026-09-12T08:41:03Z"
}

Success is indicated by the response status and by the absence of the X-Vibecode-Proxy-Error header, not by a success field: a successful response carries no platform envelope.

Error response example

409 — the external API switch is off:

JSON
{
  "success": false,
  "error": {
    "code": "APP_API_NOT_ENABLED",
    "message": "Application API is not reachable"
  }
}

The message text is the same across the admission refusals — Application API is not reachable — for APP_API_NOT_GRANTED, APP_API_NOT_ENABLED, APP_API_NO_SERVER, APP_API_NOT_ALWAYS_ON and the server variant of APP_API_UNAVAILABLE. Tell them apart by error.code.

Errors

Every response in this table carries the X-Vibecode-Proxy-Error: 1 header.

HTTP Code Description
400 APP_API_BAD_PATH The path or the query string failed the check
401 MISSING_API_KEY The key header was not sent
401 INVALID_API_KEY The key does not exist or was revoked
402 ACCOUNT_FROZEN The application owner's account is frozen
403 APP_API_NOT_GRANTED The key was issued for another application, or is not an external API key
403 APP_API_KEY_OUT_OF_SCOPE Another platform address was called with an external API key
403 WRITE_BLOCKED_READONLY_KEY The key is in read-only mode and the call changes data
404 APP_API_APP_NOT_FOUND No application with that applicationId, or it was deleted
409 APP_API_NOT_ENABLED The application external API is off
409 APP_API_NO_SERVER The application has no server
409 APP_API_NOT_ALWAYS_ON The application server falls asleep — auto-sleep or configured wake windows
413 APP_API_PAYLOAD_TOO_LARGE The request body is over 4 MiB
429 APP_API_RATE_LIMITED The per-key call rate was exceeded
429 QUOTA_EXCEEDED The application owner's call quota is exhausted
502 APP_API_BAD_ENVELOPE The application answered outside the contract — with a 1xx status, for example
502 APP_API_RESPONSE_TOO_LARGE The application response is over 4 MiB. No Retry-After is sent
503 APP_API_UNAVAILABLE The application server is not running, the application is not answering, or the channel is saturated. Carries Retry-After in seconds
503 APP_API_TIMEOUT No response arrived within 30 seconds — the overall call ceiling. Carries Retry-After in seconds

The full list of common API errors — Errors.

Key issuance errors surface on the application card rather than at this address: 409 APP_API_KEY_LIMIT — the live-key ceiling is reached, 409 APP_API_KEY_ISSUE_CONFLICT — the application changed owner while the key was being issued.

Known specifics

  • Only 503 and 429 are worth retrying. Both carry Retry-After with a delay in seconds. A 502 is not fixed by a retry: it means the application's response does not fit the channel contract. This address never returns 504: a slow application reaches the caller as a 503 — both when the platform stops waiting for the application at the twenty-fifth second (APP_API_UNAVAILABLE) and when the call hits the thirty-second overall ceiling (APP_API_TIMEOUT). A 504 seen at this address came from an intermediate node on the way to the platform, not from the channel. A timeout does not mean the work was not done: the application may have completed it after the channel stopped waiting, so a blind retry of a non-idempotent call doubles it.
  • The cause of a 503 is identified by the code, not by the status. APP_API_TIMEOUT means exactly one thing — the application did not answer within the overall call ceiling, and the cure is to move long work outside the call. APP_API_UNAVAILABLE covers a silent tunnel, an unreachable server and a saturated channel alike: the caller cannot tell them apart; all it can do is retry after Retry-After. The cause can be established through support: with the identifier from X-Vibe-Request-Id when the response carries one, otherwise by the applicationId and the time of the call.
  • One noisy caller takes the channel from the rest. A single Bitrix24 account's share is capped, but that share is a ceiling, not a reservation. While neighbours hold the channel, a 503 reaches even a caller that has not used its own share.
  • The owner of the called application pays. Calls spend that owner's quota, and an always-on server costs money regardless of how many calls arrive. The calling side pays nothing for the channel.
  • The application path never reaches the platform log. The platform records its length, not its value, so a secret in the path does not end up in the log. That is not permission to put one there: the path is visible to the caller and to the nodes in between.

See also