> For the complete documentation index, see [llms.txt](https://academy.shade.inc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://academy.shade.inc/developers/using-the-api/working-with-assets.md).

# Working with assets

Look up assets by path or ID, download originals and proxies, organize files and folders, and read transcripts and comments through the Shade API.

An asset is a file in a Shade drive, along with everything Shade knows about it: previews, proxies, AI tags, transcripts, metadata, and comments. This guide covers what you'll do with assets most often.

## Prerequisites

* A Shade API key, stored in the `SHADE_KEY` environment variable
* A drive ID. See [Finding your IDs](/developers/get-started/integrating-with-shade.md)

## Base information

* **Base URL**: `https://api.shade.inc`
* **Authentication**: your API key in the `Authorization` header, with no `Bearer` prefix
* **Paths**: in the REST API, paths start with the drive ID, for example `/7b1e4d2c-5a6f-4e8b-9c3d-2f1a0b9c8d7e/Fall Campaign/Interviews/A001_C003.mov`. Every asset's `path` field uses this form, so you can pass it straight back to any endpoint that takes a path.

## 1. Find an asset

**By ID:**

```bash
curl "https://api.shade.inc/assets/ASSET_ID?drive_id=YOUR_DRIVE_ID" \
  -H "Authorization: $SHADE_KEY"
```

**By path:**

```bash
curl -G "https://api.shade.inc/assets/path" \
  -H "Authorization: $SHADE_KEY" \
  --data-urlencode "drive_id=YOUR_DRIVE_ID" \
  --data-urlencode "path=/YOUR_DRIVE_ID/Fall Campaign/Interviews/A001_C003.mov"
```

Use `--data-urlencode` or your HTTP library's query parameter support, since paths often contain spaces.

To list a folder or find assets by type, date, or metadata, use [search](/developers/using-the-api/searching-and-filtering-assets.md).

### Key fields

| Field                                         | Description                                                                                                        |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `id`                                          | The asset ID                                                                                                       |
| `path`                                        | Full path, starting with the drive ID                                                                              |
| `name`, `extension`                           | File name, and its extension without the dot                                                                       |
| `type`                                        | `VIDEO`, `IMAGE`, `AUDIO`, `DOCUMENT`, and other file types                                                        |
| `size_bytes`                                  | File size in bytes                                                                                                 |
| `created`, `updated`                          | Timestamps                                                                                                         |
| `system_metadata`                             | Technical metadata such as `Width`, `Height`, `Duration`, `Frame Rate`, and `Codec`                                |
| `custom_metadata`                             | Your metadata values, keyed by attribute ID. See the [metadata guide](/developers/using-the-api/metadata-guide.md) |
| `category`, `ocr`, `palette`, `faces_present` | What Shade's AI found in the file                                                                                  |
| `comment_count`                               | Number of comments                                                                                                 |

### Processing status

After a file is uploaded, Shade processes it in the background. Each step has a `*_job_state` field, such as `preview_job_state`, `proxy_job_state`, and `transcription_job_state`. Each one is one of:

| State                  | Meaning                                             |
| ---------------------- | --------------------------------------------------- |
| `NOT_STARTED`          | Queued                                              |
| `IN_PROGRESS`          | Running                                             |
| `COMPLETED`            | Done                                                |
| `FAILED`               | Failed                                              |
| `INSUFFICIENT_CREDITS` | Skipped because the workspace ran out of AI credits |

To react when a step finishes, subscribe to [webhooks](/developers/guides/webhooks.md) such as `proxy.completed` and `transcription.completed` instead of polling.

## 2. Download files

`GET /assets/{asset_id}/download` returns a signed URL as a JSON string. Fetch the file from that URL; it doesn't need your API key.

```bash
URL=$(curl -s "https://api.shade.inc/assets/ASSET_ID/download?drive_id=YOUR_DRIVE_ID&origin_type=SOURCE" \
  -H "Authorization: $SHADE_KEY" | jq -r .)

curl -L "$URL" -o A001_C003.mov
```

| Parameter     | Description                                                                                    |
| ------------- | ---------------------------------------------------------------------------------------------- |
| `origin_type` | `SOURCE` for the original file, or `PROXY` for Shade's lightweight preview video               |
| `download`    | `true`, the default, makes browsers save the file. `false` lets them play or display it inline |
| `name`        | File name to save as                                                                           |

Signed URLs expire, so request a new one each time instead of storing them. To get URLs for many files at once, use [`POST /search/download-urls`](/developers/using-the-api/searching-and-filtering-assets.md#6-downloading-search-results).

### Previews

`GET /assets/{asset_id}/previews?drive_id=YOUR_DRIVE_ID` returns the preview images Shade generated. Each one has an `id`, the video `frame` it was taken from, and a `signed_url`.

## 3. Organize files and folders

All of these take a JSON body with `drive_id` and full paths, and return `null` when they succeed.

| Task                      | Endpoint                      | Body                                               |
| ------------------------- | ----------------------------- | -------------------------------------------------- |
| Create a folder           | `POST /files/directory`       | `path`                                             |
| Create several folders    | `POST /files/directory/batch` | `paths`                                            |
| Move or rename            | `POST /files/move`            | `source`, `destination`                            |
| Move or rename several    | `POST /files/move/batch`      | `sources`, `destinations`                          |
| Copy                      | `POST /files/copy`            | `source`, `destination`                            |
| Move to the trash         | `POST /files/trash`           | `path`                                             |
| Move several to the trash | `POST /files/trash/batch`     | `paths`                                            |
| Delete permanently        | `POST /files/delete`          | `path`                                             |
| Move between drives       | `POST /files/interdrive/move` | `drive_id_src`, `drive_id_dst`, `paths`            |
| Copy between drives       | `POST /files/interdrive/copy` | `source_drive_id`, `destination_drive_id`, `paths` |

`destination` is the full new path, including the file name. Renaming is a move within the same folder:

```bash
curl -X POST "https://api.shade.inc/files/move" \
  -H "Authorization: $SHADE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "drive_id": "YOUR_DRIVE_ID",
    "source": "/YOUR_DRIVE_ID/Fall Campaign/Interviews/A001_C003.mov",
    "destination": "/YOUR_DRIVE_ID/Fall Campaign/Interviews/Jordan Interview.mov"
  }'
```

{% hint style="warning" %}
`POST /files/delete` skips the trash and can't be undone. If the file is part of a stack, the whole stack is deleted. Use `POST /files/trash` unless you're sure.
{% endhint %}

Two read-only helpers take `drive_id` and `path` as query parameters:

* `GET /files/exists` returns `true` or `false`
* `GET /files/details` returns a folder's total `dir_size_bytes` and `dir_num_items`

## 4. Transcripts

Once `transcription_job_state` is `COMPLETED`, you can read the transcript as structured data or export it as a file.

**Structured utterances:**

```bash
curl "https://api.shade.inc/assets/ASSET_ID/transcription/utterances?drive_id=YOUR_DRIVE_ID" \
  -H "Authorization: $SHADE_KEY"
```

The response has `base_utterances`, the original transcript, and `edits`, the corrections made in Shade, keyed by the utterance's position in `base_utterances`. Each utterance has a `speaker`, `start` and `end` times in seconds, `text`, and word-level `words`. To show the corrected transcript, replace each utterance with its edit when one exists.

**Export as a file:**

```bash
curl "https://api.shade.inc/assets/ASSET_ID/transcription/file?drive_id=YOUR_DRIVE_ID&type=srt" \
  -H "Authorization: $SHADE_KEY" -o A001_C003.srt
```

`type` is `vtt` (the default), `srt`, `txt`, or `scriptsync` for Avid ScriptSync.

## 5. Comments

**List comments:**

```bash
curl "https://api.shade.inc/assets/ASSET_ID/comments?drive_id=YOUR_DRIVE_ID" \
  -H "Authorization: $SHADE_KEY"
```

**Add a comment:**

```bash
curl -X POST "https://api.shade.inc/assets/ASSET_ID/comments" \
  -H "Authorization: $SHADE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "drive_id": "YOUR_DRIVE_ID",
    "comment": "Color looks off in this section.",
    "timestamp": 12.5,
    "duration": 4,
    "url": "https://app.shade.inc/WORKSPACE_DOMAIN/a/DRIVE_IDENTIFIER/ASSET_ID?commentId=REPLACE_COMMENT_ID_ON_SERVER"
  }'
```

* `timestamp` is where the comment starts in the video, in seconds. Add `duration`, also in seconds, to comment on a range.
* `url` is the link Shade puts in comment notifications. `WORKSPACE_DOMAIN` is the workspace's `domain` and `DRIVE_IDENTIFIER` is the drive's `identifier`, both short names such as `northwind-studio` and `marketing`, from `GET /workspaces` and `GET /workspaces/{workspace_id}/drives`. Keep `REPLACE_COMMENT_ID_ON_SERVER` as written, and Shade fills in the new comment's ID.

Reply with `POST /assets/{asset_id}/comments/{comment_id}/reply`, and resolve with `PUT /assets/{asset_id}/comments/{comment_id}/resolve`.

## Tips

* Store asset IDs rather than paths. An asset keeps its ID when it's moved or renamed within a drive.
* Use `PROXY` downloads for previews and review tools. Proxies are much smaller than camera originals and play in any browser.
* For bulk changes, prefer the `/batch` endpoints over looping one call per file.

## Related

* [Uploading to Shade](/developers/guides/uploading-to-shade.md)
* [Searching and filtering assets](/developers/using-the-api/searching-and-filtering-assets.md)
* [Metadata guide](/developers/using-the-api/metadata-guide.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://academy.shade.inc/developers/using-the-api/working-with-assets.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
