# Download Attached File

> Programmatically download attached files from Builds via the API. Generate a download token scoped to a specific attachment and resolve its download URL.

Source: https://docs.applivery.com/en/app-distribution/api/builds/download-attached-file/  •  Last updated: 2026-04-28

---

Downloading an attached file from a Build programmatically uses the same **two-step process** as downloading a Build binary: generate a short-lived download token, then use it to resolve the actual download URL. The key difference is that you must include the `fileId` query parameter to specify which attachment you want to download.

:::warning
This endpoint is **only available through the Workspace API** and requires a **Service Account token** or a user session token obtained at login. The Integrations API (App API Token) does not support this endpoint.
:::

To create a Service Account, see [Service Accounts](https://docs.applivery.com/en/platform/api/service-accounts/).

* * *

## Overview: Download flow

```
Step 1: Generate a download token for the attached file
  GET /v1/organizations/{organizationId}/apps/{applicationId}/builds/{buildId}/downloadToken?fileId={fileId}&type=auto
  → returns { token, expiresAt }

Step 2: Resolve the download URL
  GET https://download-api.applivery.io/v1/download/{token}
  → HTTP 302 redirect to the actual file URL
```

* * *

## Before you start: Find the fileId

The `fileId` is the `id` of the attachment entry in the build's `files` array, where `type` equals `attachment`. You can retrieve it from the [Build Details](https://docs.applivery.com/en/app-distribution/api/builds/build-details/) endpoint.

In the response, look for entries in the `files` array with `"type": "attachment"`:

```json
{
  "files": [
    {
      "id": "2SWkDbddHBNUaVImZINcZzVN",
      "type": "attachment",
      "file": {
        "originalName": "screenshot.png",
        "mimetype": "image/png",
        "size": 538300,
        "location": "https://storage.cloud.google.com/...",
        "checksum": "b531c0eb..."
      },
      "createdAt": "2024-11-11T11:27:35.446Z",
      "updatedAt": "2024-11-11T11:27:35.446Z"
    }
  ]
}
```

The `id` field (`2SWkDbddHBNUaVImZINcZzVN` in this example) is the `fileId` you need for Step 1.

:::info
Other entries in the `files` array (with `type: "package"`, `type: "icon"`, or `type: "original"`) are internal build files, not user-uploaded attachments. Only entries with `type: "attachment"` are files you attached via the [POST – Build Attached Files](https://docs.applivery.com/en/app-distribution/api/builds/attached-files/) endpoint.
:::

* * *

**Generate a Download Token**

Generates a short-lived, single-use token that authorizes the download of a specific attached file.

**Endpoint**

```
GET https://api.applivery.io/v1/organizations/{organizationId}/apps/{applicationId}/builds/{buildId}/downloadToken
```

**Authentication**

```
Authorization: Bearer <your_service_account_token>
```

**Path parameters**

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `organizationId` | String | Yes | The unique identifier (or slug) of your Applivery organization. |
| `applicationId` | String | Yes | The unique identifier of the App the Build belongs to. |
| `buildId` | String | Yes | The unique identifier of the Build containing the attachment. |

**Query parameters**

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `fileId` | String | Yes | The `id` of the attachment entry in the build's `files` array (where `type` is `attachment`). |
| `type` | String | Yes | Set to `auto` for attached file downloads. |

**Example Request**

```bash
curl 'https://api.applivery.io/v1/organizations/ORG_ID/apps/APP_ID/builds/BUILD_ID/downloadToken?fileId=FILE_ID&type=auto' \
  -X GET \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_SERVICE_ACCOUNT_TOKEN'
```

**Responses**

**✓ 200 OK**

```json
{
  "status": true,
  "data": {
    "token": "string",
    "expiresAt": "string"
  }
}
```

**✗ 400 Bad Request**

Build not yet processed. The Build exists but has not finished processing. Only Builds with `status: processed` can have download tokens generated.

```json
{
  "status": false,
  "error": {
    "code": 5014,
    "message": "Build Not Processed"
  }
}
```

**✗ 401 Unauthorized**

```json
{
  "status": false,
  "error": {
    "code": 4002,
    "message": "No auth token"
  }
}
```

**✗ 404 Not Found**

```json
{
  "status": false,
  "error": {
    "code": 3001,
    "message": "Entity not found"
  }
}
```

| Field | Description |
| --- | --- |
| `token` | The download token string. Pass this as the path parameter to Step 2 to resolve the download URL. |
| `expiresAt` | ISO 8601 timestamp indicating when the token expires. Tokens are short-lived — use them promptly after generation. |

**Resolve the Download URL**

Uses the token obtained in Step 1 to get the actual file download URL. The API responds with an HTTP `302 Found` redirect to the file's storage location.

:::warning
**No authentication required**. This endpoint is public — the token itself acts as the credential. Anyone with the token can download the file, so treat tokens as sensitive and do not share them beyond the intended recipient.
:::

**Endpoint**

```
GET https://download-api.applivery.io/v1/download/{token}
```

**Path parameters**

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `token` | String | Yes | The download token returned in Step 1. |

**Example Request**

```bash
curl -L 'https://download-api.applivery.io/v1/download/YOUR_DOWNLOAD_TOKEN' \
  -o downloaded_file.png
```

:::info
The `-L` flag instructs curl to follow the `302` redirect automatically. Without it, you will receive the redirect response with the `Location` header containing the actual file URL, but the file will not be downloaded.
:::

**Responses**

**✓ 302 Found**

Redirect to the file URL.  
The response does not have a body. The actual download URL is in the `Location` response header. Follow the redirect to download the file.

**✗ 401 Unauthorized**

Token expired. Download tokens are short-lived. If the token has expired, generate a new one from Step 1.

```json
{
  "status": false,
  "error": {
    "code": 4005,
    "message": "Token Expired"
  }
}
```

**✗ 404 Not Found**

```json
{
  "status": false,
  "error": {
    "code": 3001,
    "message": "Entity not found"
  }
}
```

* * *

## Complete example: Download an attached file

```bash
# Step 1: Generate the download token for the attached file
TOKEN=$(curl -s \
  'https://api.applivery.io/v1/organizations/ORG_ID/apps/APP_ID/builds/BUILD_ID/downloadToken?fileId=FILE_ID&type=auto' \
  -H 'Authorization: Bearer YOUR_SERVICE_ACCOUNT_TOKEN' \
  | jq -r '.data.token')

# Step 2: Download the file, following the redirect
curl -L \
  "https://download-api.applivery.io/v1/download/$TOKEN" \
  -o downloaded_file
```
