For AI agents: markdown of this page — /docs-content-en/applications/get.md documentation index — /llms.txt
Application card
GET /v1/applications/:id
Returns one application of the Bitrix24 account together with a summary of its server, saved sources and any operation in flight. The card is available to the owner and to whoever the application was shared with — personally or through the server policy. Administering the Bitrix24 account plays no part here: an administrator who neither owns the application nor was given access gets 403 FORBIDDEN like any other viewer.
Parameters
| Parameter | Type | Req. | Description |
|---|---|---|---|
id (path) |
string | yes | Application id. List: GET /v1/applications |
Examples
curl — personal key
curl -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/applications/cmsw806qi0000tdskiw2aegii
curl — OAuth application
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
https://vibecode.bitrix24.com/v1/applications/cmsw806qi0000tdskiw2aegii
JavaScript — personal key
const id = 'cmsw806qi0000tdskiw2aegii'
const res = await fetch(`https://vibecode.bitrix24.com/v1/applications/${id}`, {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data: application } = await res.json()
console.log(application.name, application.server?.status ?? 'no server')
if (application.sources.hasVersions) {
console.log('Latest version:', application.sources.latestVersionId)
}
JavaScript — OAuth application
const id = 'cmsw806qi0000tdskiw2aegii'
const res = await fetch(`https://vibecode.bitrix24.com/v1/applications/${id}`, {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data: application } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data.id |
string | Application id |
data.name |
string | Application name |
data.description |
string | null | Description. null when none was set |
data.type |
string | How the application was created: SHARED — with a server and/or an authorization key up front, PERSONAL — without them. The value is stamped at creation and never recomputed, so a PERSONAL application can own a server too |
data.iconUrl |
string | null | Host-less relative path to the icon, e.g. /api/app-icons/7f3…?v=1755500000000. The serve endpoint is anonymous: no key, no signature, no expiry — join the path with your API base URL and drop it straight into <img src>. A 256×256 PNG is returned with Cache-Control: public, max-age=300, must-revalidate and an ETag. null when the card holds no icon pointer |
data.createdAt |
string | When the application was created, ISO 8601 |
data.updatedAt |
string | When the card was last written to, ISO 8601. A deployment does not touch the card — to see how fresh the code is, read sources.latestSavedAt |
data.viewerState |
string | The viewer's relation to the application: owner — the owner, shared — access granted personally, through the server's access policy, or through being a member of that server's development team, 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 decided by the server policy, and an application open to everyone arrives as shared |
data.pinned |
boolean | Whether this viewer pinned the application |
data.author.name |
string | Display name of the application owner |
data.openUrl |
string | null | The address the application is opened at. It carries the application server address when there is one. null means "nowhere to open it" and is a normal value |
data.openTarget |
string | null | What exactly openUrl holds. Today there is a single value — app, the address of the application server. null arrives together with a null in openUrl. A value your client does not know should be read as "nowhere to open it", not as a malformed response: the set is closed but open to additions |
data.isEmbedded |
boolean | The application is embedded into the Bitrix24 interface — that is, at least one placement is bound to it. This is the only thing that tells "embedded, opens inside Bitrix24" apart from "not published yet": both arrive with openUrl and openTarget set to null. The flag does not depend on the server — an embedded application without a server of its own is a normal state. Disclosed to everyone who can see the card |
data.server |
object | null | Summary of the application server. null when there is no server, or it was deleted or torn down |
data.server.id |
string | Server id — the same id used in the Servers paths |
data.server.status |
string | Server state: PROVISIONING, RUNNING, STOPPED, SLEEPING, ERROR. Uppercase here — GET /v1/infra/servers reports the very same value for the very same server in lowercase, so normalize the case before comparing strings from the two sections. A torn-down server never appears here at all: its server is null. Read an unfamiliar value as "a state your client does not know", not as a malformed response |
data.server.url |
string | null | Application address. null until a subdomain is issued — there is no separate "has an address" flag; this check is the flag. Moving the container between galaxies does not change the address: it is derived from the subdomain, and the move does not touch the subdomain |
data.server.kind |
string | Resource type: STANDALONE — a dedicated virtual machine, GALAXY_APP — an application on a shared galaxy host |
data.server.reachable |
boolean | The server both runs and answers over the network. Not the same question as status: a container can be up while the tunnel to it has never come up at all. The flag already implies status === "RUNNING" — it never arrives true for another state, so there is nothing to conjoin. ⚠️ For kind: "GALAXY_APP" its second half is taken from the galaxy HOST rather than from the container itself; see "Known specifics" |
data.server.lastDeployedAt |
string | null | When the application was last deployed SUCCESSFULLY, ISO 8601 — the only signal in this section that an application is actually lived in, rather than merely having a server that is up. Distinct from updatedAt (which moves when the card is edited and never sees a deployment) and from sources.latestSavedAt ("code saved", not "deployed", and disclosed to the owner only). ⚠️ null does not mean "never deployed": for servers created before 2026-08-18 the field stays empty until their next deployment — the history was deliberately not reconstructed, see "Known specifics" |
data.sources |
object | Summary of the saved source versions. Filled in only for whoever manages the application |
data.sources.hasVersions |
boolean | Whether at least one saved version exists |
data.sources.latestVersionId |
string | null | Latest version in the v<N> shape — exactly the shape GET /v1/infra/servers/:id/sources/:versionId/download accepts. It is not the record's primary key, and no separate call for the version list is needed. null when there are no versions |
data.sources.latestSavedAt |
string | null | When the latest version was saved, ISO 8601 |
data.activeOperation |
object | null | Operation in flight on the server. Filled in only for whoever manages the application. The null case is covered in "Known specifics" |
data.activeOperation.kind |
string | Operation kind: deploy — deployment, repair — repair, resize — server plan change, migrate — moving a container between galaxies |
data.activeOperation.status |
string | running — the operation is in flight. unknown — the operation did start and its outcome is not known |
data.activeOperation.step |
string | null | The step the operation is on. A free-form string, not an enumeration |
data.activeOperation.startedAt |
string | When the operation started, ISO 8601 |
Response example
{
"success": true,
"data": {
"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"
}
}
}
An application with no server returns server: null, an empty sources summary and activeOperation: null. There is nowhere to open it, so openUrl and openTarget arrive null too — the application in the example is embedded in Bitrix24, which is exactly that case:
{
"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
}
}
Error response example
404 — no application with that id on the Bitrix24 account:
{
"success": false,
"error": {
"code": "APPLICATION_NOT_FOUND",
"message": "Application not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 404 | APPLICATION_NOT_FOUND |
No application with that id on the key's portal. An id from another portal and a deleted application answer the same way |
| 403 | FORBIDDEN |
The application exists, but the viewer has no access to it |
| 401 | NO_PORTAL |
The key is not bound to an account — the actual answer for this case |
| 403 | MANAGEMENT_KEY_NO_ENTITY_ACCESS |
A management key: an API key or an authorization key is required |
| 403 | PORTAL_KEY_REQUIRED |
The section's safety net: a damaged key row with no owner. The ordinary "key with no account" is 401 NO_PORTAL above |
| 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 exceeded. 120 requests per minute is the platform-wide limit; one replica's share today is 40 — read X-RateLimit-Limit from the response. The card keeps its own counter, noticeably more generous than the one for the list. A Retry-After header carries the pause 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 meant for logs rather than for people: build your interface texts from error.code. The full list of common API errors — Errors.
Known specifics
- The card is open to more than just the owner. An application shared with you personally, through the server, or through membership in its development team is readable via a direct link — the card answers with the
owner,sharedandusablestates. A viewer with no access gets403 FORBIDDEN, so the valuerequestablenever appears in a card. - An embedded application has nowhere to open, and both fields arrive
null. The platform does not yet know the address an embedded application is opened at inside the Bitrix24 account. An empty slot here is the normal answer, not a failure: an invented link would take the person somewhere else, and they could not tell that from a working one. - The server address is not substituted into
openUrl, and you must not substitute it yourself. For an embedded applicationserver.urlarrives as usual, but it is not the place to open: it serves the gateway login page with a200, so the move looks successful without being it. A client that "fixes" an emptyopenUrlby substitutingserver.urlgets exactly that silent refusal. openUrlis not suppressed when the server is unreachable. The address arrives even withserver.reachable: false. A person cannot diagnose a greyed-out button, but they can diagnose a refusal they are shown.isEmbedded, and nothing else, tells an empty open pair apart. "Embedded, opens inside Bitrix24" and "not published yet" both arrive withopenUrl: nullandopenTarget: null, yet a person must be shown different things. Do NOT infer embedding from the presence of a server: an embedded application with no server of its own is a normal state (embedded before the code was ever deployed), and conversely an embedded application WITH a server reportsserver.urlas usual while that address is not where it opens.- For an application inside a galaxy, the second half of
reachableis about the host, not the container. Withserver.kind: "GALAXY_APP"the connectivity is held by the shared galaxy host; the container itself has no tunnel of its own by design. Sotruehere means three things at once: the container runs, the host runs, and the host's tunnel is up — the flag impliesstatus === "RUNNING"and is never true without it. The consequence runs the other way: a freshly created container that has not reachedRUNNINGyet (it only does so after its first source upload) arrives withreachable: falseon a perfectly healthy host. That is "the container is not up yet", not "the host is unreachable", and the flag alone does not tell the two apart — readstatusfor that.STANDALONEhas no such split: there both facts are about one machine. lastDeployedAtfills forward, not backward. The stamp is written by the deployment itself, in the same moment it records success, so it cannot drift from the outcome: a failed deployment never moves it. But the field carries no history: for servers that existed before 2026-08-18 it stays empty until their next deployment. Reconstructing the history was only possible from the operations journal, which covers one of the three deployment paths — a date would then be present for applications on a dedicated machine and missing for applications inside a galaxy, and that emptiness would read as "galaxy applications are dead". A uniform "no deployments since" is more honest. So anullin the first weeks is normal, not a sign of an abandoned application.- A torn-down server arrives as
server: null, not as a separate status. You will not see values such asdeleted,terminated,destroyedorarchivedinserver.status— but for different reasons, and the difference is worth keeping: the last three do not exist in the platform at all, while the "torn down" state does exist and simply is not published by this section. Once a server is torn down the card returnsserver: nulloutright, together withopenUrl: null. If you normalize statuses coming fromGET /v1/infra/servers, note that its value set is different — that section reports the status in lowercase and, with theincludeDeletedparameter, shows deleted servers as well. This section has no such parameter. - An application of another Bitrix24 account is indistinguishable from a missing one. An id from another account answers
404 APPLICATION_NOT_FOUNDrather than403: the section does not even confirm that such a record exists. - The source summary and the operation in flight are filled in only for whoever manages the application. A viewer the application was merely shared with gets an empty
sourcesandactiveOperation: null, and the response shape does not change. So an empty summary on its own does not mean "there are no versions": it has three causes, identical from the outside — the application has no server, there really are no versions, or the application is someone else's and the data is not disclosed to you. A client that renders "no code" from an emptysourceswill be wrong on every application belonging to someone else. activeOperation: nulldoes not mean "nothing is happening to this application". The field is reliable only for operations with a stored record — deployment, repair, a server plan change and moving a container between galaxies. The platform does not record anything else, and such actions never surface in this field. The valueunknowninstatusis a third state: the operation did start and its outcome is not known — waiting for it to finish is pointless; re-read the state from the server itself.- Server state arrives in upper case. In the card,
server.statusfor a running server isRUNNING, whileGET /v1/infra/serversreports the same server at the same moment asrunning. A client comparing strings from both sections must normalize the case.