## Download the archive

`GET /v1/apps/:id/sources/:versionId/download`

Returns a temporary signed link for downloading the source archive of the selected application version.

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`](/docs/apps/list). |
| `versionId` (path) | string | yes | Version identifier of the form `v<N>`. Get it via [List versions](/docs/source-storage/versions). The `savedVersionId` returned by a [deploy](/docs/infra/deploy/deploy) to a server on a personal key belongs to the server's history, not the application's: with it, this method returns a link to the archive of a different application version or `404 VERSION_NOT_FOUND`. Download that version via the [server endpoints](/docs/source-storage/servers). |

## Examples

### curl — personal key

```bash
# 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

```bash
# 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

```javascript
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

```javascript
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. The archive format is given by the version's `contentType` field, see [Get version metadata](/docs/source-storage/versions-get). |
| `data.expiresAt` | string | When the signature expires (ISO 8601, UTC). The requested link lifetime is 30 minutes, but the signature may expire earlier: download the archive right away and check this field. |

## Response example

`HTTP 200`, the signed link in the example is shortened:

```json
{
  "success": true,
  "data": {
    "url": "https://<storage-endpoint>/...",
    "expiresAt": "2026-10-07T09:12:22.000Z"
  }
}
```

## Error response example

404 — the application has no version with that identifier:

```json
{
  "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` | The personal key belongs neither to the application author nor to a Bitrix24 account administrator and was not issued for this application. |
| 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](/docs/source-storage/save). |
| 502 | `SOURCE_DOWNLOAD_URL_FAILED` | Storage is temporarily unavailable — retry the request. |

Full list of common API errors — [Errors](/docs/errors).

## See also

- [Source code storage](/docs/source-storage)
- [List versions](/docs/source-storage/versions)
- [Get version metadata](/docs/source-storage/versions-get)
- [Save a snapshot](/docs/source-storage/save)
- [Server-keyed source endpoints](/docs/source-storage/servers)
