Skip to content
Welcome to the new, unified Livepeer documentation! 👋
Reference
Create Asset

Create 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 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:

Request

curl --location --request POST 'https://livepeer.studio/api/asset/request-upload' \
--header 'Authorization: Bearer $API_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name":"Example name"
}'

Response example

{
    "url": "https://origin.livepeer.com/api/asset/upload/direct?token=eyJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJoZWxsbyBoYWNrZXIsIHRoZXJlJ3Mgbm90aGluZyBmb3IgeW91IGhlcmUg8J-YhiJ9.1YDjmXsqLcgNyMSzT4kXl_kIni46_EuGX_xfqmC7e0Q",
    "tusEndpoint": "https://origin.livepeer.com/api/asset/upload/tus?token=eyJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJoZWxsbyBoYWNrZXIsIHRoZXJlJ3Mgbm90aGluZyBmb3IgeW91IGhlcmUg8J-YhiJ9.1YDjmXsqLcgNyMSzT4kXl_kIni46_EuGX_xfqmC7e0Q"
    "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'

Step 2b: Resumable Upload

Livepeer supports resumable uploads via Tus (opens in a new tab). 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: {
    filename,
    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) {
  upload.resumeFromPreviousUpload(previousUploads[0]);
}
upload.start();

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.