Bind to Workers API (2)
Last updated May 7, 2026 A binding connects your Worker to external resources on the Developer Platform, like Stream, R2 buckets, or KV namespaces.
For example, when you use Stream within Workers, you can:
- Upload videos from a URL and manage their lifecycle
- Create direct uploads for client-side uploads without having to expose API keys
- List and search videos
- Manage captions and downloads for videos
- Create and manage watermark profiles
Setup
The Stream binding is enabled on a per-Worker basis.
To bind Stream to your Worker, add the following to the end of your Wrangler configuration file:
{
"stream": {
"binding": "STREAM"
}
}
[stream]
binding = "STREAM"
For more detailed information on configuring your Worker, refer to the Wrangler Configuration documentation.
Methods
Binding-level methods
The following methods are available on the env.STREAM binding directly.
upload(url, params?)
Upload a video from a URL. Returns Promise<StreamVideo>.
url(required): The URL of the video to upload.params(optional): AStreamUrlUploadParamsobject with the following properties:allowedOrigins: Array of allowed origins for the video.creator: Creator identifier.meta: Arbitrary metadata object.requireSignedURLs: Whether signed URLs are required.scheduledDeletion: ISO 8601 timestamp for scheduled deletion.thumbnailTimestampPct: Thumbnail timestamp as a percentage (0.0 to 1.0).watermarkId: ID of a watermark profile to apply.
Throws: BadRequestError, QuotaReachedError, MaxFileSizeError, RateLimitedError, AlreadyUploadedError, InternalError.
createDirectUpload(params)
Create a basic direct upload URL for client-side uploads without an API key. Returns Promise<StreamDirectUpload> with uploadURL and id.
This method does not currently support files over 200MB. For larger direct uploads, refer to the API request for provisioning a TUS endpoint ↗︎._
params(required): AStreamDirectUploadCreateParamsobject with the following properties:maxDurationSeconds(required): Maximum duration of the uploaded video in seconds.expiry(optional): ISO 8601 timestamp when the upload URL expires.creator(optional): Creator identifier.meta(optional): Arbitrary metadata object.allowedOrigins(optional): Array of allowed origins for the video.requireSignedURLs(optional): Whether signed URLs are required.thumbnailTimestampPct(optional): Thumbnail timestamp as a percentage (0.0 to 1.0).scheduledDeletion(optional): ISO 8601 timestamp for scheduled deletion.watermark(optional): ID of a watermark profile to apply.
videos.list(params?)
List all videos in the account. Returns Promise<StreamVideo[]>.
params(optional): AStreamVideosListParamsobject with the following properties:limit: Maximum number of videos to return.before: Return videos created before this ISO 8601 timestamp.beforeComp: Comparison operator forbefore—eq,gt,gte,lt, orlte.after: Return videos created after this ISO 8601 timestamp.afterComp: Comparison operator forafter—eq,gt,gte,lt, orlte.
Video-scoped methods
Calling env.STREAM.video(id) returns a handle scoped to a single video, with the following methods.
details()
Get full video details. Returns Promise<StreamVideo>.
update(params)
Update video metadata. Returns Promise<StreamVideo>.
params(required): AStreamUpdateVideoParamsobject with the following properties:allowedOrigins: Array of allowed origins for the video.creator: Creator identifier.maxDurationSeconds: Maximum duration in seconds.meta: Arbitrary metadata object.requireSignedURLs: Whether signed URLs are required.scheduledDeletion: ISO 8601 timestamp for scheduled deletion.thumbnailTimestampPct: Thumbnail timestamp as a percentage (0.0 to 1.0).
delete()
Delete a video and its copies. Returns Promise<void>.
generateToken()
Create a signed URL token for a video. Returns Promise<string>.
downloads
Namespace for download operations on a video.
generate(downloadType?): Generate a download.downloadTypeis aStreamDownloadTypeofdefaultoraudio. Defaults todefault. ReturnsPromise<StreamDownloadGetResponse>.get(): List existing downloads. ReturnsPromise<StreamDownloadGetResponse>.delete(downloadType?): Delete downloads.downloadTypeisdefaultoraudio.
captions
Namespace for caption operations on a video.
upload(language, input): Upload a caption file for a BCP 47 language tag.inputis aReadableStream. ReturnsPromise<StreamCaption>.generate(language): Generate captions via AI for a BCP 47 language tag. ReturnsPromise<StreamCaption>.list(language?): List captions, optionally filtered by language. ReturnsPromise<StreamCaption[]>.delete(language): Delete captions for a language. ReturnsPromise<void>.
Watermark methods
The following methods are available on the env.STREAM.watermarks namespace.
watermarks.generate(input, params)
Create a watermark profile. Accepts either a ReadableStream or a URL string. Returns Promise<StreamWatermark>.
input(required): AReadableStreamor URL string of the watermark image.params(optional): AStreamWatermarkCreateParamsobject with the following properties:name: Name of the watermark profile.opacity: Opacity of the watermark (0.0 to 1.0).padding: Padding around the watermark as a proportion of the video resolution.scale: Scale of the watermark as a proportion of the video resolution.position: Position of the watermark —upperRight,upperLeft,lowerLeft,lowerRight, orcenter.
watermarks.list()
List all watermark profiles. Returns Promise<StreamWatermark[]>.
watermarks.get(watermarkId)
Get a single watermark profile. Returns Promise<StreamWatermark>.
watermarkId(required): The ID of the watermark profile.
watermarks.delete(watermarkId)
Delete a watermark profile. Returns Promise<void>.
watermarkId(required): The ID of the watermark profile.
Examples
Upload a video from a URL
export default {
async fetch(request, env) {
const video = await env.STREAM.upload("https://example.com/video.mp4", {
creator: "user-123",
meta: { category: "tutorial" },
allowedOrigins: ["example.com"],
});
return Response.json(video);
},
};
export default {
async fetch(request, env) {
const video = await env.STREAM.upload("https://example.com/video.mp4", {
creator: "user-123",
meta: { category: "tutorial" },
allowedOrigins: ["example.com"],
});
return Response.json(video);
},
};
Create a direct upload
export default {
async fetch(request, env) {
const directUpload = await env.STREAM.createDirectUpload({
maxDurationSeconds: 300,
creator: "user-123",
meta: { source: "browser-upload" },
});
return Response.json(directUpload);
},
};
export default {
async fetch(request, env) {
const directUpload = await env.STREAM.createDirectUpload({
maxDurationSeconds: 300,
creator: "user-123",
meta: { source: "browser-upload" },
});
return Response.json(directUpload);
},
};
List videos
export default {
async fetch(request, env) {
const videos = await env.STREAM.videos.list({
limit: 10,
after: "2025-01-01T00:00:00Z",
});
return Response.json(videos);
},
};
export default {
async fetch(request, env) {
const videos = await env.STREAM.videos.list({
limit: 10,
after: "2025-01-01T00:00:00Z",
});
return Response.json(videos);
},
};
Get video details
export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").details();
return Response.json(videoDetails);
},
};
export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").details();
return Response.json(videoDetails);
},
};
Update video metadata
export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").update({
meta: { category: "updated-tutorial" },
allowedOrigins: ["example.com", "*.example.com"],
});
return Response.json(videoDetails);
},
};
export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").update({
meta: { category: "updated-tutorial" },
allowedOrigins: ["example.com", "*.example.com"],
});
return Response.json(videoDetails);
},
};
Delete a video
export default {
async fetch(request, env) {
await env.STREAM.video("VIDEO_ID").delete();
return new Response("Video deleted", { status: 200 });
},
};
export default {
async fetch(request, env) {
await env.STREAM.video("VIDEO_ID").delete();
return new Response("Video deleted", { status: 200 });
},
};
Generate a signed URL token
export default {
async fetch(request, env) {
const token = await env.STREAM.video("VIDEO_ID").generateToken();
return Response.json({ token });
},
};
export default {
async fetch(request, env) {
const token = await env.STREAM.video("VIDEO_ID").generateToken();
return Response.json({ token });
},
};
Upload captions
export default {
async fetch(request, env) {
const captionResponse = await fetch("https://example.com/captions-en.vtt");
const caption = await env.STREAM.video("VIDEO_ID").captions.upload(
"en",
captionResponse.body,
);
return Response.json(caption);
},
};
export default {
async fetch(request, env) {
const captionResponse = await fetch("https://example.com/captions-en.vtt");
const caption = await env.STREAM.video("VIDEO_ID").captions.upload(
"en",
captionResponse.body,
);
return Response.json(caption);
},
};
Generate AI captions
export default {
async fetch(request, env) {
const caption = await env.STREAM.video("VIDEO_ID").captions.generate("en");
return Response.json(caption);
},
};
export default {
async fetch(request, env) {
const caption = await env.STREAM.video("VIDEO_ID").captions.generate("en");
return Response.json(caption);
},
};
List and delete captions
export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const captions = await video.captions.list();
await video.captions.delete("en");
return Response.json(captions);
},
};
export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const captions = await video.captions.list();
await video.captions.delete("en");
return Response.json(captions);
},
};
Generate and list downloads
export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const downloads = await video.downloads.generate();
const audioDownloads = await video.downloads.generate("audio");
const allDownloads = await video.downloads.get();
return Response.json({ downloads, audioDownloads, allDownloads });
},
};
export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const downloads = await video.downloads.generate();
const audioDownloads = await video.downloads.generate("audio");
const allDownloads = await video.downloads.get();
return Response.json({ downloads, audioDownloads, allDownloads });
},
};
Create a watermark profile
export default {
async fetch(request, env) {
const watermark = await env.STREAM.watermarks.generate(
"https://example.com/watermark.png",
{
name: "My Watermark",
opacity: 0.5,
position: "lowerRight",
padding: 0.05,
scale: 0.1,
},
);
return Response.json(watermark);
},
};
export default {
async fetch(request, env) {
const watermark = await env.STREAM.watermarks.generate(
"https://example.com/watermark.png",
{
name: "My Watermark",
opacity: 0.5,
position: "lowerRight",
padding: 0.05,
scale: 0.1,
},
);
return Response.json(watermark);
},
};
List and delete watermark profiles
export default {
async fetch(request, env) {
const watermarks = await env.STREAM.watermarks.list();
const watermark = await env.STREAM.watermarks.get("WATERMARK_ID");
await env.STREAM.watermarks.delete("WATERMARK_ID");
return Response.json({ watermarks, watermark });
},
};
export default {
async fetch(request, env) {
const watermarks = await env.STREAM.watermarks.list();
const watermark = await env.STREAM.watermarks.get("WATERMARK_ID");
await env.STREAM.watermarks.delete("WATERMARK_ID");
return Response.json({ watermarks, watermark });
},
};
Type definitions
StreamVideo
StreamVideo is returned by operations that retrieve or create a video. It contains the full metadata for a video.
idstring- The unique identifier for the video.
creatorstring | null- A user-defined identifier for the media creator.
thumbnailstring- The thumbnail URL for the video.
thumbnailTimestampPctnumber- The thumbnail timestamp percentage.
readyToStreamboolean- Indicates whether the video is ready to stream.
readyToStreamAtstring | null- The date and time the video became ready to stream.
statusStreamVideoStatus- Processing status information. Refer to StreamVideoStatus.
metaRecord<string, string>- A user modifiable key-value store.
createdstring- The date and time the video was created.
modifiedstring- The date and time the video was last modified.
scheduledDeletionstring | null- The date and time at which the video will be deleted.
sizenumber- The size of the video in bytes.
previewstringoptional- The preview URL for the video.
allowedOriginsArray<string>- Origins allowed to display the video.
requireSignedURLsboolean | null- Indicates whether signed URLs are required.
uploadedstring | null- The date and time the video was uploaded.
uploadExpirystring | null- The date and time when the upload URL expires.
maxSizeBytesnumber | null- The maximum size in bytes for direct uploads.
maxDurationSecondsnumber | null- The maximum duration in seconds for direct uploads.
durationnumber- The video duration in seconds.
-1indicates unknown. inputStreamVideoInput- Input metadata for the original upload. Refer to StreamVideoInput.
hlsPlaybackUrlstring- The HLS playback URL for the video.
dashPlaybackUrlstring- The DASH playback URL for the video.
watermarkStreamWatermark | null- The watermark applied to the video, if any. Refer to StreamWatermark.
liveInputIdstring | nulloptional- The live input ID associated with the video, if any.
clippedFromIdstring | null- The source video ID if this is a clip.
publicDetailsStreamPublicDetails | null- Public details associated with the video. Refer to StreamPublicDetails.
