Multipart Resumable Upload

Upload a 100MB-25GB media file that is on the local machine

When you have a file that is >100 MB in size that you need to upload from your local machine, you should use this approach.

This method has several advantages:

ā€¢ Speed: CDN acceleration and parallelized uploading can decrease the time required to upload.
ā€¢ Resumability: Network failures don't require starting over. Uploading can be paused.
ā€¢ Measurability: Upload progress can be reliably measured.


Due to the additional requests that this approach uses, additional network overhead will be created on the network where the requests are being made.

Upload media

Uploading via the multipart method requires several steps:

  1. Make an authenticated POST /v2/sites/{site_id}/media call to create a new media object. Within the JSON body, set upload.method to multipart and define the metadata of the media item. Refer to the POST /v2/sites/site_id/media/ reference for more information about acceptable metadata body parameters.

    The API call will return a response with the upload_id and upload_token. These fields will be used to interact with the Upload API.

    In the following sample, only the media item's metadata.title is defined.
curl -X POST{site_id}/media \
 -H 'Authorization: Bearer {v2_api_secret}' \
 -H 'Content-Type: application/json' \
 -d '{ "upload": { "method": "multipart" }, "metadata": {"title": "My Multipart Upload Video"} }'

  1. Determine the number of parts into which the file should be split and the size of each part. For example, if a file is 500MB, you could split the file into 5 MB parts. This means that your part count will be 100 parts. You should choose your part size to optimize either for resumability (smaller part sizes) or reducing network overhead (larger part sizes).

    The minimum size for a part is 5 MB (with the exception of the last part).
    The maximum number of possible parts is 10,000.

  1. Make a GET /v2/uploads/{upload_id}/parts call to get a list of upload parts.

    You can copy the following sample. Be sure to replace the {upload_id} and {upload_token} placeholders with the upload_id and upload_token that you received from API response in step 1. Also, set page_length to the part count. In the example, 100 is used. The API call will return a response that lists 100 parts. Each part will have an upload_link location.
curl '{upload_id}/parts?page=1&page_length=100' \
 -H 'Authorization: Bearer {upload_token}' \
 -H 'Content-Type: application/json'

  1. Upload the bytes of the local media file part to the upload_link location. Be sure to replace the {path_to_your_video} with the actual path to the file. Use the following table to define the bs, count, and skip parameters within your request.
bsSize of the part in megabytes (M)
countNumber of parts

This should always be 1.
skipNumber of previous uploaded part to jump over

Below is an example of reading 5 MB parts at a time and uploading each part to its respective upload_link.

dd if=~/{path_to_your_video}.mp4 bs=5M count=1 skip=0 | curl \
  -XPUT -H "Content-Type:" \
  --data-binary @- \

dd if=~/{path_to_your_video}.mp4 bs=5M count=1 skip=1 | curl \
  -XPUT -H "Content-Type:" \
  --data-binary @- \


dd if=~/{path_to_your_video}.mp4 bs=5M count=1 skip=99 | curl \
  -XPUT -H "Content-Type:" \
  --data-binary @- \

  1. After all parts have been uploaded, make a PUT /v1/uploads/{upload_id}/complete call. This signals to JW Player that all parts have been uploaded.
curl -X PUT \
  -H "Authorization: Bearer {upload_token}" \
  -H "Content-Type: application/json" \



Subsequent calls to GET /v1/uploads/{upload_id}/parts will return both completed and uncompleted parts.

Completed parts will have the etag field set to an MD5 hash of the uploaded part and upload_link field will no longer be present. Counting the number of completed parts is a way of checking the progress of an upload.

  1. Make a GET /v2/sites/{site_id}/media/{media_id} call to retrieve the media transcoding status.
curl -X GET{site_id}/media/{media_id} \
 -H 'Authorization: Bearer {v2_api_secret}' \
 -H 'Content-Type: application/json'