> ## Documentation Index
> Fetch the complete documentation index at: https://aspect.inc/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload files

> Upload files and directory trees to Aspect, control name conflicts, and handle interrupted or large transfers.

Use `aspect upload` to copy local files into an existing Aspect project or directory:

```bash theme={null}
aspect upload ./interview.mov "aspect://Acme/Documentary"
```

The destination is always the last argument. It must identify a project or an existing folder, and your account must have permission to upload there.

## Upload folders and multiple sources

```bash theme={null}
aspect upload ./Footage ./Audio ./notes.pdf "aspect://Acme/Documentary"
```

Folder uploads include the source folder's name and recreate its nested file paths. For example, `./Footage/Day 01/interview.mov` becomes:

```text theme={null}
aspect://Acme/Documentary/Footage/Day 01/interview.mov
```

You do not need a recursive flag. Symbolic links encountered inside a folder are skipped. Empty directories are not created independently of files.

The CLI creates the folders needed for the uploaded file tree **inside** the destination. The destination URL itself must already resolve; create a new destination project or folder in Aspect first.

## Choose what happens when a name exists

| Option | Behavior |
| - | - |
| No conflict flag | Skip files with an existing name at the destination. |
| `--replace` | Replace the existing file's content. |
| `--keep-both` | Keep the existing file and upload another copy with a distinct name. |

```bash theme={null}
aspect upload ./final.mov "aspect://Acme/Documentary/Deliverables" --replace
aspect upload ./review.mov "aspect://Acme/Documentary/Reviews" --keep-both
```

`--replace` and `--keep-both` cannot be combined. The default skip behavior compares destination conflicts; it does not make a changed local file into an automatic update. Choose `--replace` when you intend to upload revised content.

## Large uploads

The CLI streams file content and handles chunked uploading for you. To keep a job running after the terminal closes:

```bash theme={null}
aspect upload ./Footage "aspect://Acme/Documentary" --detach
aspect transfer list
```

Use the returned transfer ID to check progress or wait for completion. See [Background transfers](/docs/cli/transfers).

## Completion and interruptions

A foreground upload prints progress and a final count of uploaded, skipped, and failed files. Add `--json` for a result that a script can read:

```bash theme={null}
aspect upload ./Footage "aspect://Acme/Documentary" --json
```

The result includes `uploaded`, `skipped`, and a `failed` array containing each failed path and its error. A skipped file counts as a successful outcome; any file failure or interruption makes the command exit with a nonzero status.

Ctrl-C cancels a foreground job. You can rerun the same upload to skip files that already completed and try the remaining files again. This is a new transfer, not a promise to resume every partial file at its previous byte offset.

An upload completing means the source file has reached Aspect. Proxy generation and other media processing happen separately; a [streaming proxy](/docs/cli/proxies) may not be available immediately.
