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

# CLI

> Install the yungle CLI, sign in, send files and folders resumably, push into collections, script it with --json, and look up every command.

`yungle` sends files and folders from a terminal, a script or a build server. An interrupted upload continues when you run the same command again, and `--json` turns every command into something a pipeline can read.

## Prerequisites

* Node 22 or newer, if you install with npm.
* A Yungle account. Sending transfers works on the free plan. Collections, upload requests and `watch` need a paid plan ([pricing](https://yungle.co/pricing)).
* `yungle get` needs neither: anyone with a link can download it.

## Install

<CodeGroup>
  ```bash npm theme={null}
  npm install -g yungle-cli
  ```

  ```bash Homebrew theme={null}
  brew install heindewilde/yungle/yungle
  ```
</CodeGroup>

Check it works:

```bash theme={null}
yungle --version
```

## Sign in

There are two ways to sign in. Which one you need depends on whether Yungle should email anyone for you.

| | Browser sign-in | API key |
| - | - | - |
| How | `yungle login` | `yungle login --key`, or set `YUNGLE_API_KEY` |
| Where | Your own machine, including over SSH | Servers, CI, anywhere without a person present |
| Makes share links | Yes | Yes |
| Emails recipients (`--to`) | No | Yes, with the `transfers:write` scope |
| Registers webhooks | No | Yes, with the `webhooks:write` scope |

### Browser sign-in

```bash theme={null}
yungle login
```

The CLI opens your browser, you confirm a code, and the session is saved in `~/.config/yungle/config.json` (readable only by you). It renews itself, including during a long upload. Add `--no-browser` to print the link instead, for example when the browser is on another machine.

A browser sign-in makes links but never emails anyone. Signing in with a code can be phished ("enter this code" is the whole attack), so that session cannot make Yungle mail strangers or register a webhook. If you pass `--to` with a browser sign-in, the CLI notices before uploading and offers to send a link instead.

### API key

Create a key in [Settings → API keys](https://yungle.co/dashboard/settings/api) (or run `yungle open keys`), then save it:

```bash theme={null}
yungle login --key yk_live_…
```

The CLI checks the key against Yungle before saving it. On a server or in CI, set the environment variable instead. `YUNGLE_API_KEY` is always read first, so no login step is needed:

```bash theme={null}
export YUNGLE_API_KEY=yk_live_…
yungle whoami
```

See [Authentication](/authentication) for the scopes a key can have.

## Everyday tasks

### Send a file or folder

```bash theme={null}
yungle send ~/Shoot
```

It uploads, prints the share link, and emails nobody. You pass the link on yourself.

* Folder structure is kept: `Shoot/Ceremony/Raw` arrives as `Shoot/Ceremony/Raw`.
* Hidden files (names starting with `.`) are skipped when the CLI walks a folder, so a `.DS_Store` in every subfolder stays behind. A hidden file you name directly is sent.
* `--expires 90` sets the lifetime in days. A value beyond your plan's maximum is clamped to it, not rejected.
* `--password <text>` makes recipients enter a password. `--title <text>` labels the transfer in your dashboard.

To include a file that is already online (a presigned S3 link, a CDN URL), add `--from-url <url>`. Yungle fetches it itself, and the CLI waits until it has arrived before the transfer goes live.

### Send to people

```bash theme={null}
yungle send ~/Shoot --to anna@example.com --to joost@example.com \
  --message "Final selects attached."
```

`--to` takes one address per flag or a comma-separated list. It needs an [API key](#api-key); a browser sign-in cannot email.

### Resume an interrupted upload

Run the same command again with the same files. The CLI continues the existing transfer from the last committed part, instead of starting a second one.

```bash theme={null}
yungle send ~/Shoot --to anna@example.com     # killed at 92%
yungle send ~/Shoot --to anna@example.com     # continues the same transfer
```

<Note>
  The resume state lives in `~/.cache/yungle/`, keyed on each file's path, size and modification time, because that is all a second run has to go on. If you change a file between runs, the upload starts over. Resume state expires after two hours, the lifetime of the upload permissions it holds.
</Note>

### See who downloaded it

```bash theme={null}
yungle status N6P8R1ST
```

It shows, per recipient, whether they were emailed, downloaded, or bounced, plus the link and when it expires. An id can be the full id, its last 6–8 characters, or the link. With no id, you pick from your recent transfers.

### Push into a collection

Collections need a paid plan. Find the collection's id, then push files or folders into it:

```bash theme={null}
yungle collections
yungle push ~/Shoot/Selects --collection <collection-id>
```

Add `--folder <folder-id>` to upload into a folder of the collection. A push resumes like a send.

### Watch a folder

For a render box writing frames, a card reader or an export folder:

```bash theme={null}
yungle watch ~/Renders --collection <collection-id>
```

It looks every 10 seconds (`--interval` to change), and uploads a file only once it has stopped changing, so a half-written frame never goes up. What it uploaded is remembered across restarts. Files already in the folder when it starts are left alone unless you pass `--existing`. Stop it with Ctrl-C.

### Download a link

```bash theme={null}
yungle get https://yungle.co/t/<slug> --out ~/Downloads
```

No account is needed: the link is the credential. Folders are kept, the download resumes if interrupted, and the CLI asks for the password if the transfer has one. `yungle pull --collection <collection-id>` downloads a whole collection of your own the same way.

### Use it in a script

With `--json`, every command prints one JSON object on stdout. Progress and diagnostics go to stderr, so a pipe stays clean:

```bash theme={null}
URL=$(yungle send ./render.mp4 --json | jq -r .url)
curl -X POST "$SLACK_WEBHOOK" -d "{\"text\":\"Render ready: $URL\"}"
```

`send --json` prints:

```json theme={null}
{
  "id": "01J8Z3M9Q0W4X7K2B5N6P8R1ST",
  "url": "https://yungle.co/t/<slug>",
  "expiresAt": "2026-10-18T09:30:00.000Z",
  "notified": ["anna@example.com"]
}
```

`notified` lists the addresses that were emailed. `push --json` prints `collection` (the id), `uploaded` (the number of files) and the collection's `url`. `watch --json` prints one line of JSON per uploaded file.

How the CLI behaves depends on where it runs:

| | At a terminal | In a pipe or CI | With `--json` |
| - | - | - | - |
| Output | Colour, tables, a progress bar | Plain text; `send` prints only the link | One JSON object on stdout |
| Missing arguments | Asks for them | Fails with a usage hint | Fails with a usage hint |
| Confirmations | Asks | Never asks | Never asks |

Use `--yes` to skip confirmations in a script that runs at a terminal. A failure with `--json` prints `{ "error": { "code", "message" } }` on stdout.

Exit codes: `0` success, `1` failure, `2` usage error, `130` cancelled.

For a complete CI job, see [Send from CI](/guides/send-from-ci).

## Command reference

Run `yungle <command> --help` for examples of any command. Old spellings (`auth login`, `ls transfers`, `rm transfer`) still work.

### `yungle login`

Opens your browser to sign in; nothing to copy, and it works over SSH because the browser can be on another machine. The session refreshes itself, including during long uploads. On a server or in CI, save an API key with --key instead, or set YUNGLE\_API\_KEY, which is always read first.

| Flag | What it does |
| - | - |
| `--key <key>` | use an API key instead (servers, CI); asks if left out |
| `--no-browser` | print the link instead of opening it |

### `yungle whoami`

The workspace, plan, storage used, and how you are signed in (browser, saved key, or YUNGLE\_API\_KEY).

### `yungle logout`

Revokes the browser session on the server and forgets it on this machine.

### `yungle send <paths…>`

Uploads resumably: interrupt it and run the same command again, and it carries on from the last committed part. Folders keep their structure; hidden files are skipped. Without --to you get a link and nobody is emailed; --to needs an API key (yungle login --key), because a browser sign-in never emails anyone. Run it with no paths at a terminal and it asks what to send.

| Flag | What it does |
| - | - |
| `--from-url <url>` | also send a file Yungle fetches from a URL (repeatable) |
| `--to <email>` | recipient (repeatable, or comma-separated) |
| `--message <text>` | note for the recipients |
| `--title <text>` | label for your dashboard |
| `--password <text>` | recipients must enter this |
| `--expires <days>` | lifetime, clamped to your plan |

### `yungle get <link>`

Needs no account: the link is the credential. Asks for the password if the transfer has one, and resumes an interrupted download. End-to-end encrypted transfers open only in a browser.

| Flag | What it does |
| - | - |
| `--out <dir>` | where to save (default: current directory) |
| `--zip` | one zip instead of separate files |
| `--password <text>` | for a protected link; asks if left out |

### `yungle put <file> --target <target>`

For AI assistants that cannot reach your disk: the assistant prepares the upload and hands you one command with a target in it. Running it checks the file is the one the target was made for, then uploads it resumably, renewing its token as it goes.

### `yungle status [<id\|link>]`

Per recipient: emailed, downloaded, or bounced, plus the link and when it expires. Takes the full id, the short id from yungle transfers, or the link; with none, it lets you pick from your recent transfers.

### `yungle transfers`

The latest 25, with size, downloads and time left.

### `yungle revoke <id>`

Destroys the files and ends the link immediately. Asks first at a terminal; cannot be undone.

### `yungle push <paths…> --collection <id>`

Resumable like send. Folder structure is kept.

| Flag | What it does |
| - | - |
| `--folder <id>` | target folder |
| `--from-url <url>` | also add a file Yungle fetches from a URL (repeatable) |

### `yungle watch <dir> --collection <id>`

For render farms, card readers and export folders. A file goes up once it has stopped changing, what went up is remembered across restarts, and files already in the folder are left alone unless --existing.

| Flag | What it does |
| - | - |
| `--interval <seconds>` | how often to look (default 10) |
| `--existing` | also upload what is already in the folder |

### `yungle pull --collection <id>`

Downloads a whole collection into a folder, keeping its folder structure, resumably: run it again and it skips what is already there at full size. With --transfer it downloads one of your own transfers instead.

| Flag | What it does |
| - | - |
| `--transfer <id>` | download your own transfer instead |
| `--out <dir>` | where to save (default: the collection's title) |
| `--zip` | one zip instead of separate files |

### `yungle collections`

List your collections.

### `yungle requests`

Every public upload page you have out, with its link, whether it is open, and how much has arrived through it.

### `yungle requests new --collection <id>`

Creates a public upload page whose files go straight into the collection, and prints its link. Anyone with the link can upload.

| Flag | What it does |
| - | - |
| `--title <text>` | shown on the upload page |

### `yungle requests pause\|resume\|close <id>`

Pause and close both stop new uploads through the link; resume opens it again.

### `yungle contacts`

List your contacts.

### `yungle open [<id>\|plan\|keys\|webhooks]`

Opens the page in your browser: the dashboard, a transfer by id or link, or your plan, API keys or webhook settings.

### `yungle webhooks ls`

List webhook endpoints.

### `yungle webhooks listen`

Reads a pull endpoint of its own, so it needs no public URL, and prints each event live. With --forward-to it also POSTs each one, signed with the session's secret, to a server on your machine while you build the receiver.

| Flag | What it does |
| - | - |
| `--forward-to <url>` | also POST each one, signed, to a local server |

### `yungle mcp install`

Writes the local MCP server into your assistant's config, with a saved API key (a browser sign-in expires too soon to live in a config file). Refuses keys with more power than the server uses; transfers:write needs --allow-write. Simpler still: add [https://yungle.co/mcp](https://yungle.co/mcp) to your assistant and sign in there.

| Flag | What it does |
| - | - |
| `--client <id>` | claude-desktop \| claude-code \| cursor \| windsurf |
| `--dry-run` | show what would change, write nothing |
| `--allow-write` | accept a key with transfers:write (share links) |

### `yungle mcp status`

Show where it is installed.

### `yungle completion <shell>`

Prints a completion script; yungle completion bash >> \~/.bashrc, for example.

### `yungle --version`

Print the version.

## Global flags

| Flag | What it does |
| - | - |
| `--json` | machine-readable output |
| `--yes` | never ask; for scripts |
| `--url <base>` | use another Yungle (development) |

## What the CLI cannot do

* **Reach your vault.** Its key is derived in your browser and never reaches Yungle.
* **Open end-to-end encrypted transfers.** `yungle get` on such a link says so and points you to the browser.
* **Wait for a download.** To act when someone downloads, poll `yungle status`, or subscribe to the `transfer.downloaded` [webhook](/guides/webhooks).

The CLI is open source (MIT): [yungle-cli on GitHub](https://github.com/heindewilde/yungle-clients/tree/main/apps/cli).

## Next steps

<Columns cols={2}>
  <Card title="Send from CI" icon="workflow" href="/guides/send-from-ci">
    Deliver build artefacts to a client from a pipeline.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    API keys, scopes, and what each one allows.
  </Card>

  <Card title="MCP server" icon="bot" href="/mcp-server">
    Let an AI assistant answer questions about your files.
  </Card>

  <Card title="Upload large files" icon="upload" href="/guides/upload-large-files">
    How resumable uploads work, if you build your own.
  </Card>
</Columns>


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