This guide creates a stream-ready video asset from a file in Convertly Storage. Use it when your app needs adaptive playback instead of a single downloadable video.
Video streaming and live inputs require a Business or Enterprise plan. Pro and lower plans can still convert, trim, thumbnail, and poster-frame video through the Media Tools API.
1. Upload the source video
Create a direct upload session, upload the bytes to storage, then complete the upload. The completed file ID becomes sourceFileId.
curl -X POST "https://convertly.sh/api/uploads" \
-H "Authorization: Bearer $CONVERTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "lesson.mp4",
"contentType": "video/mp4",
"sizeBytes": 104857600
}'
After upload completion, keep the returned file.id.
2. Create the HLS/DASH stream
curl -X POST "https://convertly.sh/api/video/streams" \
-H "Authorization: Bearer $CONVERTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sourceFileId": "00000000-0000-0000-0000-000000000000",
"profile": "hd",
"packageFormats": ["hls", "dash"],
"access": "signed",
"segmentDuration": 6,
"allowedDomains": ["app.example.com"]
}'
For a clip:
{
"clip": {
"start": 80,
"duration": 45,
"mode": "accurate"
}
}
Use mode: "fast" for cheaper keyframe-boundary clips when exact frame boundaries do not matter.
3. Wait for readiness
Poll the asset:
curl "https://convertly.sh/api/video/streams/<asset-id>" \
-H "Authorization: Bearer $CONVERTLY_API_KEY"
Or subscribe a webhook to:
video.stream.started
video.stream.ready
video.stream.failed
4. Play the stream
When ready, use hlsManifestUrl in any HLS-capable player, or dashManifestUrl with dash.js.
<video controls poster="https://convertly.sh/video/v1/pb_.../poster.jpg?expires=...&token=...">
<source src="https://convertly.sh/video/v1/pb_.../master.m3u8?expires=...&token=..." type="application/vnd.apple.mpegurl" />
</video>
Safari plays HLS natively. For Chrome/Firefox desktop, use a player such as hls.js.
import Hls from "hls.js";
const video = document.querySelector("video");
const manifestUrl = "https://convertly.sh/video/v1/pb_.../master.m3u8?expires=...&token=...";
if (video.canPlayType("application/vnd.apple.mpegurl")) {
video.src = manifestUrl;
} else if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(manifestUrl);
hls.attachMedia(video);
}
Recommended defaults
Start with:
profile: "standard" for most product video.
profile: "hd" when 1080p matters.
access: "signed" for user/private content.
segmentDuration: 6 unless you have a playback reason to change it.
Custom ladders are best for products with strict bandwidth budgets or known playback environments.
Usage pricing
Video streaming uses two meters:
| Meter | How it is counted |
|---|
| Encoded minutes | Stream duration multiplied by the number of generated renditions. |
| Delivery | Manifest, poster, playlist, and segment bytes served through /video/v1/.... |
Business includes streaming quotas and can continue with optional overage when enabled in billing settings. Enterprise plans use contracted limits. Free, Starter, and Pro are not eligible for streaming asset or live input creation.
Live broadcast
Create a live input when you need a real RTMP/SRT broadcast workflow:
curl -X POST "https://convertly.sh/api/live/inputs" \
-H "Authorization: Bearer $CONVERTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly launch demo",
"recordMode": "automatic",
"allowedDomains": ["app.example.com"]
}'
The response returns the stream key once. Put ingest.obsServer and ingest.obsStreamKey into OBS. Playback URLs are returned under playback.hlsUrl and playback.webRtcUrl.