How it works:
1
Request
The admin UI calls
POST /api/storage-bunny/stream/tus-auth with the target collection and file info.2
Authorize
The plugin checks access (via
checkAccess or the default rule) and the file. It rejects a type outside the collection’s upload.mimeTypes or the Stream mimeTypes, a restricted type (HTML, scripts, SVG or XML) and a file over Payload’s upload.limits.fileSize, whatever checkAccess returns. Then it creates the video in Bunny Stream and returns a signed TUS authorization. The response also contains a videoToken that is bound to the video, the collection, the library and the signed-in user. It expires after 24 hours.3
Upload
The browser uploads directly to Bunny using the TUS protocol.
4
Save
The admin UI saves the document with
bunnyData.stream.videoId and bunnyData.stream.videoToken. Payload only accepts a videoId that comes with a matching videoToken. To resume an upload, send both values to tus-auth again. Without a valid token, tus-auth creates a new video. Payload also rejects a videoId that another document in a Stream collection of the same library already uses.5
Track (optional)
If
cleanup is enabled, the plugin tracks the upload in a hidden bunny-stream-upload-sessions collection until it completes.Bulk uploads and form saves
Payload’s bulk upload drawer opens from the list view’s Bulk Upload button and whenever a file is dropped or pasted on an upload field. The drawer has no TUS controls. Instead, videos saved there, and videos saved from the edit view without switching to TUS mode, go to Bunny Stream over TUS through Payload’s client upload handler. The document is created only after the upload finishes. Video bytes never pass through your server, so a request body cap (Vercel’s 4.5 MB) doesn’t apply. This covers collections that store files only in Stream (storage: false). A collection that also stores files in Bunny Storage needs client uploads enabled for the same effect, because the handler must take every file, not only videos. Without them, those saves upload through your server as before.
Uploads through your server are multipart form data. Payload limits them to 20 MB per file and 50 MB per request by default. Change them with upload.limits.fileSize and upload.requestSizeLimit in your Payload config, or use TUS or client uploads for large files.
These uploads show Payload’s own progress overlay and don’t resume after a dropped connection. Use TUS mode in the edit view for that.
If the save fails after the video has uploaded, the video stays in your Stream library. Enable cleanup to remove such videos automatically.