Para agentes de IA: markdown desta página — /docs-content-en/source-storage/versions.md índice da documentação — /llms.txt
Os artigos da documentação estão disponíveis atualmente em inglês.
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.
Storage overview and the endpoint reference — Source code storage.
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.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id (path) |
UUID | Application identifier. Get it via GET /v1/apps. |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sha256 |
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. |
Response
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.
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, etc.). |
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 by hand — 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 (`linkedServerSources`)
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 (the existence probe stays lightweight). Download and the full per-server list are available via GET /v1/infra/servers/:serverId/sources (see serverContext.serverId). This response's versions / totalVersions / currentVersionId stay app-scoped and are unchanged.
Examples
curl
curl -H "X-Api-Key: YOUR_APP_KEY" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources
JavaScript
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources`,
{ headers: { 'X-Api-Key': process.env.VIBE_APP_KEY } },
)
const { data } = await res.json()
console.log(`Versions: ${data.totalVersions}, latest: ${data.currentVersionId}`)
Error codes
| HTTP | Code | When returned |
|---|---|---|
| 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. |
Metadata for a single version
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.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id (path) |
UUID | Application identifier. |
versionId (path) |
string | Version identifier of the form v<N>. |
Response
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": "Repro snapshot",
"serverContext": null
}
}
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.
Error response example
404 — the application has no version with that number:
{
"success": false,
"error": {
"code": "VERSION_NOT_FOUND",
"message": "Version v99 not found"
}
}
Examples
curl
curl -H "X-Api-Key: YOUR_APP_KEY" \
https://vibecode.bitrix24.com/v1/apps/<APP_ID>/sources/v3
JavaScript
const res = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3`,
{ headers: { 'X-Api-Key': process.env.VIBE_APP_KEY } },
)
const { data } = await res.json()
console.log(data.versionId, data.tags, data.note)
Error codes
| HTTP | Code | When returned |
|---|---|---|
| 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. |
Downloading 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.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id (path) |
UUID | Application identifier. |
versionId (path) |
string | Version identifier of the form v<N>. |
Response
HTTP 200:
{
"success": true,
"data": {
"url": "https://<storage-endpoint>/...",
"expiresAt": "2026-05-21T10:45:30.000Z"
}
}
Examples
curl
# Get the link
curl -H "X-Api-Key: YOUR_APP_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>"
JavaScript
const { data } = await fetch(
`https://vibecode.bitrix24.com/v1/apps/${appId}/sources/v3/download`,
{ headers: { 'X-Api-Key': process.env.VIBE_APP_KEY } },
).then((r) => r.json())
const archive = await fetch(data.url)
const buffer = await archive.arrayBuffer()
// Next — unpack the archive (tar.gz: tar library; zip: JSZip or similar)
Error codes
| HTTP | Code | When returned |
|---|---|---|
| 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. |
The full code reference — Error codes.