Stream Clip API
Programmatically cut time ranges from a video already hosted on Cloudflare Stream into a new, permanent, independently deliverable video object.
Developer docs →
Media Transformations
Resize, reformat, and optimise any video or image hosted on R2 or any public URL on-the-fly at the edge — no Stream subscription required.
Developer docs →
Feature comparison
Which tool do you need?
Pick the right product before you build.
| Feature | Stream Clip API | Media Transformations |
|---|---|---|
| Video already on Stream | Yes — use this | No |
| Video on R2 / S3 / any URL | No | Yes |
| Creates a permanent new video | Yes | No — on-the-fly |
| Works without Stream upload | No | Yes |
| Needs Stream enabled | Yes | Zone only |
| Watermark support | Yes — profiles | No |
| File size upper limit | 30 GB per video | 100 MB per request |
Live demos
Four videos, two products
Cards 1–3 use Stream Clip API. Card 4 uses Media Transformations on an R2-hosted file.
Duration 65 min
Product Stream
UID e736e08b
1
Enable Cloudflare Stream on your account at
dash.cloudflare.com → Stream. Billing is per-minute stored + per-minute delivered.
2
Upload via API using a direct TUS upload or a URL-pull request:
curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/stream/copy" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-origin.com/video.mp4","meta":{"name":"My Video"}}'
3
Embed using the iframe URL returned in the upload response:
<iframe
src="https://customer-xxx.cloudflarestream.com/{UID}/iframe"
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture"
allowfullscreen>
</iframe>
Duration 3 min
Product Stream Clip API
UID de92efdc
1
Prerequisites: source video must already exist on Stream (you need its UID).
2
Create a clip by posting start/end times in seconds:
curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/stream/clip" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"clippedFromVideoUID": "{SOURCE_UID}",
"startTimeSeconds": 0,
"endTimeSeconds": 180,
"meta": {"name": "First 3 minutes"}
}'
3
Poll for readiness — the new UID in the response starts as
pendingupload.
Poll GET /stream/{NEW_UID} until status.state === "ready".
4
Embed the new UID exactly like any other Stream video.
Duration 3 min
Watermark upper right, 80%
UID 725b20ab
1
Upload your watermark image (PNG with transparency recommended) to create a reusable profile:
curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/stream/watermarks" \
-H "Authorization: Bearer {TOKEN}" \
-F file=@logo.png \
-F name="My Logo" \
-F opacity=0.8 \
-F position=upperRight \
-F scale=0.1
2
Save the watermark profile UID from the response — you'll pass it at clip creation time.
3
Create a clip with the watermark by including
watermark.uid:
curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/stream/clip" \
-H "Authorization: Bearer {TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"clippedFromVideoUID": "{SOURCE_UID}",
"startTimeSeconds": 0,
"endTimeSeconds": 180,
"watermark": {"uid": "{WATERMARK_PROFILE_UID}"}
}'
Source R2 (14.7 MB)
Transform 640×360
Limit 100 MB
1
Enable Media Transformations for your zone: Cloudflare Dashboard →
Speed → Optimization → Media Transformations → toggle on.
No extra subscription required on most plans.
2
Upload your video to R2 (or any publicly accessible URL — S3, GCS, your origin).
Make sure the object is publicly readable.
3
Construct the transformation URL using your Cloudflare zone as the host:
https://<YOUR_ZONE>/cdn-cgi/media/width=640,height=360/<SOURCE_VIDEO_URL>Example with R2 public URL:
https://limerolling.space/cdn-cgi/media/width=640,height=360/ https://pub-xxx.r2.dev/default.mp4
4
Use in a
<video> tag — the transformation is applied on first request
and cached at the edge. File size limit is 100 MB.
Watermark overlays are not supported — use Stream for that.