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

# bunny stream

> Manage Bunny Stream video libraries, videos, collections, and captions from the command line.

<Note>
  CLI support for `bunny stream` is in [Public Preview](/docs/product-release-stages#stage-2-public-preview). Commands and flags may change during this period.
</Note>

`bunny stream` manages [Bunny Stream](/docs/stream) video libraries and the videos in them.

| Command | Use it to |
| - | - |
| `bunny stream libraries` | Create and configure libraries, including player and security settings |
| `bunny stream videos` | Upload, fetch, update, encode, transcribe, caption, and delete videos |
| `bunny stream collections` | Group videos into [collections](/docs/stream/collections) |
| `bunny stream import` | Move a library from another platform into Stream |
| `bunny stream link` | Link the current directory to a library |
| `bunny stream regions` | List the regions a library can replicate to |

```bash theme={null}
bunny stream libraries create my-library --link
bunny stream videos upload ./video.mp4
bunny stream videos embed <video-id>
```

## Choosing a library

Library commands take the library's name or numeric ID as an argument (`bunny stream libraries show my-library`). Other commands take it with `--lib` or `--library` (`bunny stream videos list --lib 12345`). If you leave it out, the CLI uses the library linked to the current directory, and otherwise asks you to pick one.

Run [`bunny stream link`](#bunny-stream-link-and-unlink) to link a directory. It writes `.bunny/stream.json`, so every video, collection, and caption command in that directory targets the same library.

You don't need a library's Stream API key. The CLI looks it up from your account.

***

## Libraries

`bunny stream libraries` also answers to `library` and `lib`.

### `bunny stream libraries create`

Create a video library. The main storage region is always DE. The command asks whether to replicate the library to other regions, with SG, LA, and NY preselected. Pass `--replication-regions` to choose without the prompt. Run [`bunny stream regions`](#bunny-stream-regions) to see every region code.

```bash theme={null}
# Create a library and choose replication regions interactively
bunny stream libraries create my-library

# Replicate to New York and Singapore only
bunny stream libraries create my-library --replication-regions NY,SG

# Keep everything in DE without asking about replication
bunny stream libraries create internal --replication-regions DE

# Create with Premium Encoding and transcribing
bunny stream libraries create my-library --encoding-tier premium --codecs x264,vp9 --transcribing --transcribing-languages en,de

# Link this directory and save the library ID and API key to .env, with no prompts
bunny stream libraries create my-library --link --save-env --no-add-videos
```

After it creates the library, the command offers to:

1. Link the current directory to the new library.
2. Save `BUNNY_STREAM_LIBRARY_ID` and `BUNNY_STREAM_API_KEY` to `.env`. The [Stream examples](https://github.com/BunnyWay/examples/tree/main/stream) read these names.
3. Add videos, by importing them from another platform or uploading a file.

It then prints the commands to upload a video, import videos, and show the library's credentials. Use the flags below to answer the offers up front. When the command can't prompt, it skips any offer you didn't set with a flag.

| Flag | Description |
| - | - |
| `--replication-regions` | Regions to replicate to besides DE: `UK`, `SE`, `NY`, `LA`, `SG`, `SYD`, `BR`, `JH`. Pass `DE` alone for no replication. Leave it out to be asked in a terminal, or to get no replicas when the command can't prompt. |
| `--player-version` | `1` for the legacy player, `2` for the current one |
| `--link`, `--no-link` | Link the current directory to the new library, or skip the offer |
| `--save-env`, `--no-save-env` | Save the library ID and API key to `.env`, or skip the offer |
| `--no-add-videos` | Skip the offer to import or upload videos |

`libraries create` also accepts every [library settings flag](#library-settings-flags).

<Warning>
  Replication regions can't be removed once they're enabled. See
  [Replication](/docs/stream/replication).
</Warning>

### `bunny stream libraries list`

List your video libraries with their video count, storage, traffic, and replication regions.

```bash theme={null}
bunny stream libraries list
bunny stream libraries ls --output json
```

### `bunny stream libraries show`

Show one library's settings. API keys are never printed here, in any output format.

```bash theme={null}
bunny stream libraries show my-library
bunny stream libraries show 12345 --output json
```

### `bunny stream libraries update`

Change a library's settings. The command changes only the settings you pass flags for. Without flags, it walks you through the settings interactively.

```bash theme={null}
# Edit interactively
bunny stream libraries update my-library

# Set the enabled resolutions
bunny stream libraries update my-library --resolutions 720p,1080p

# Switch to Premium Encoding
bunny stream libraries update my-library --encoding-tier premium --codecs x264,vp9

# Add Sydney as a replication region
bunny stream libraries update my-library --add-replication-regions SYD
```

| Flag | Description |
| - | - |
| `--name` | New library name |
| `--add-replication-regions` | Regions to add. Regions can't be removed later. |
| `--content-tagging` | Categorize uploads automatically with [content tagging](/docs/stream/tagging) |
| `--force`, `-f` | Skip prompts and apply only the flag values |

`libraries update` also accepts every [library settings flag](#library-settings-flags).

#### Library settings flags

`libraries create` and `libraries update` share these flags. Boolean flags take a `--no-` prefix to turn a setting off, such as `--no-jit`.

| Flag | Description |
| - | - |
| `--encoding-tier` | `free` or `premium`. [Premium Encoding](/docs/stream/premium-encoding) is billed per output codec per minute. |
| `--jit` | [Just-in-time encoding](/docs/stream/premium-encoding#just-in-time-encoding) (Premium) |
| `--codecs` | Output codecs, comma-separated: `x264`, `vp9`, `hevc`, `av1`. `vp9`, `hevc`, and `av1` need Premium. |
| `--resolutions` | Enabled resolutions, comma-separated: `240p`, `360p`, `480p`, `720p`, `1080p`, `1440p`, `2160p` |
| `--transcribing` | Transcribe new uploads automatically (billed per use) |
| `--transcribing-languages` | Caption languages, comma-separated ISO 639-1 codes such as `en,de` |
| `--transcribing-title` | Generate the title from the transcript |
| `--transcribing-description` | Generate the description from the transcript |
| `--transcribing-chapters` | Generate chapters from the transcript |
| `--transcribing-moments` | Generate moments from the transcript |
| `--mp4-fallback` | Also encode [MP4 files](/docs/stream/encoding#enable-mp4-fallback) up to 1080p |
| `--keep-original` | Store the uploaded original next to the encoded files |
| `--early-play` | Play from the original file before encoding finishes. Needs `--keep-original`. |
| `--multi-audio` | Encode every [audio track](/docs/stream/multi-audio) separately and offer them in the player |

### `bunny stream libraries credentials`

Show a library's ID and Stream API key. The key is masked unless you pass `--show-secret`.

```bash theme={null}
bunny stream libraries credentials my-library --show-secret

# Save the library ID and API key to .env
bunny stream libraries credentials my-library --save-env

# Rotate the read-only key without a prompt
bunny stream libraries credentials my-library --rotate --read-only --force
```

| Flag | Description |
| - | - |
| `--show-secret` | Reveal the API key |
| `--read-only` | Use the read-only API key |
| `--rotate` | Reset the key. Anything using the old key stops working. |
| `--save-env`, `--no-save-env` | Save `BUNNY_STREAM_LIBRARY_ID` and `BUNNY_STREAM_API_KEY` to `.env`, or skip the offer |
| `--force`, `-f` | Skip the rotation confirmation |

### `bunny stream libraries player`

Show, update, or reset a library's [player settings](/docs/stream/player-settings). `player update` without flags edits the settings interactively.

```bash theme={null}
bunny stream libraries player show my-library

# Brand the player and show the heatmap
bunny stream libraries player update my-library --color "#FF7755" --heatmap

# Set playback speeds, including a custom one
bunny stream libraries player update my-library --speeds 0.5,1.0,1.15,2.0

# Reset language, font, colours, captions, controls, and speeds
bunny stream libraries player reset my-library --force
```

| Flag | Description |
| - | - |
| `--language` | Player UI language as an ISO 639-1 code |
| `--font` | Font family, such as `Rubik` |
| `--color` | Primary control colour, such as `#FF7755` |
| `--caption-color` | Caption text colour |
| `--caption-background` | Caption background colour |
| `--caption-size` | Caption font size |
| `--controls` | Controls to show, comma-separated. Pass it alone to restore the defaults, or `--no-controls` to hide every control. |
| `--speeds` | Playback speeds, comma-separated |
| `--custom-html` | File with custom HTML and CSS for the player head |
| `--heatmap` | Show the watch-time heatmap |
| `--remember-position` | Resume where the viewer left off |
| `--compact-controls` | Use the smaller player UI |
| `--legacy-player` | Use the legacy player |
| `--captions-in-playlist` | Signal captions in the HLS master playlist for third-party players |

### `bunny stream libraries security`

Show or update a library's [security settings](/docs/stream/security-options). `security update` without flags edits the settings interactively.

```bash theme={null}
# Show settings, including the token authentication key
bunny stream libraries security show my-library --show-secret

# Require embed tokens and allow embeds on one domain only
bunny stream libraries security update my-library --embed-token --block-direct-access --allow-referrer example.com

# Turn on MediaCage Basic DRM
bunny stream libraries security update my-library --drm-basic

# Rotate the token authentication key
bunny stream libraries security show my-library --rotate
```

| Flag | Description |
| - | - |
| `--allow-referrer` | Add an allowed domain, such as `*.example.com` (repeatable) |
| `--remove-allowed-referrer` | Remove an allowed domain (repeatable) |
| `--block-referrer` | Add a blocked domain (repeatable) |
| `--remove-blocked-referrer` | Remove a blocked domain (repeatable) |
| `--block-direct-access` | Block requests with no `Referer` header |
| `--direct-play` | Allow playback from the direct video URL |
| `--embed-token` | Require [embed view token authentication](/docs/stream/token-authentication) |
| `--cdn-token` | Require CDN token authentication |
| `--token-ip` | Bind CDN tokens to the viewer's IP |
| `--drm-basic` | [MediaCage Basic DRM](/docs/stream/mediacage-basic) |

`security show` takes `--show-secret` to reveal the token authentication key, and `--rotate` to reset it. `--rotate` asks for confirmation, which `--force` skips.

<Warning>
  `--rotate` resets the key used for both CDN and embed view tokens. Every
  signed URL issued with the old key stops working.
</Warning>

### `bunny stream link` and `unlink`

Link the current directory to a library so video, collection, and caption commands can leave out `--lib`. `bunny stream libraries link` and `bunny stream libraries unlink` do the same.

```bash theme={null}
# Pick a library interactively
bunny stream link

# Link by name or ID
bunny stream link my-library

# Remove .bunny/stream.json
bunny stream unlink
```

### `bunny stream regions`

List the region codes a library can store and replicate videos in. DE is the fixed main region, and SG, LA, and NY are the suggested replication regions.

```bash theme={null}
bunny stream regions
```

### `bunny stream libraries delete`

Delete a library and every video in it. Pass `--force` to skip the confirmation, which is required when running non-interactively.

```bash theme={null}
bunny stream libraries delete my-library
bunny stream libraries delete my-library --force
```

***

## Videos

`bunny stream videos` also answers to `video`. Every video command accepts `--lib` / `--library` to pick a library. Commands that take a `[video]` argument expect the video's GUID, and prompt you to pick a video when you leave it out.

### `bunny stream videos upload`

Upload a local file. Files over 2 GB upload through [TUS](/docs/stream/tus-resumable-uploads), which retries and resumes automatically.

```bash theme={null}
bunny stream videos upload ./video.mp4
bunny stream videos upload ./video.mp4 --lib 12345 --title "Launch keynote"
```

| Flag | Description |
| - | - |
| `--title` | Video title (defaults to the file name) |
| `--collection` | Collection ID to put the video in |
| `--thumbnail-time` | Time in milliseconds to take the main thumbnail from |

### `bunny stream videos fetch`

Have bunny.net download a video from a URL, server side. See [URL Fetch](/docs/stream/url-fetch).

```bash theme={null}
bunny stream videos fetch https://example.com/video.mp4

# Send a header to an origin that needs authentication
bunny stream videos fetch https://example.com/video.mp4 --header "Authorization: Bearer <token>"
```

`videos fetch` takes the same flags as `videos upload`, plus `--header "Name: value"` (repeatable).

### `bunny stream videos list`

List the videos in a library with their ID, title, status, size, length, views, and upload date.

```bash theme={null}
bunny stream videos list
bunny stream videos list --search launch
bunny stream videos list --collection <collection-id>
```

### `bunny stream videos show`

Show one video's details, including its caption languages and Direct Play URL.

```bash theme={null}
bunny stream videos show <video-id>
```

### `bunny stream videos update`

Change a video's title, collection, chapters, or moments.

```bash theme={null}
bunny stream videos update <video-id> --title "Launch keynote"
bunny stream videos update <video-id> --collection <collection-id>
bunny stream videos update <video-id> --chapters '[{"title":"Intro","start":0,"end":30}]'
bunny stream videos update <video-id> --moments '[{"label":"Demo","timestamp":42}]'
```

Pass `--collection ""` to remove the video from its collection.

### `bunny stream videos thumbnail`

Set a video's thumbnail from a local file or a URL.

```bash theme={null}
bunny stream videos thumbnail <video-id> --file ./thumb.jpg
bunny stream videos thumbnail <video-id> --url https://example.com/thumb.jpg
```

### `bunny stream videos embed`

Print the player embed URL. When the library requires [embed view tokens](/docs/stream/token-authentication), the URL is signed.

```bash theme={null}
bunny stream videos embed <video-id>

# Signed URL valid for 30 minutes (default 1h)
bunny stream videos embed <video-id> --expires 30m
```

### `bunny stream videos stats`

Show a video's views and watch time. See [Statistics](/docs/stream/statistics).

```bash theme={null}
bunny stream videos stats <video-id>
bunny stream videos stats <video-id> --from 2026-08-01 --to 2026-08-31 --hourly
bunny stream videos stats <video-id> --heatmap
bunny stream videos stats <video-id> --play-data
```

The range defaults to the last 30 days.

### `bunny stream videos resolutions`

Show which resolutions the library enables, and which ones the video has encoded and stored.

```bash theme={null}
bunny stream videos resolutions <video-id>
```

### `bunny stream videos cleanup`

Delete encoded resolutions, MP4 fallback files, or the stored original to free up storage.

```bash theme={null}
# Preview deleting resolutions the library no longer enables
bunny stream videos cleanup <video-id> --non-configured --dry-run

# Delete specific resolutions
bunny stream videos cleanup <video-id> --resolutions 240p,360p

# Delete the original file
bunny stream videos cleanup <video-id> --original --force
```

| Flag | Description |
| - | - |
| `--resolutions` | Resolutions to delete, comma-separated |
| `--non-configured` | Delete resolutions the library doesn't enable |
| `--all` | Delete every encoded resolution |
| `--original` | Delete the stored original file |
| `--mp4` | Delete the MP4 fallback files |
| `--outputs` | Outputs to clean: `hls`, `mp4`, or `all` |
| `--dry-run` | Show what would be deleted without deleting anything |
| `--force`, `-f` | Skip the confirmation |

### `bunny stream videos delete`

```bash theme={null}
bunny stream videos delete <video-id>
bunny stream videos delete <video-id> --force
```

***

## Captions

`bunny stream videos captions` uploads your own `.vtt` or `.srt` caption file for one language, or removes one.

```bash theme={null}
# Upload a file, then pick the video and type the language
bunny stream videos captions add ./captions.vtt

# Upload for a given video and language
bunny stream videos captions add ./captions.vtt <video-id> en
bunny stream videos captions add ./de.srt <video-id> de --label "Deutsch"

# Remove a language
bunny stream videos captions remove <video-id> en
```

`captions add` takes the caption file first, then the video and the language code. The player shows `--label` in its caption menu, and it defaults to the language code. When you leave out the language, `captions remove` lets you pick one of the video's caption languages. Pass `--force` to skip the confirmation, which is required when running non-interactively.

To generate captions from the audio instead, use [`bunny stream videos transcribe`](#bunny-stream-videos-transcribe).

***

## Encoding

### Turn on Premium Encoding

Switch a library to [Premium Encoding](/docs/stream/premium-encoding) with `libraries update`. Set the codecs, resolutions, and just-in-time encoding in the same command.

```bash theme={null}
bunny stream libraries update my-library --encoding-tier premium --jit --codecs x264,vp9 --resolutions 720p,1080p
```

### `bunny stream videos encode`

Re-encode a video with the library's current encoding settings. It works from the stored original file, so the library needs `--keep-original` turned on when the video was uploaded.

```bash theme={null}
bunny stream videos encode <video-id>
```

Re-encoding is billed like the original encode. If the library transcribes new uploads automatically, the video is transcribed again too.

***

## Transcribing and Smart Generate

Both commands are billed. `videos transcribe` prints a cost estimate when it queues the job. See [Stream pricing](/docs/stream/pricing).

### `bunny stream videos transcribe`

Transcribe a video's audio into captions with [transcribing](/docs/stream/transcribing).

```bash theme={null}
# Use the library's transcribing defaults
bunny stream videos transcribe <video-id>

# Transcribe into two languages and generate a title
bunny stream videos transcribe <video-id> --target-languages en,de --source-language en --generate-title
```

| Flag | Description |
| - | - |
| `--target-languages` | Target languages, comma-separated ISO 639-1 codes |
| `--source-language` | Language spoken in the video, as an ISO 639-1 code |
| `--generate-title` | Generate the title from the transcript |
| `--generate-description` | Generate the description from the transcript |
| `--generate-chapters` | Generate chapters from the transcript |
| `--generate-moments` | Generate moments from the transcript |
| `--overwrite` | Overwrite the existing transcription and override the library's transcribing defaults |

### `bunny stream videos smart`

Generate a title, description, chapters, or moments from a video's existing captions with [Smart Generate](/docs/stream/smart-generate).

```bash theme={null}
bunny stream videos smart <video-id> --title --description
bunny stream videos smart <video-id> --chapters --moments

# Transcribe first if the video has no captions (billed)
bunny stream videos smart <video-id> --chapters --transcribe
```

| Flag | Description |
| - | - |
| `--title` | Generate the title |
| `--description` | Generate the description |
| `--chapters` | Generate chapters |
| `--moments` | Generate moments |
| `--source-language` | Caption track to generate from, such as `en` |
| `--transcribe` | Transcribe first if the video has no captions. Required to do so non-interactively. |
| `--force`, `-f` | Never fall back to a picker, so the run only acts on the library and video you named |

***

## Collections

`bunny stream collections` also answers to `collection`. Organize a library's videos into [collections](/docs/stream/collections). Add a video to one with `--collection` on `videos upload`, `videos fetch`, or `videos update`.

```bash theme={null}
bunny stream collections list
bunny stream collections create Tutorials
bunny stream collections show <collection-id>
bunny stream collections update <collection-id> --name "Getting started"
bunny stream collections delete <collection-id>
```

<Warning>
  Deleting a collection also deletes every video inside it.
</Warning>

***

## Importing from another platform

`bunny stream import` moves an existing video library into Stream from Vimeo, AWS S3 (or an S3-compatible provider), Wistia, Mux, Cloudflare Stream, JW Player, or Brightcove. bunny.net fetches each file directly from the source, so nothing passes through your machine. Source folders become Stream collections of the same name.

For a full walkthrough, see the migration guides for [Vimeo](/docs/stream/migrate-from-vimeo), [Mux](/docs/stream/migrate-from-mux), and [Cloudflare Stream](/docs/stream/migrate-from-cloudflare-stream).

```bash theme={null}
# See folders, video counts, and what's already in Stream
bunny stream import --library 12345 --source vimeo --dry-run

# Import
bunny stream import --library 12345 --source vimeo --force

# Check encoding progress
bunny stream import status --library 12345 --source vimeo

# Continue an interrupted or partly failed run
bunny stream import --library 12345 --source vimeo --resume --force
```

You can run an import again safely. It skips finished videos, leaves videos that are still encoding, and imports failed ones again.

### Source credentials

The CLI reads the source's credentials from environment variables and never takes them as flags. In an interactive run, it asks for any required value that isn't set, then offers to save what you typed for the active CLI profile, so later runs don't ask again.

If you leave out `--source`, the CLI uses the one source whose credentials are all set, and otherwise asks you to pick one.

| Source | Environment variables |
| - | - |
| `vimeo` | `VIMEO_ACCESS_TOKEN` with the `public`, `private`, and `video_files` scopes. Downloads need a Vimeo Standard plan or above. |
| `s3` | `S3_BUCKET`, `AWS_REGION` or `AWS_DEFAULT_REGION` (default `us-east-1`). Optional: `S3_PREFIX`, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`, `S3_PRESIGNED_URL_TTL`, `S3_ENDPOINT` or `AWS_ENDPOINT_URL_S3`, `S3_INCLUDE_TS` |
| `wistia` | `WISTIA_ACCESS_TOKEN` |
| `mux` | `MUX_TOKEN_ID`, `MUX_TOKEN_SECRET` |
| `cloudflare` | `CLOUDFLARE_API_TOKEN` with Stream:Edit, `CLOUDFLARE_ACCOUNT_ID` |
| `jwplayer` | `JWPLAYER_API_KEY` (v2), `JWPLAYER_SITE_ID` |
| `brightcove` | `BRIGHTCOVE_CLIENT_ID`, `BRIGHTCOVE_CLIENT_SECRET` with CMS video read, `BRIGHTCOVE_ACCOUNT_ID` |

For S3, leave both AWS keys unset to use the default AWS credential chain, such as a profile, SSO, or an instance role. The IAM policy needs `s3:ListBucket` and `s3:GetObject`.

### `bunny stream import`

| Flag | Description |
| - | - |
| `--library`, `--lib` | Destination library name or ID |
| `--source`, `-s` | `vimeo`, `s3`, `wistia`, `mux`, `cloudflare`, `jwplayer`, or `brightcove` |
| `--folder` | Import one source folder only. Not available for Mux, Cloudflare Stream, or JW Player. |
| `--dry-run` | Print the plan without writing anything |
| `--resume` | Continue the saved import for this source and library |
| `--wait` | Stay until every video has encoded, instead of returning once they're queued |
| `--clean-failed` | Delete failed copies in Stream before importing them again |
| `--retry-stalled` | Delete and import again videos stuck at zero bytes |
| `--force`, `-f` | Skip the confirmation. Required when running non-interactively. |
| `--concurrency`, `-c` | Videos handed to Stream in parallel, 1 to 20 (default 3) |
| `--bucket`, `--prefix`, `--url-ttl` | S3 overrides for one run. `--url-ttl` takes 3600 to 604800 seconds. |
| `--include-ts` | S3: import `.ts` files too |
| `--request-timeout` | Seconds per HTTP request (default 30) |
| `--video-timeout` | Seconds per video hand-off, or per encode with `--wait` (default 5400) |
| `--processing-timeout` | With `--wait`, seconds per encode (default 3600) |

The command exits `0` when every video was queued, `1` when any video failed, and `130` when you press Ctrl-C. After Ctrl-C, it prints the `--resume` command to continue.

### `bunny stream import list`

Browse a source's folders and videos before importing.

```bash theme={null}
bunny stream import list --source vimeo
bunny stream import list --source vimeo --videos
bunny stream import list --source vimeo --folder 987654
```

### `bunny stream import status`

Show Stream's encoding status for every video an import queued. It exits `1` when any video failed, so you can poll it from a script.

```bash theme={null}
bunny stream import status --library 12345 --source vimeo
```

A video still processing with no data after 30 minutes is marked `(stalled?)`. Run the import again with `--retry-stalled` to replace it.


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