Für KI-Agenten: Markdown dieser Seite — /docs-content-en/source-storage/versions.md Dokumentationsindex — /llms.txt
Dokumentationsartikel sind derzeit auf Englisch verfügbar.
Version list and download
Reading the snapshot history: the list of an application's versions, the metadata of a single version, and a signed link to the archive. All three operations stay available even when source saving is disabled.
List versions
GET /v1/apps/:id/sources
Returns non-deleted versions, at most 500 per call, in descending order of save time — the most recent first.
The operation stays available even when source saving is disabled: the previously saved history remains readable.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) |
UUID | yes | Application identifier. Get it via GET /v1/apps. |
sha256 (query) |
string | no | A probe for whether an archive with the given contents already exists: exactly 64 hexadecimal characters, otherwise 400 INVALID_SHA256. Responds with the same shape as a list call without this parameter, but the linkedServerSources section is not computed — the probe stays lightweight. |
Examples
curl — personal key
curl -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources
curl — OAuth application
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources`,
{ headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
)
const { data } = await res.json()
console.log(`Versions: ${data.totalVersions}, latest: ${data.currentVersionId}`)
JavaScript — OAuth application
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources`,
{
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
},
)
const { data } = await res.json()
console.log(`Versions: ${data.totalVersions}, latest: ${data.currentVersionId}`)
Response fields
| Field | Type | Description |
|---|---|---|
data.totalVersions |
number | Total number of non-deleted versions. Counted without a cap, so with a long history it exceeds the length of the versions array. |
data.currentVersionId |
string | null | Identifier of the most recent version (v<N>). null if there are no versions. |
data.totalSizeBytes |
number | Total size of all archives in bytes. |
data.versions |
array | The list of versions, newest first. At most 500 entries are returned — with a longer history the array is truncated while totalVersions shows the real number. |
data.versions[].versionId |
string | Version identifier of the form v<N>. |
data.versions[].filename |
string | Filename in storage. Contains a -published or -manual suffix if the corresponding tag is set. |
data.versions[].contentType |
string | null | Archive type: application/gzip, application/zip, and other allowed values. |
data.versions[].timestamp |
string | Save time (ISO 8601, UTC). |
data.versions[].size |
number | Archive size in bytes. |
data.versions[].sha256 |
string | SHA-256 of the archive contents. Used for deduplication within one owner. |
data.versions[].tags |
string[] | Active tags: manual, published. |
data.versions[].savedBy.userId |
string | null | Vibecode user identifier. |
data.versions[].savedBy.session |
string | null | AI session identifier from the X-AI-Session-Id header. |
data.versions[].linkedDeployId |
string | null | Publication identifier, filled in after POST /v1/apps/:id/publish. |
data.versions[].deployStatus |
string | null | How the DEPLOY of this version ended: success or failed. Empty for versions saved manually — they were never deployed. Publishing does not change this field: it is not a deploy and knows nothing about how one ended. |
data.versions[].note |
string | null | Note from the X-Note field at save time or from PATCH. |
data.versions[].serverContext |
object | null | Server-level display context: serverId, serverName, serverDisplayName, linkedApp ({ appId, title } or null). Present on both server-scoped responses and app-scoped version items. linkedApp is resolved at read time from the current OAuth key of the app that owns the server. |
Linked server versions
The versions array lists only app-scoped versions. Versions stored under a server (via POST /v1/infra/servers/:id/sources or auto-save on deploy under a personal key) are not included there — they are returned in a separate additive field data.linkedServerSources, grouped by server:
{
"data": {
"totalVersions": 0,
"versions": [],
"linkedServerSources": [
{
"serverContext": {
"serverId": "8de64f8d-...",
"serverName": "srv-prod",
"serverDisplayName": "Prod",
"linkedApp": null
},
"totalVersions": 2,
"totalSizeBytes": 20,
"versions": [ /* same shape as versions[] items */ ]
}
],
"linkedServerSourcesTruncated": false,
"linkedServerHint": {
"message": "This app has source versions stored under a server (server-keyed storage). List and download them via the server endpoint.",
"listEndpoint": "GET /v1/infra/servers/:serverId/sources",
"downloadEndpoint": "GET /v1/infra/servers/:serverId/sources/:versionId/download",
"docs": "https://vibecode.bitrix24.com/docs-content-en/source-storage.md"
}
}
}
| Field | Type | Description |
|---|---|---|
data.linkedServerSources[] |
array | Groups of server versions, one per server. Empty if there are no linked server versions. |
data.linkedServerSources[].serverContext |
object | The server: serverId, serverName, serverDisplayName, linkedApp — null for servers on a personal key. |
data.linkedServerSources[].totalVersions |
number | Exact number of versions on the server, not limited by the list size below. |
data.linkedServerSources[].totalSizeBytes |
number | Total size of that server's versions. |
data.linkedServerSources[].versions[] |
array | Server versions in the same shape as versions[]. Version numbers come from a single sequence shared by the server and its linked application, so an individual server's sequence may not start at v1 and may contain gaps. |
data.linkedServerSourcesTruncated |
boolean | true if the version list was truncated because the history is very large. The full list is on the server endpoint. |
data.linkedServerHint |
object | null | Present when linkedServerSources is non-empty. Points to the authoritative list and download endpoints for server versions. |
The field is populated when the caller is the app author (personal vibe_api_* key) or a Bitrix24 account administrator. When called with an OAuth-app key the section is empty: a machine key does not enumerate the author's personal servers. On a ?sha256= request the section is not computed, so the existence probe stays lightweight. Download and the full per-server list are available via GET /v1/infra/servers/:serverId/sources, with the identifier in serverContext.serverId. This response's versions, totalVersions, and currentVersionId stay app-scoped and are unchanged.
Response example
HTTP 200:
{
"success": true,
"data": {
"totalVersions": 3,
"currentVersionId": "v3",
"totalSizeBytes": 552960,
"versions": [
{
"versionId": "v3",
"filename": "2026-05-21T10-15-30-000Z-v3.tar.gz",
"contentType": "application/gzip",
"timestamp": "2026-05-21T10:15:30.000Z",
"size": 184320,
"sha256": "a3f5d8b2c1e9f4...",
"tags": [],
"savedBy": {
"userId": "8f1a2b3c-...",
"session": "claude-session-2026-05-21"
},
"linkedDeployId": null,
"deployStatus": null,
"note": "Added OAuth flow"
},
{
"versionId": "v2",
"filename": "2026-05-20T18-02-11-000Z-v2-published.tar.gz",
"contentType": "application/gzip",
"timestamp": "2026-05-20T18:02:11.000Z",
"size": 184320,
"sha256": "9e7c4b2a1f8d3...",
"tags": ["published"],
"savedBy": {
"userId": "8f1a2b3c-...",
"session": null
},
"linkedDeployId": "publish:2026-05-20T18:05:42.000Z",
"deployStatus": "success",
"note": null
},
{
"versionId": "v1",
"filename": "2026-05-20T09-44-50-000Z-v1.tar.gz",
"contentType": "application/gzip",
"timestamp": "2026-05-20T09:44:50.000Z",
"size": 184320,
"sha256": "5a8d3e2f1c4b9...",
"tags": [],
"savedBy": { "userId": "8f1a2b3c-...", "session": null },
"linkedDeployId": null,
"deployStatus": null,
"note": null,
"serverContext": null
}
],
"linkedServerSources": [],
"linkedServerSourcesTruncated": false
}
}
The linkedServerSources and linkedServerSourcesTruncated fields are always present — when there are no linked server versions they are an empty array and false.
Error response example
404 — there is no application with that identifier:
{
"success": false,
"error": {
"code": "APP_NOT_FOUND",
"message": "Application not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_SHA256 |
The sha256 parameter is not exactly 64 hexadecimal characters. |
| 403 | SOURCE_APP_ID_MISMATCH |
The call was made with an authorization key vibe_app_… issued for a different application. Such a key can access only its own application's snapshots, even when both applications were created by the same author. |
| 403 | NOT_AUTHORIZED |
Only the application author, the application OAuth key, or a Bitrix24 account administrator can manage snapshots. |
| 404 | APP_NOT_FOUND |
The application does not exist, was deleted, or belongs to another portal. |
Full list of common API errors — Errors.
Get version metadata
GET /v1/apps/:id/sources/:versionId
Returns one version in the same shape as a data.versions[] element of the list. Useful when the version identifier is already known — for example, it arrived in savedVersionId of the deploy response — and there is no reason to fetch the whole list.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) |
UUID | yes | Application identifier. Get it via GET /v1/apps. |
versionId (path) |
string | yes | Version identifier of the form v<N>. Get it via List versions. |
Examples
curl — personal key
curl -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources/v3
curl — OAuth application
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources/v3
JavaScript — personal key
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3`,
{ headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
)
const { data } = await res.json()
console.log(data.versionId, data.tags, data.note)
JavaScript — OAuth application
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3`,
{
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
},
)
const { data } = await res.json()
console.log(data.versionId, data.tags, data.note)
Response fields
The field set matches a data.versions[] element — see the list response fields. This response carries no data.id: the internal record identifier is returned only on save.
Response example
HTTP 200:
{
"success": true,
"data": {
"versionId": "v1",
"filename": "2026-08-17T11-30-16-449Z-v1-published.tar.gz",
"contentType": "application/gzip",
"timestamp": "2026-08-17T11:30:16.449Z",
"size": 451,
"sha256": "3e9568ee635bb9faacb3eab4be8e59c747792e0b2bfcdc71ea42dd3dabb12d2c",
"tags": ["published"],
"savedBy": {
"userId": "8f1a2b3c-...",
"session": null
},
"linkedDeployId": "publish:2026-08-17T11:30:27.898Z",
"deployStatus": "success",
"note": "Snapshot for reproduction",
"serverContext": null
}
}
Error response example
404 — the application has no version with that number:
{
"success": false,
"error": {
"code": "VERSION_NOT_FOUND",
"message": "Version v99 not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_VERSION_ID |
The versionId format does not match v<non-negative integer>. |
| 403 | SOURCE_APP_ID_MISMATCH |
The call was made with an authorization key vibe_app_… issued for a different application. Such a key can access only its own application's snapshots, even when both applications were created by the same author. |
| 403 | NOT_AUTHORIZED |
Only the application author, the application OAuth key, or a Bitrix24 account administrator can manage snapshots. |
| 404 | APP_NOT_FOUND |
The application does not exist, was deleted, or belongs to another portal. |
| 404 | VERSION_NOT_FOUND |
A version with this versionId does not exist or was deleted. |
Full list of common API errors — Errors.
Download the archive
GET /v1/apps/:id/sources/:versionId/download
Returns a signed link to the version's archive. The requested link lifetime is 30 minutes. The actual signature expiry is returned in expiresAt and may be shorter, so download as early as you can and check that field.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) |
UUID | yes | Application identifier. Get it via GET /v1/apps. |
versionId (path) |
string | yes | Version identifier of the form v<N>. Get it via List versions. |
Examples
curl — personal key
# Get the link
curl -H "X-Api-Key: YOUR_API_KEY" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources/v3/download
# Download the archive using that link, no additional headers
curl -o source-v3.tar.gz "<url from the response above>"
curl — OAuth application
# Get the link
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources/v3/download
# Download the archive using that link, no additional headers
curl -o source-v3.tar.gz "<url from the response above>"
JavaScript — personal key
const { data } = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3/download`,
{ headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
).then((r) => r.json())
const archive = await fetch(data.url)
const buffer = await archive.arrayBuffer()
// Next, unpack the archive: read tar.gz with a tar library, zip with JSZip or similar
JavaScript — OAuth application
const { data } = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3/download`,
{
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
},
).then((r) => r.json())
const archive = await fetch(data.url)
const buffer = await archive.arrayBuffer()
// Next, unpack the archive: read tar.gz with a tar library, zip with JSZip or similar
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success. |
data.url |
string | Signed link to the archive. Requires no additional headers when downloading. |
data.expiresAt |
string | When the signature expires (ISO 8601, UTC). May come earlier than the requested 30 minutes. |
Response example
HTTP 200:
{
"success": true,
"data": {
"url": "https://<storage-endpoint>/...",
"expiresAt": "2026-05-21T10:45:30.000Z"
}
}
Error response example
404 — there is no version with that identifier:
{
"success": false,
"error": {
"code": "VERSION_NOT_FOUND",
"message": "Version v99 not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_VERSION_ID |
The versionId format does not match v<non-negative integer>. |
| 403 | SOURCE_APP_ID_MISMATCH |
The call was made with an authorization key vibe_app_… issued for a different application. Such a key can access only its own application's snapshots, even when both applications were created by the same author. |
| 403 | NOT_AUTHORIZED |
Only the application author, the application OAuth key, or a Bitrix24 account administrator can manage snapshots. |
| 404 | APP_NOT_FOUND |
The application does not exist, was deleted, or belongs to another portal. |
| 404 | VERSION_NOT_FOUND |
A version with this versionId does not exist or was deleted. |
| 410 | SOURCE_VERSION_BYTES_PURGED |
The version record still exists, but its bytes have already been purged from storage. The only recovery is to save the archive again. |
| 502 | SOURCE_DOWNLOAD_URL_FAILED |
Storage is temporarily unavailable — retry the request. |
Full list of common API errors — Errors.