Skip to main content

POST Upload asset

To upload an asset, your first need to request for a direct upload URL and only then actually upload the contents of the asset.

This also allows your users to upload files directly to Livepeer Studio's storage, since the upload URL is pre-signed with your credentials and is accessible from the browser. The initial API call to get the upload URL must be done from a backend though, from which an API token is available.

Step 1: Create a new Direct Upload URL

First generate a URL to directly upload a video Asset to Livepeer on POST /api/asset/request-upload:


curl --location --request POST '' \
--header 'Authorization: Bearer $API_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"name":"Example name"

Response example

"url": "",
"tusEndpoint": ""
"asset": {
"id": "eeb9e573-ebc2-4236-952a-2a09eba70c41",
"playbackId": "eeb9ilj0f84g34ny",
"userId": "80dc8f6e-69d5-401f-bbd7-bfc09a2a5320",
"createdAt": 1659715372244,
"status": {
"phase": "waiting",
"updatedAt": 1659715372244
"name": "Example name"
"task": {
"id": "34d7618e-fd42-4798-acf5-19504616a11e"

Step 2: Upload the file

You now have 2 options, resumable or direct upload. For a more reliable experience, you should use resumable uploads which will work better for users with unreliable or slow network connections. If you want a simpler implementation though, you should just use a direct upload.

Step 2a: Direct Upload

For a direct upload, make a PUT request to the URL received in the url field of the response above, with the raw video file as the request body. response above:

curl --location --request PUT "${url}" \
--header 'Content-Type: video/mp4' \
--data-binary '@$VIDEO_FILE_PATH'

Notice that we only support mp4 files encoded with H264 video and AAC audio at the moment. If you are unsure about these, try sending the file anyway and check any returned errors!

Step 2b: Resumable Upload

Livepeer Studio supports resumable uploads via Tus. This section provides a simple example of how to use tus-js-client to upload a video file.

From the previous section, we generated a URL to upload a video file to Livepeer on POST /api/asset/request-upload. You should use the tusEndpoint field of the response to upload the video file and track the progress:

//  This assumes there is an `input` element of `type="file"` with id `fileInput` in the HTML
const input = document.getElementById("fileInput");
const file = input.files[0];
const upload = new tus.Upload(file, {
endpoint: tusEndpoint, // URL from `tusEndpoint` field in the `/request-upload` response
metadata: {
filetype: "video/mp4",
uploadSize: file.size,
onError(err) {
console.error("Error uploading file:", err);
onProgress(bytesUploaded, bytesTotal) {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
console.log("Uploaded " + percentage + "%");
onSuccess() {
console.log("Upload finished:", upload.url);
const previousUploads = await upload.findPreviousUploads();
if (previousUploads.length > 0) {

Note: If you are using tus from node.js, you need to add a custom URL storage to enable resuming from previous uploads. On the browser, this is enabled by default using local storage. In node.js, add urlStorage: new tus.FileUrlStorage("path/to/tmp/file"), to the UploadFile object definition above.