Para agentes de IA: markdown desta página — /docs-content-en/applications.md índice da documentação — /llms.txt
Os artigos da documentação estão disponíveis atualmente em inglês.
Application catalog
This section provides the foundation for a "my applications" screen in your product: a single request returns both a person's own applications and other applications they can access. It provides two operations: listing applications and retrieving a single application card.
There is no other way to assemble that list: GET /v1/infra/servers is scoped to the calling key, so an application created in the Vibecode dashboard is not visible there. Every row also carries the state you would otherwise have to fetch separately: the server, the saved source versions, whether an operation is in flight, and a ready-made address for opening the application. The section is read-only — creating, editing and deleting applications are not part of it.
Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key | Key: an API key or an authorization key
What the selection contains | What a card carries | Identifiers | Ordering and pagination | Rate limiting | Quick start | Full example | Endpoint reference | Error codes
What the selection contains
The selection is scoped to the key owner, not to the key itself. That is the main difference from Servers: there the output is limited to the servers of the current key, so an application created in the Vibecode dashboard is not visible there — its server is bound to another key belonging to the same person. That application does appear here, and issuing a new key does not reset the list.
This section accepts a key bound to a Bitrix24 account: either an API key vibe_api_… or an authorization key vibe_app_…. It does not require a session token. With an authorization key, the selection belongs to the key owner — whoever issued the key — not the employee on whose behalf the application acts. The section requires no dedicated scope. A key that is not bound to a Bitrix24 account is rejected before reaching this section with 401 NO_PORTAL; a management key gets 403 MANAGEMENT_KEY_NO_ENTITY_ACCESS. See "Error codes" below for a full breakdown.
The scope parameter determines what is returned:
scope |
What it covers |
|---|---|
feed |
The combined list of your own applications and all other applications you can access. This is the default value |
mine |
Your own applications only |
shared |
Other applications that you can access. Besides applications shared with you personally, this includes applications without a server that are open to the whole Bitrix24 account |
Deleted applications are never returned in any scope.
The feed selection has an upper limit because its order is computed by the platform rather than the database. Therefore, total is the size of the selection, not the number of applications on the Bitrix24 account, and the list envelope indicates this with truncated. The mine and shared selections have no upper limit.
The viewerState field describes the viewer's relationship to each row: owner — the application is yours, shared — access was granted to you personally or through the server, usable — the application has no server and is open to the whole Bitrix24 account, requestable — no access. When an application has a server, its access is determined by the server policy, so an application open to everyone is returned as shared rather than usable. The section returns no separate "may I manage this" flag — it is read-only. viewerState itself distinguishes your own applications from other people's.
What a card carries
A list row and a single application card have the same shape, so a client does not need to know about two different objects. Beyond the name, description and icon, that shape carries the opening address and three blocks of state.
openUrl and openTarget together answer the question "where do I open this application?" If the application has a server with an address, openUrl returns that address and openTarget is app. In every other case, both fields are null; this is an expected result, not an error.
Both fields are also null for an application registered in one of the placements on the Bitrix24 account, meaning that it opens inside the Bitrix24 interface. The platform does not yet know the URL for opening such an application and returns null rather than inventing one. Do not substitute server.url yourself; the Application card explains why.
isEmbedded distinguishes those two cases. Both opening fields are null for an embedded application and for an application that has not yet been published, but users need different messages: "opens inside Bitrix24" versus "nowhere to open it yet". Do NOT infer embedding from the presence of a server: an embedded application with no server of its own is a normal state — it was embedded before the code was deployed — and the flag does not depend on the server. The field is returned to everyone who can see the card, not only the owner.
server is a summary of the application server: ID, state, address, resource type, and the reachable flag. It is null when there is no server or the server has been deleted. The reachable field does not answer the same question as status: status says the container is up, while reachable says it also responds over the network. The values can differ in practice: a container can be up even if its tunnel has never come up, and the application appears healthy based on status alone.
The flag already implies status === "RUNNING": it is never true in any other state, so clients do not need to combine it with status.
For an application on a shared galaxy host (server.kind: "GALAXY_APP"), the second half of the flag is determined by the HOST, not the container itself. The host provides connectivity; by design, the container has no tunnel of its own. Therefore, true means three things at once: the container is running, the host is running, and the host's tunnel is up. A newly created container that has not yet reached RUNNING (it does so only after the first source upload) is returned with reachable: false even when the host is healthy. This means "the container is not up yet", not "the host is unreachable"; this flag alone cannot distinguish the two cases, so check status.
iconUrl is a relative path without a hostname, for example /api/app-icons/7f3…?v=1755500000000, or null when the card has no icon. The icon endpoint is anonymous: the URL requires no key, has no signature, and does not expire. Join the path to your API base URL and use it directly in <img src>; there is no need to proxy it through your own server. The endpoint returns a 256×256 PNG with Cache-Control: public, max-age=300, must-revalidate and an ETag. After five minutes, the client can revalidate the cached icon with an inexpensive 304 response. The client must provide its own placeholder for null; the platform does not generate one.
sources is a summary of the saved source versions. The latestVersionId field uses the v<N> format accepted by GET /v1/infra/servers/:id/sources/:versionId/download. It is not the record's primary key: use it in the download URL to get the latest version without a separate request for the version list.
activeOperation describes the operation in flight on the server: its kind, step, and start time. null means "there is no operation with a stored record", not "nothing is happening to this application". The field tracks deployment, repair, server plan changes, and moves between galaxies. The platform does not log other actions, so they do not appear in this field. A third state is status: "unknown": the operation started, but its outcome is unknown, so waiting for it to finish is pointless.
Only users who can manage the application receive data in those last two blocks. A viewer with whom the application was merely shared gets an empty sources summary (hasVersions: false, both fields null) and activeOperation: null. The response shape does not change, so an empty summary alone does not mean "there are no versions". The three possible causes look identical from the outside: the application has no server, no versions exist, or the data is hidden because someone else owns the application.
Identifiers: what matches what
The section returns two identifiers, and both lead into other API sections — just not where the field name suggests.
server.id is the identifier used by the Servers endpoints. Use it directly in GET /v1/infra/servers/:id and in the source download path. One caveat: the format matches, but the access scope does not. That endpoint is scoped to the calling key's own servers, so a server returned by this section (which selects by key owner, not by key) may return 404 there.
The application id and the id from GET /v1/apps identify DIFFERENT entities. The former identifies an application card; the latter identifies an OAuth application registration on the Bitrix24 account, and even their formats differ. The platform links them internally, but this section deliberately does not expose that link. As a result, using an id from this section in a /v1/apps/... path returns 404, not somebody else's data.
Same concept, different names. The application name is returned here as name, while in GET /v1/apps the registration title is called title. These are independent fields on two entities: they are not synchronized and may differ, so do not copy one into the other.
Sources use two paths, and :appId in the first is not what it looks like. Use POST /v1/apps/:appId/sources to save a version, where :appId identifies the OAuth application — NOT the application in this section or the server. Reading and downloading versions use the server ID: pass server.id from this section together with sources.latestVersionId to GET /v1/infra/servers/:id/sources/:versionId/download. Both paths are current and serve different purposes; neither replaces the other.
Ordering and pagination
The complete ordering is specified here because it determines whether paginating through the list returns every application exactly once.
scope |
Order |
|---|---|
feed |
Applications you pinned → your own applications → other users' applications. Within each group, updatedAt newest first, with ties broken by id |
mine, shared |
createdAt newest first, with ties broken by id |
updatedAt changes only when the card itself is edited; a deployment does not update it. Therefore, "freshness" in the feed means "when the card was last changed", not "when the application was last deployed": an application deployed a minute ago stays exactly where it was. To determine how recent the code is, read sources.latestSavedAt.
The trailing id key is not a formality. Applications created in a batch have identical timestamps, and without a secondary key two pages from the same traversal could overlap or skip an application: the database does not guarantee order within a group of equal timestamps. The secondary key makes pagination deterministic.
Rate limiting
| Operation | Platform-wide limit |
|---|---|
GET /v1/applications |
60 requests per minute |
GET /v1/applications/:id |
120 requests per minute |
The effective limit for your key is returned in the x-ratelimit-limit header. It is lower than the platform-wide limit shown in the table because that limit is divided across replicas.
The counter is shared by all keys belonging to the same owner within a Bitrix24 account — it is not per IP address or per individual key. This matters in both directions: several keys belonging to one person share a single counter (issuing a new key does not reset the limit), while employees of the same Bitrix24 account use separate counters even when all their requests reach the internet through a single address. The list and card operations also use separate counters.
Exceeding the rate limit returns 429 with the code RATE_LIMITED and a Retry-After header containing the whole number of seconds until the window closes.
429 does not always indicate rate limiting, so branch on error.code rather than the status. Exhausting the key's daily free-call quota returns the same status with the code QUOTA_EXCEEDED, and waiting will not help — a paid plan is required. A client that presents every 429 as "too fast, please wait" will wait indefinitely when the quota is exhausted; one that presents every 429 as "quota exhausted" will mislead users during an ordinary rate spike.
Quick start
Your own applications in a single request:
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://vibecode.bitrix24.com/v1/applications?scope=mine&limit=20"
{
"success": true,
"data": [
{
"id": "cmsw806qi0000tdskiw2aegii",
"name": "Deal report",
"type": "PERSONAL",
"viewerState": "owner",
"pinned": false,
"author": { "name": "Application author" },
"isEmbedded": false,
"openUrl": "https://app-05b67cf7.vibecode.bitrix24.com",
"openTarget": "app",
"server": {
"id": "5cbb50f9-f95f-4ddf-ba3b-b771209cb6fb",
"status": "RUNNING",
"url": "https://app-05b67cf7.vibecode.bitrix24.com",
"kind": "STANDALONE",
"reachable": true,
"lastDeployedAt": "2026-08-16T19:50:41.302Z"
},
"sources": { "hasVersions": true, "latestVersionId": "v2", "latestSavedAt": "2026-08-16T19:41:18.818Z" },
"activeOperation": { "kind": "deploy", "status": "running", "step": "build", "startedAt": "2026-08-16T19:50:33.822Z" }
}
],
"total": 2,
"page": 1,
"limit": 20,
"truncated": false
}
The example shows one application and its main fields. See Application card for a full breakdown.
Full example
The script collects all your own applications page by page, shows the ones with an operation in flight, and takes the address of the latest source version from one of them.
const BASE = 'https://vibecode.bitrix24.com/v1'
const API_KEY = process.env.VIBE_API_KEY
async function api(path) {
const res = await fetch(`${BASE}${path}`, { headers: { 'X-Api-Key': API_KEY } })
const body = await res.json()
if (!res.ok) throw new Error(`${path}: ${body.error.code} — ${body.error.message}`)
return body
}
// 1. Your own catalog: walk the pages until every application is collected.
const applications = []
let page = 1
let total = 0
do {
const chunk = await api(`/applications?scope=mine&page=${page}&limit=100`)
applications.push(...chunk.data)
total = chunk.total
page += 1
} while (applications.length < total && page <= 100)
console.log(`Applications: ${applications.length} of ${total}`)
// 2. Applications with an operation in flight right now.
for (const app of applications.filter(a => a.activeOperation !== null)) {
const { kind, status, step, startedAt } = app.activeOperation
console.log(`${app.name}: ${kind} — ${status}, step ${step ?? 'not reported'}, started ${startedAt}`)
}
// 3. One application card: where to open it and the address of its latest source version.
const target = applications.find(a => a.server !== null && a.sources.hasVersions)
if (target) {
const { data: card } = await api(`/applications/${target.id}`)
console.log(`${card.name}: open at ${card.openUrl ?? 'nowhere'} (${card.openTarget ?? 'no address'})`)
console.log(`Server ${card.server.status}, answers over the network: ${card.server.reachable}`)
console.log(`Version ${card.sources.latestVersionId} saved ${card.sources.latestSavedAt}`)
console.log(`Download: ${BASE}/infra/servers/${card.server.id}/sources/${card.sources.latestVersionId}/download`)
}
Output for the Bitrix24 account used in the example:
Applications: 2 of 2
Deal report: deploy — unknown, step build, started 2026-08-16T19:50:33.822Z
Deal report: open at https://app-05b67cf7.vibecode.bitrix24.com (app)
Server RUNNING, answers over the network: true
Version v2 saved 2026-08-16T19:41:18.818Z
Download: https://vibecode.bitrix24.com/v1/infra/servers/5cbb50f9-f95f-4ddf-ba3b-b771209cb6fb/sources/v2/download
List applications
GET /v1/applications
Returns the applications in the Bitrix24 account that the key owner can see — their own, those shared by colleagues, or both. Results are paginated, and each item has the same fields as an application card.
Parameters
| Parameter | Type | Req. | Default | Description |
|---|---|---|---|---|
scope (query) |
string | no | feed |
Which applications to return: mine — your own, shared — other people's applications you can access, feed — both together. Values are case-sensitive. An empty scope= returns 400 INVALID_SCOPE, as does an unknown value; either omit the parameter or set it to one of the three values |
page (query) |
number | no | 1 |
Page number, starting from 1. Values below 1 and non-numeric values are treated as 1 |
limit (query) |
number | no | 50 |
How many applications per page, at most 100. A larger value is clamped to 100; 0 and a non-numeric value fall back to 50; a negative value becomes 1 |
To paginate, use total, page and limit from the response: request pages sequentially until the number of rows collected reaches total. A page beyond the end of the result set returns 200 with an empty data array rather than an error.
Calculate the page count from total / limit only when truncated is false. When it is true, total is not a complete count and there are no further feed pages; retrieve the remaining applications through mine and shared, which are uncapped.
Examples
curl — personal key
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://vibecode.bitrix24.com/v1/applications?scope=mine&limit=20"
curl — OAuth application
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
"https://vibecode.bitrix24.com/v1/applications?scope=mine&limit=20"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/applications?scope=mine&limit=20', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data: applications, total } = await res.json()
applications.forEach(app => {
const state = app.activeOperation
? `${app.activeOperation.kind} — ${app.activeOperation.status}`
: app.server?.status ?? 'no server'
console.log(`${app.name}: ${state}`)
})
console.log(`Showing ${applications.length} of ${total}`)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/applications?scope=mine&limit=20', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data: applications, total } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data |
array | Array of applications. Each array item has the same shape as the data object returned for a single application; its fields are described on the Application card page |
total |
number | How many applications matched the requested scope. On feed, this is the size of the result set rather than the number of applications in the Bitrix24 account — read truncated before using it to calculate the page count |
page |
number | Returned page number, already normalized to an allowed value |
limit |
number | Returned page size, already normalized to an allowed value |
truncated |
boolean | Whether the result set was truncated. This field is always present for every scope. If false, total is exact. If true, total is the size of the result set rather than the complete count, and there are no pages beyond it |
Response example
{
"success": true,
"data": [
{
"id": "cmsw806qp0001tdskzf6mitka",
"name": "Draft with no server",
"description": null,
"type": "PERSONAL",
"iconUrl": null,
"createdAt": "2026-08-16T19:51:18.817Z",
"updatedAt": "2026-08-16T19:51:18.817Z",
"viewerState": "owner",
"pinned": false,
"author": { "name": "Application author" },
"isEmbedded": true,
"openUrl": null,
"openTarget": null,
"server": null,
"sources": { "hasVersions": false, "latestVersionId": null, "latestSavedAt": null },
"activeOperation": null
},
{
"id": "cmsw806qi0000tdskiw2aegii",
"name": "Deal report",
"description": "Pipeline summary for the period",
"type": "PERSONAL",
"iconUrl": null,
"createdAt": "2026-08-16T19:51:18.810Z",
"updatedAt": "2026-08-16T19:51:18.810Z",
"viewerState": "owner",
"pinned": false,
"author": { "name": "Application author" },
"isEmbedded": false,
"openUrl": "https://app-05b67cf7.vibecode.bitrix24.com",
"openTarget": "app",
"server": {
"id": "5cbb50f9-f95f-4ddf-ba3b-b771209cb6fb",
"status": "RUNNING",
"url": "https://app-05b67cf7.vibecode.bitrix24.com",
"kind": "STANDALONE",
"reachable": true,
"lastDeployedAt": "2026-08-16T19:50:41.302Z"
},
"sources": {
"hasVersions": true,
"latestVersionId": "v2",
"latestSavedAt": "2026-08-16T19:41:18.818Z"
},
"activeOperation": {
"kind": "deploy",
"status": "running",
"step": "build",
"startedAt": "2026-08-16T19:50:33.822Z"
}
}
],
"total": 2,
"page": 1,
"limit": 50,
"truncated": false
}
Error response example
400 — the scope value is outside the allowed set:
{
"success": false,
"error": {
"code": "INVALID_SCOPE",
"message": "scope must be one of: mine, shared, feed"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_SCOPE |
The scope value is not one of mine, shared, feed. An empty value or different letter case produces the same error |
| 401 | NO_PORTAL |
The key is not linked to a portal — this is the actual response for that case |
| 403 | MANAGEMENT_KEY_NO_ENTITY_ACCESS |
A management key cannot access this endpoint; use an API key or an authorization key |
| 403 | PORTAL_KEY_REQUIRED |
Endpoint safeguard: a malformed key record with no owner. A regular key with no portal returns 401 NO_PORTAL instead |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not sent |
| 401 | INVALID_API_KEY |
Invalid or expired API key |
| 429 | RATE_LIMITED |
Rate limit exceeded. The platform-wide limit is 60 requests per minute. The effective limit for your key is returned in the x-ratelimit-limit header. It is lower than the platform-wide limit because that limit is divided across replicas. The counter is per key owner. The limit is stricter than the one for the application card: the list is intended for refreshing a screen, not polling in a loop. The Retry-After header specifies the delay in whole seconds |
| 429 | QUOTA_EXCEEDED |
The key's daily free-call quota is exhausted. Same status, different cause: waiting does not help |
The error.message text is always English and intended for logs. Build user-facing messages from error.code. See Errors for the full list of common API errors.
Known specifics
- The result set is determined by the key owner, not the key itself. Applications created in your Vibecode account are also included: their servers are linked to other keys owned by the same person, so they do not appear in
GET /v1/infra/serversbut do appear here. The reverse is also true — replace the key with a new one and the same list is returned. - Row order depends on
scopeand is fully deterministic. Onfeed, pinned applications come first, followed by your own applications and then those shared with you; within each group, applications with a newerupdatedAtcome first.mineandshareduse a single order:createdAtdescending. In both cases,idbreaks timestamp ties. This matters during pagination: applications created in a batch can have identical timestamps, and without the secondary key, pages in the same traversal could overlap or skip an application. - The
feedresult set has an upper limit, indicated bytruncated. The service computes the order for this list before pagination rather than relying on the database query, so it paginates only after sorting. Accordingly,totalreports the size of the capped result set, not the total number of applications in the Bitrix24 account. Interpret the flag carefully: it is set when the result set reaches the cap, and a single request cannot distinguish truncation from a result set that contains exactly that many applications. The platform therefore errs on the side of reporting possible truncation. You can identify a false positive by requesting the next page and receiving an empty result. A false negative would be impossible to detect, so the platform does not allow one. Onmineandshared, there is no upper limit,totalis the complete number of rows matching the filter, andtruncatedis alwaysfalse. updatedAtdoes not indicate code freshness. The field changes when the application card itself changes: after a rename, a description change, or unlinking a deleted server. Deployments do not update it, so an application deployed ten times today may still appear near the end offeed. Usesources.latestSavedAtto determine code freshness.- On
sharedandfeed, the source summary is almost always empty. Both enrichment blocks are populated only for users who manage the application, so for other people's applications,sourcesis empty andactiveOperationisnull. The row shape does not change, so the row alone cannot distinguish undisclosed data from an application with no versions. A screen that displays code status for the entire result set must account for this. - An empty
sharedresult is a valid state, not an error. A200response with an emptydataarray andtotal: 0means that no applications owned by other people are available to you. No error occurred. requestableis never returned in the list, regardless ofscope. The result set includes only applications that you own, can access through the server's access policy, have been shared with you directly, are linked to a server whose development team you belong to, or have no server and are open to the whole Bitrix24 account. Therefore, this section needs no "Request access" button, and there is nowhere to link one because the endpoint exposes no write operations. Therequestablevalue exists for completeness and appears only when access to the application card is denied: a direct request for someone else's private application returns403 FORBIDDEN.scopeandviewerStateuse different boundaries. Besides applications shared with you directly,sharedalso includes applications with no server that are open to the whole Bitrix24 account; such a row hasviewerState: "usable", not"shared". A client that filters rows byviewerState === "shared"will omit part of the result set.