Bind to Workers API
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
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.
The following methods are available on the env.STREAM binding directly.
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.
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.
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.
Calling env.STREAM.video(id) returns a handle scoped to a single video, with the following methods.
Get full video details. Returns Promise<StreamVideo>.
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 a video and its copies. Returns Promise<void>.
Create a signed URL token for a video. Returns Promise<string>.
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.
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>.
The following methods are available on the env.STREAM.watermarks namespace.
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.
List all watermark profiles. Returns Promise<StreamWatermark[]>.
Get a single watermark profile. Returns Promise<StreamWatermark>.
watermarkId(required): The ID of the watermark profile.
Delete a watermark profile. Returns Promise<void>.
watermarkId(required): The ID of the watermark profile.
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); },};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); },};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); },};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); },};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); },};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 }); },};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 }); },};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); },};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); },};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); },};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 }); },};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); },};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 }); },};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.
- The video duration in seconds.
-
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.
Processing status information for a video.
-
statestring- The current processing state.
-
stepstringoptional- The current processing step.
-
pctCompletestringoptional- The percent complete as a string.
-
errorReasonCodestring- An error reason code, if applicable.
-
errorReasonTextstring- An error reason text, if applicable.
Input metadata for the original upload.
-
widthnumber- The input width in pixels.
-
heightnumber- The input height in pixels.
Public details associated with a video.
-
titlestring | null- The public title for the video.
-
share_linkstring | null- The public share link.
-
channel_linkstring | null- The public channel link.
-
logostring | null- The public logo URL.
Returned by createDirectUpload(). Contains the upload URL and video identifier for a direct upload.
-
uploadURLstring- The URL an unauthenticated upload can use for a single multipart request.
-
idstring- A Cloudflare-generated unique identifier for a media item.
-
watermarkStreamWatermark | null- The watermark profile applied to the upload. Refer to StreamWatermark.
-
scheduledDeletionstring | null- The scheduled deletion time, if any.
Represents a caption or subtitle track for a video.
-
generatedbooleanoptional- Whether the caption was generated via AI.
-
labelstring- The language label displayed in the native language to users.
-
languagestring- The language tag in BCP 47 format.
-
status'ready' | 'inprogress' | 'error'optional- The status of a generated caption.
An object with download type keys. Each key is optional and only present if that download type has been created.
-
defaultStreamDownloadoptional- The default video download. Only present if this download type has been created. Refer to StreamDownload.
-
audioStreamDownloadoptional- The audio-only download. Only present if this download type has been created. Refer to StreamDownload.
Represents a generated download for a video.
-
percentCompletenumber- Indicates the progress as a percentage between 0 and 100.
-
statusStreamDownloadStatus- The status of a generated download.
-
urlstringoptional- The URL to access the generated download.
Represents a watermark profile.
-
idstring- The unique identifier for a watermark profile.
-
namestring- A short description of the watermark profile.
-
opacitynumber- The translucency of the image. A value of
0.0makes the image completely transparent, and1.0makes the image completely opaque. Note that if the image is already semi-transparent, setting this to1.0will not make the image completely opaque.
- The translucency of the image. A value of
-
paddingnumber- The whitespace between the adjacent edges (determined by position) of the video and the image.
0.0indicates no padding, and1.0indicates a fully padded video width or length.
- The whitespace between the adjacent edges (determined by position) of the video and the image.
-
scalenumber- The size of the image relative to the overall size of the video.
0.0indicates no scaling, and1.0fills the entire video.
- The size of the image relative to the overall size of the video.
-
positionStreamWatermarkPosition- The location of the image. Refer to StreamWatermarkPosition.
-
sizenumber- The size of the image in bytes.
-
heightnumber- The height of the image in pixels.
-
widthnumber- The width of the image in pixels.
-
createdstring- The date and time a watermark profile was created.
-
downloadedFromstring | null- The source URL for a downloaded image. If the watermark profile was created via direct upload, this field is
null.
- The source URL for a downloaded image. If the watermark profile was created via direct upload, this field is
The position of a watermark on a video.
'upperRight' | 'upperLeft' | 'lowerLeft' | 'lowerRight' | 'center'
upperRight— Top-right corner of the video.upperLeft— Top-left corner of the video.lowerLeft— Bottom-left corner of the video.lowerRight— Bottom-right corner of the video.center— Center of the video. Note thatcenterignores thepaddingparameter.
The status of a generated download.
'ready' | 'inprogress' | 'error'
ready— The download is ready.inprogress— The download is being generated.error— An error occurred during generation.
The type of download to generate.
'default' | 'audio'
default— A video download.audio— An audio-only download.
Parameters for uploading a video from a URL.
-
allowedOriginsArray<string>optional- Lists the origins allowed to display the video. Enter allowed origin domains in an array and use
*for wildcard subdomains. Empty arrays allow the video to be viewed on any origin.
- Lists the origins allowed to display the video. Enter allowed origin domains in an array and use
-
creatorstringoptional- A user-defined identifier for the media creator.
-
metaRecord<string, string>optional- A user modifiable key-value store used to reference other systems of record for managing videos.
-
requireSignedURLsbooleanoptional- Indicates whether the video can be accessed using the ID. When set to
true, a signed token must be generated with a signing key to view the video.
- Indicates whether the video can be accessed using the ID. When set to
-
scheduledDeletionstring | nulloptional- Indicates the date and time at which the video will be deleted. Omit the field to indicate no change, or include with a
nullvalue to remove an existing scheduled deletion. If specified, must be at least 30 days from upload time.
- Indicates the date and time at which the video will be deleted. Omit the field to indicate no change, or include with a
-
thumbnailTimestampPctnumberoptional- The timestamp for a thumbnail image calculated as a percentage value of the video's duration. To convert from a second-wise timestamp to a percentage, divide the desired timestamp by the total duration of the video. If this value is not set, the default thumbnail image is taken from 0s of the video.
-
watermarkIdstringoptional- The identifier for the watermark profile.
Parameters for creating a direct upload.
-
maxDurationSecondsnumber- The maximum duration in seconds for a video upload.
-
expirystringoptional- The date and time after upload when videos will not be accepted.
-
creatorstringoptional- A user-defined identifier for the media creator.
-
metaRecord<string, string>optional- A user modifiable key-value store used to reference other systems of record for managing videos.
-
allowedOriginsArray<string>optional- Lists the origins allowed to display the video.
-
requireSignedURLsbooleanoptional- Indicates whether the video can be accessed using the ID. When set to
true, a signed token must be generated with a signing key to view the video.
- Indicates whether the video can be accessed using the ID. When set to
-
thumbnailTimestampPctnumberoptional- The timestamp for a thumbnail image calculated as a percentage value of the video's duration.
-
scheduledDeletionstring | nulloptional- The date and time at which the video will be deleted. Include
nullto remove a scheduled deletion.
- The date and time at which the video will be deleted. Include
-
watermarkStreamDirectUploadWatermarkoptional- The watermark profile to apply. Refer to StreamDirectUploadWatermark.
Watermark configuration for a direct upload.
-
idstring- The unique identifier for the watermark profile.
Parameters for updating a video.
-
allowedOriginsArray<string>optional- Lists the origins allowed to display the video. Enter allowed origin domains in an array and use
*for wildcard subdomains. Empty arrays allow the video to be viewed on any origin.
- Lists the origins allowed to display the video. Enter allowed origin domains in an array and use
-
creatorstringoptional- A user-defined identifier for the media creator.
-
maxDurationSecondsnumberoptional- The maximum duration in seconds for a video upload. Can be set for a video that is not yet uploaded to limit its duration. Uploads that exceed the specified duration will fail during processing. A value of
-1means the value is unknown.
- The maximum duration in seconds for a video upload. Can be set for a video that is not yet uploaded to limit its duration. Uploads that exceed the specified duration will fail during processing. A value of
-
metaRecord<string, string>optional- A user modifiable key-value store used to reference other systems of record for managing videos.
-
requireSignedURLsbooleanoptional- Indicates whether the video can be accessed using the ID. When set to
true, a signed token must be generated with a signing key to view the video.
- Indicates whether the video can be accessed using the ID. When set to
-
scheduledDeletionstring | nulloptional- Indicates the date and time at which the video will be deleted. Omit the field to indicate no change, or include with a
nullvalue to remove an existing scheduled deletion. If specified, must be at least 30 days from upload time.
- Indicates the date and time at which the video will be deleted. Omit the field to indicate no change, or include with a
-
thumbnailTimestampPctnumberoptional- The timestamp for a thumbnail image calculated as a percentage value of the video's duration. To convert from a second-wise timestamp to a percentage, divide the desired timestamp by the total duration of the video. If this value is not set, the default thumbnail image is taken from 0s of the video.
Parameters for listing videos.
-
limitnumberoptional- The maximum number of videos to return.
-
beforestringoptional- Return videos created before this timestamp (RFC3339/RFC3339Nano).
-
beforeCompStreamPaginationComparisonoptional- Comparison operator for the
beforefield. Defaults tolt. Refer to StreamPaginationComparison.
- Comparison operator for the
-
afterstringoptional- Return videos created after this timestamp (RFC3339/RFC3339Nano).
-
afterCompStreamPaginationComparisonoptional- Comparison operator for the
afterfield. Defaults togte. Refer to StreamPaginationComparison.
- Comparison operator for the
Comparison operators for pagination queries.
'eq' | 'gt' | 'gte' | 'lt' | 'lte'
eq— Equal togt— Greater thangte— Greater than or equal tolt— Less thanlte— Less than or equal to
Parameters for creating a watermark profile.
-
namestringoptional- A short description of the watermark profile.
-
opacitynumberoptional- The translucency of the image. A value of
0.0makes the image completely transparent, and1.0makes the image completely opaque. Note that if the image is already semi-transparent, setting this to1.0will not make the image completely opaque.
- The translucency of the image. A value of
-
paddingnumberoptional- The whitespace between the adjacent edges (determined by position) of the video and the image.
0.0indicates no padding, and1.0indicates a fully padded video width or length.
- The whitespace between the adjacent edges (determined by position) of the video and the image.
-
scalenumberoptional- The size of the image relative to the overall size of the video.
0.0indicates no scaling, and1.0fills the entire video.
- The size of the image relative to the overall size of the video.
-
positionStreamWatermarkPositionoptional- The location of the image. Refer to StreamWatermarkPosition.
Errors throw a StreamError, which extends the standard Error interface with additional information:
code: A numeric error code.statusCode: An HTTP status code.message: A description of the error.stack: Optional stack trace.
The following error subtypes may be thrown:
| Error type | Description |
|---|---|
InternalError | An internal server error occurred. |
BadRequestError | The request was malformed or contained invalid parameters. |
NotFoundError | The requested resource was not found. |
ForbiddenError | The request was not authorized. |
RateLimitedError | The request was rate limited. |
QuotaReachedError | The account has reached its video quota. |
MaxFileSizeError | The uploaded file exceeds the maximum allowed size. |
InvalidURLError | The provided URL is invalid or unreachable. |
AlreadyUploadedError | The video has already been uploaded. |
TooManyWatermarksError | The account has reached the watermark profile limit. |
Use a try...catch block to handle errors:
export default { async fetch(request, env) { try { const videoDetails = await env.STREAM.upload( "https://example.com/video.mp4", ); return Response.json(videoDetails); } catch (e) { if (e instanceof Error) { return new Response(`Stream error: ${e.message}`, { status: 500 }); } throw e; } },};export default { async fetch(request, env) { try { const videoDetails = await env.STREAM.upload("https://example.com/video.mp4"); return Response.json(videoDetails); } catch (e) { if (e instanceof Error) { return new Response(`Stream error: ${e.message}`, { status: 500 }); } throw e; } },};