Skip to main content

Uploading an asset transcodes the file to adaptive bitrate HLS and makes it available for VOD playback. The API supports direct upload, URL-based import, and resumable upload via the tus protocol.

Step 1 — Create an asset and get upload URL

import { Livepeer } from 'livepeer';

const client = new Livepeer({ apiKey: process.env.LIVEPEER_API_KEY });

const response = await client.asset.create({
  name: 'product-demo.mp4',
});

const asset = response.asset;
console.log('Asset ID:', asset.id);
console.log('Upload URL (tus):', response.tusEndpoint);

Step 2 — Upload the file

Direct upload (small files < 200 MB):
const fs = require('fs');

await fetch(response.uploadUrl, {
  method: 'PUT',
  headers: { 'Content-Type': 'video/mp4' },
  body: fs.readFileSync('./product-demo.mp4'),
});
Resumable upload with tus (recommended for large files):
npm install tus-js-client
import * as tus from 'tus-js-client';

const upload = new tus.Upload(file, {
  endpoint: response.tusEndpoint,
  uploadSize: file.size,
  onError: (error) => console.error('Upload failed:', error),
  onProgress: (bytesUploaded, bytesTotal) => {
    console.log(`${((bytesUploaded / bytesTotal) * 100).toFixed(1)}% uploaded`);
  },
  onSuccess: () => console.log('Upload complete'),
});

upload.start();
URL-based import:
const response = await client.asset.create({
  name: 'imported-video.mp4',
  url: 'https://your-storage.com/video.mp4',
});

Step 3 — Wait for transcoding

Poll for status or use the asset.ready webhook:
// Poll approach
let asset;
do {
  await new Promise(r => setTimeout(r, 5000)); // wait 5 seconds
  const response = await client.asset.get(assetId);
  asset = response.asset;
} while (asset.status.phase === 'processing' || asset.status.phase === 'waiting');

if (asset.status.phase === 'ready') {
  const playbackUrl = `https://livepeercdn.studio/asset/hls/${asset.playbackId}/index.m3u8`;
  console.log('Ready:', playbackUrl);
} else {
  console.error('Failed:', asset.status.error);
}
Transcoding time varies by file size: a 10-minute HD file typically takes 2-3 minutes.

Playback

Embed the playback URL after transcoding is complete.

Webhooks

Subscribe to asset.ready and asset.failed to avoid polling.
Last modified on April 7, 2026