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

# Files and ports

> Copy files and folders to and from a cloud machine, and open a port on it at a private run.voyager.computer link.

Moving files to or from a paused machine resumes it first.

## Upload

The CLI handles everything below; use it unless you're writing your own client:

```sh theme={"system"}
voyager-cloud push $MACHINE scene/            # a folder, to the same path on the machine
voyager-cloud push $MACHINE ./big.blend assets/big.blend
```

`POST /v1/machines/{id}/files/upload` takes `{"root", "files": [{"path", "size", "sha256", "content_base64"}]}`. Paths are relative to `root` (default `/project`) or absolute. Each file in the response has a `status`:

| `status` | What it means |
| - | - |
| `unchanged` | The machine already has this file with the same `sha256`; it was skipped. |
| `written` | Sent inline in `content_base64` (files up to 4 MiB) and written. |
| `upload` | Too big to send inline. `PUT` the whole file to its `upload_url` before `expires_at`, then commit it. |

Commit uploaded files with `POST /v1/machines/{id}/files/upload/complete` and `{"root", "files": [{"path", "sha256", "upload_id"}]}`, using each file's `upload_id`. Each file comes back `written`, or `committing` while it's still being copied onto the machine.

## Download

```sh theme={"system"}
voyager-cloud pull $MACHINE out/              # a folder
voyager-cloud pull $MACHINE out/final.exr ./renders/
```

`POST /v1/machines/{id}/files/download` takes `{"root", "paths": [...]}`, files or folders, relative to `root` (default `/project`). Each file comes back with its `path`, `size` and `sha256`, and either `content_base64` (small files) or a `download_url` to `GET` (larger files; valid 2 hours).

## Ports

Run a server on the machine, such as a preview, a notebook or a viewer, and open it in your browser:

```sh theme={"system"}
voyager-cloud exec --detach $MACHINE -- python3 -m http.server 8080
voyager-cloud port $MACHINE 8080
```

`POST /v1/machines/{id}/ports` with `{"port": 8080}` returns `{port, url, expires_at}`, where `url` is a link like `https://k3v9q2m7x4b8n1c6z5w0.run.voyager.computer/`. It serves HTTP and WebSockets while the machine runs, and stops working when it's released or the link expires.

> [!WARNING]
>
> Anyone with the link can reach that port while the machine runs. Don't share it, and don't serve anything on it you wouldn't want seen.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.