Skip to main content
Run bunny skills install --global so AI coding agents, such as Claude Code, Cursor, and Codex, can run this migration for you. Then ask your agent: “Migrate my Wistia videos to Bunny Stream.”
bunny stream import is in Public Preview and still in development. Commands, flags, and output may change, so what you see can differ from the examples in this guide. To report a bug, open an issue on the Bunny CLI repository.
Bunny Stream bills only for the storage and bandwidth you use. See the Bunny Stream pricing page for current rates.

Overview

Diagram of the Bunny CLI listing Wistia folders and videos and Bunny Stream fetching each file directly from Wistia
The Bunny CLI lists every video in your Wistia folders and hands each one to Bunny Stream, which fetches the best available file directly from Wistia. Nothing is downloaded to your machine. Each Wistia folder becomes a Bunny Stream collection with the same name. Each imported video is tagged with its Wistia media ID under the wistiaId metatag, so running the import again skips videos that are already imported.

Scope

The import copies the video files, their names and descriptions, and your folder structure. Settings that control who can watch your videos and how the player looks stay on Wistia, so plan to set up their Bunny equivalents.
Protected Wistia videos are not protected on Bunny. The import copies every video your token can read, but not its privacy settings. Every imported video follows the security settings of its Bunny library, and a new library allows playback from any site. On Bunny, a video that was password protected or restricted to certain domains on Wistia plays for anyone with its URL until you protect the library. Before you publish the new URLs, set up Allowed domains to replace Wistia’s domain restrictions, and turn on embed view token authentication or CDN token authentication for videos that only signed-in viewers should see. If the videos that need protection are in their own Wistia folders, you can import those folders into a separate library with --folder and give that library stricter settings.

Prerequisites

  • A bunny.net account
  • A Wistia account on any plan, including the Free plan. Only the Account Owner can create API tokens, so ask them for a token if you are not the owner.

Migrate your videos

1

Install and authenticate the Bunny CLI

Install the Bunny CLI with the shell installer or npm:
The installer downloads a prebuilt binary for your platform and places it on your PATH.
See Installation for more options. Then authenticate the CLI with your bunny.net account:
bunny login opens your browser to complete authentication and stores the credentials locally. The first time you log in from an interactive terminal, it also offers to install the agent skill for AI coding tools. On a remote machine or in CI without a browser, run bunny login --api-key "$BUNNYNET_API_KEY" instead, with a key from Account Settings > API key.
2

Create a Bunny Stream library

Create a library for the imported videos, or skip this step to use an existing one:
DE is always the main storage region. Replicate to the regions closest to your audience, from UK, SE, NY, LA, SG, SYD, BR, and JH. You can’t remove a replication region later.
Set encoding options, such as --resolutions or --encoding-tier, when you create the library. Changes you make later apply only to new uploads, not to videos that are already imported. Run bunny stream libraries create --help to see every option, or read Encoding.
When the CLI asks how to add videos, choose Later. You start the import in the next steps.Copy the library ID from the output. You pass it to --library in the import commands. The flag also accepts the library’s name, and --lib works as a short alias.
3

Create a Wistia API token

The Bunny CLI needs a Wistia API token with the Read all data permission, which lets it list your folders and videos and read the file URLs for each video. The CLI never changes anything on Wistia.In Wistia, open Settings and go to API Tokens, at https://<account_slug>.wistia.com/account/api, where <account_slug> is your Wistia account’s subdomain. Click New token.
The API Tokens page in Wistia Settings with the New token button
Enter a token nickname, such as Migrate to Bunny, and under Permissions check Read all data. Wistia checks Read all folder and media data and Read detailed stats along with it. Click Create token.
The New API token dialog in Wistia with Read all data checked
Copy the token with the copy button next to it. Wistia shows a token only once, so if you leave or refresh the page before copying it, create a new one.
The New API token dialog in Wistia showing the created token and its copy button
4

Preview the migration with a dry run

Run the import with --dry-run, using the library ID from step 2:
--dry-run prints the import plan without making any changes to either platform.The CLI then prompts for your Wistia API token. Paste it at the API Token prompt:
Once Wistia accepts the token, the CLI offers to save it so later runs skip this prompt. Press Enter to accept:
The CLI stores saved credentials in ~/.config/bunnynet/stream-import-credentials.json (or under $XDG_CONFIG_HOME/bunnynet/ when it is set). Only your user account can read the file, and it is separate from the main Bunny CLI config. Saved credentials belong to the active Bunny CLI profile. If Wistia later rejects them, for example after you revoke the token, the CLI deletes them and prompts again on the next run. If you answer no, the CLI prompts on every run.The WISTIA_ACCESS_TOKEN environment variable always takes priority over a saved token.
The dry run then prints a summary and the import plan:
Already imported counts videos that are already in the library, and To import counts the ones a real run would import. The plan groups videos by the collection they will land in, and each Wistia folder maps to a collection of the same name.Bunny Stream accepts sources up to 2160p (3840x2160, or 2160x3840 in portrait) and up to 72 hours long. Wistia reports the resolution of each original upload, so the dry run warns about any video beyond those limits, as it will fail on Bunny:
The dry run does not check whether Wistia has finished processing each video. A video that is still queued, processing, or failed on Wistia appears in the plan and fails during the import, so let Wistia finish processing recent uploads before you run it.
5

Run the import

Run the same command without --dry-run:
The CLI prints the same summary, then asks for confirmation. Type y and press Enter to start:
The CLI creates a collection for each folder, skips videos that are already imported, hands the rest to Bunny three at a time, and tags each video with wistiaId, along with its Wistia description. It returns once every video is queued. Bunny then fetches each file directly from Wistia and encodes it.
Collection names match without regard to case, so Wistia folders named Webinars and webinars land in one collection. Rename one of them in Wistia before the import to keep them separate.The import command also accepts these flags:
  • --wait keeps the command running, with a live encoding progress indicator, until Bunny has encoded every video.
  • --force skips the confirmation prompt and the offer to retry failed videos, for unattended or CI runs.
  • --concurrency N sets how many videos the CLI passes to Bunny in parallel, from 1 to 20.
  • --clean-failed deletes the failed Bunny copies of videos before importing them again, including videos that Bunny rejected.
  • --retry-stalled deletes and imports again any video stuck at zero bytes on Bunny.
  • --request-timeout sets how many seconds one request to Wistia or Bunny can take before it gives up (default 30).
  • --video-timeout sets how many seconds the hand-off of one video to Bunny, or with --wait its encoding, can take before it gives up (default 5400).
Run bunny stream import --help for the full list.To migrate a large account one folder at a time, list the folders and their IDs:
The ID is the folder’s hashed ID, the same one that appears in the folder’s Wistia URL. The Videos column is Wistia’s media count for the folder, so it also counts images and audio files that the import skips.Preview a folder’s videos with --folder, then pass the same ID to the import:
The import works the same way, limited to that folder’s videos and its collection.
6

Watch encoding progress

The import returns before Bunny finishes encoding. Check progress with the status command:
It prints one row per queued video, with its status on Bunny, encode percentage, size, and when it was queued:
Run it again until the last line reports 0 processing. The command exits with a non-zero code when any video has failed, so you can also use it as a check in scripts.
7

Verify in the bunny.net dashboard

Open the bunny.net dashboard and go to Stream > Your library > Manage library. Each Wistia folder appears as a collection, and every migrated video is listed under Latest videos.
The Manage library page in the bunny.net dashboard showing the imported collections and videos
Set up the library’s security settings if you have not already, then replace the Wistia embeds (embed codes and iframes loaded from fast.wistia.com or fast.wistia.net) and links in your site with their Bunny Stream equivalents. See Embedding videos for the embed and player options.

Troubleshooting

When videos fail during an interactive import, the CLI lists each failure and offers to retry them:
Answer y to retry them in the same run. If the import was interrupted, or you declined the retry, run it again with --resume:
--resume retries failed videos, processes any that were still outstanding, and re-applies the wistiaId tag to videos Bunny fetched before the run stopped. When the interrupted run was limited to one folder, the resume continues that folder. It stops retrying a video after three failed attempts and skips videos that Bunny rejected. To retry those too, add --clean-failed, which deletes their Bunny copies first.Running the import again is always safe. Videos that already carry the wistiaId tag are skipped, and the CLI reports Everything is already imported once nothing is left.
Wistia has not finished processing the video, or processing failed. The error names the status Wistia reports: queued, processing, or failed. Wait until the video plays in Wistia, then retry. A video that failed on Wistia needs to be uploaded to Wistia again, or uploaded to Bunny directly with bunny stream videos upload.
Wistia returned no file for that video, or the video was deleted from Wistia after the import started. Check that the video still exists in Wistia and plays there, then retry.
Wistia rejected the token. Check that you copied the whole value, then run the command again to re-enter it. If Wistia answers with Wistia refused the access token (403) instead, the token exists but lacks the Read all data permission. Edit the token’s permissions on the API Tokens page of your Wistia Settings, or create a new one.
--folder takes the folder’s hashed ID, not its numeric ID. Use the ID the error suggests, or the one in the ID column of bunny stream import list --source wistia.
If bunny stream import status reports videos stuck at zero bytes, run the import again with --retry-stalled to delete and fetch them again.

Migrate more than one Wistia account

Wistia API tokens belong to a single account. To migrate several accounts, repeat steps 2 to 7 for each one, with a token created in that account. Import each account into its own Bunny library. The CLI keeps one saved import per source and library, so a separate library keeps each account’s progress, --resume, and status apart. The CLI saves one Wistia token per Bunny CLI profile, and uses it without prompting for the next account. Point the CLI at the next account’s token in one of these ways:
  • Set WISTIA_ACCESS_TOKEN in your shell. Environment variables always take priority over saved credentials.
  • Run the import with a different Bunny CLI profile, using --profile.
Last modified on November 5, 2026