The Vimeo API includes a full set of features for uploading and managing video files. With this functionality, you can access all the amazing upload capabilities of vimeo.com through your own front end in your own application.

Below, you’ll find step-by-step instructions for uploading videos through the API, whether to your personal Vimeo account or to the accounts of the people who use your app. We assume no prior knowledge, so if you’re new to uploading, this is the perfect place to start. And if you’re a returning Vimeo champion, you should keep reading anyway, to get all the latest details on uploading with us. Or you can find a more advanced take on this subject in our Getting Started guide.

This information is current for our latest API release, version 3.4. For complete details on 3.4, see our Changelog.

Before you begin

Upload workflows in 3.4 are more streamlined and easier than ever to implement, but there are a couple preliminaries to consider, especially if you’ve never used our API before.


In this section, we go over everything you need to know (and do) to be able to upload videos through the API. If you need more details on any of these topics, see our Getting Started guide.

Registering your app

Uploading videos through the API always happens in the context of an application. Even if you’re just sending us HTTP requests from a command line, we assume that there’s an app associated with these requests. So the first order of business is to register your app:

  1. Log into your Vimeo account, and go to your My Apps page at developer.vimeo.com/apps.
  2. Click Create an app. Your browser goes to the Create a New App page.
  3. Fill out the brief registration form, and click or tap Create app.

Once created, your app will appear in the list on your My Apps page.

Requesting upload access

Registering your app unlocks many different API features. But for uploading videos specifically, you’ll need to get access before moving forward. To do so, reach out to our moderation team:

  1. From the My Apps page, click the name of your app. Your browser goes to the Details page for this app.
  2. Find the Upload Access heading, and click the Request Upload Access link. Your browser goes to the Request Upload Permissions page.
  3. Provide some basic information about your project, and click Request Upload Access.

Working with access tokens

Upload requests require authentication, which means that you need to send an authenticated access token along with the call to the API. The token is an alphanumeric string that identifies your end user’s Vimeo account. It belongs in the Authorization header, after the keyword bearer and a space, like this: bearer {string}.

We’ll show you exactly when and where to send this header as we move through the process below.

Using /me

In Vimeo API URLs, the shortcut /me is the same as /users/{user_id}, where user_id is the unique identifier code of your end user’s Vimeo account. This shortcut works only when you send your API request with an authenticated access token, since we determine the account to associate with /me based on the token’s value.

The /me shortcut always refers to the user associated with the access token that you’ve provided, whether that user is you personally or the end user of your application.

NOTE: The end user’s account might specify default upload settings for privacy, comments, and so on. These settings carry over to any video that the end user uploads through the API (or any video that you upload through the API on the end user’s behalf). You can modify the end user’s upload settings with a PATCH request to /me. To learn more, see the API Reference.

Understanding upload approaches

There are three main approaches for uploading video:

  • Resumable, or tus, after the open-source tus protocol

  • Form-based, also known as POST

  • Pull


In the following sections, we describe these approaches and help you determine which one to use.

NOTE If you’re a veteran of the Vimeo API, you probably remember us discussing the streaming approach, which was how we used to do resumable uploads. The tus approach — our new way forward — improves upon everything that streaming did right, while getting rid of everything that was less than ideal. Your streaming-based apps will continue to work in 3.4, but we invite you to see what tus can do.

About resumable uploads

With the resumable or tus approach, you can poll the progress of the upload as it’s occurring, and pick up a partial upload where it left off — whether that’s because of a lost internet connection or because you’ve programmed pause functionality into your app.

Since you have access to the current state of the upload, you can utilize progress bars or percent-complete counters to enhance user experience, which you can’t do with the other approaches. And just being able to resume an upload is the definition of user-friendly design, so we recommend this approach for just about everyone. But these kinds of features take time to implement. If you’re looking to upload with minimum effort, you might want to consider an alternative.

About form-based uploads

With the form-based or POST approach, your end user uploads the video to Vimeo through an HTML form, which you deploy in your app or through a link.

Integrating this approach is easy enough. Your code doesn’t manage the upload itself, and you don’t even need to create your own form. But the video comes to us as POST data, so the upload isn’t resumable. Also, if the upload fails, your end user needs to resend the entire video file.

About pull uploads

With the pull approach, you point us toward a video file that already exists on the internet. We make a copy of the video, assign it a place on Vimeo, and otherwise treat it like any other upload. We even handle any connectivity issues that might come up. All we need is the absolute path to the video file.

As long as you have this information, the pull approach is the easiest one to integrate. But the key is having this information, which means that someone has already uploaded the video and that it’s readily available for us to find. If this approach makes sense for your app, then use it, but most apps are better with tus or POST.

Checking your end user’s upload quota

No matter which upload approach you choose, your first task is always the same: making sure that your end user’s Vimeo account has enough free space for the upload. The membership type determines how much video can be uploaded per week (see Table 1).

Table 1. Upload quota by membership level
Membership Quota
Vimeo Basic 500MB/week, up to 5GB total
Vimeo Plus 5GB/week, up to 250GB/year
Vimeo Producer 5GB/week, up to 250GB/year
Vimeo PRO 20GB/week, up to 1TB/year
Vimeo Business No weekly limit, up to 5TB total
Vimeo Premium No weekly limit, up to 7TB total

* We also have live streaming plans, but we don't currently support live videos through the API.

NOTE Vimeo also offers custom membership plans for very specific storage needs. See vimeo.com/business for details.


To check your end user’s upload quota, make an authenticated GET request to /me:


GET https://api.vimeo.com /me

Table 2 shows the required headers.

Table 2. Required headers for GET to /me
Header Set value to
Authorization bearer {access_token}
Content-Type application/json
Accept application/vnd.vimeo.*+json;version=3.4

In the response, find the upload_quota object, look for the space object inside it, and check the value of this object’s free field. If the value of upload_quota.space.free is smaller than the size of your video in bytes, the API won’t accept the file.

NOTE Exceeding the end user’s upload quota returns HTTP status code 403 and error code 4101. For more information, see the API Reference.

Using the resumable approach

Here’s the general procedure for a resumable upload:

  1. Step 1. Create the video.
  2. Step 2. Upload the video file.

The following sections describe these steps in scintillating detail.

Step 1. Create the video

Make an authenticated POST request to /me/videos:

POST https://api.vimeo.com /me/videos

See Table 3 for the required headers.

Table 3. Required headers for POST to /me/videos
Header Set value to
Authorization bearer {access_token}
Content-Type application/json
Accept application/vnd.vimeo.*+json;version=3.4

In the body of the request, set the upload.approach parameter to the value tus and the upload.size parameter to length of the video file in bytes:


{
    "upload" : {
        "approach" : "tus",
        "size" : {size}
    }
}

The response returns the HTTP 200 status code and a number of fields about the new video, including upload.upload_link, which gives you the web address for uploading the video file, and uri, which gives you the eventual location of the video on Vimeo.

Step 2. Upload the video file

PATCH the binary data of the video file to the URL from upload.upload_link, along with some custom tus headers:

PATCH {upload.upload_link}

The required headers appear in Table 4.

Table 4. Required headers for PATCH to {upload.upload_link}
Header Set value to
Tus-Resumable 1.0.0
Upload-Offset 0 for the initial request; the stated upload offset for subsequent requests
Content-Type application/offset+octet-stream

Use byte 0 as the start of the the binary video data.


In the response, look for the Upload-Offset header:

  • If the value of Upload-Offset is the same as the size of the video file, we received the entire file. Consider this video uploaded.

  • If the value of Upload-Offset is less than the size of the video file, we didn’t receive the entire file, but you can easily resume the transfer.


To resume, send another PATCH request to upload.upload_link, only this time, set the Upload-Offset header to the value of Upload-Offset from the previous response, and include only the unsent portion of the binary data (which starts at the byte equal to Upload-Offset). The API responds with a new Upload-Offset header for you to compare against the size of the video file. If we still haven’t received all the data from the file, resume the transfer again from this new offset.

NOTE No matter how many times you PATCH to upload.upload_link, always be sure to supply the most recent Upload-Offset value in the header. If you don’t, the API comes back with the HTTP 409 conflict status. Check Upload-Offset, and try again.

Verifying the upload

To monitor the progress of the upload, send a HEAD request to upload.upload_link:

HEAD {upload.upload_link}

See Table 5 for the required headers.

Table 5. Required headers for HEAD to {upload.upload_link}
Header Set value to
Tus-Resumable 1.0.0

The response returns the HTTP 200 status code and the Upload-Length and Upload-Offset headers, among others. Determine the completeness of the upload by comparing the values of Upload-Length and Upload-Offset:


  • If Upload-Length and Upload-Offset are equal,we received the entire file.

  • If Upload-Length is larger than Upload-Offset,we haven't.


To complete the upload, PATCH the remainder of the binary video data to upload.upload_link starting from Upload-Offset:

PATCH {upload.upload_link}

Set the Tus-Resumable header to 1.0.0, Upload-Offset to the upload offset value, and Content-Type to application/offset+octet-stream, like in Table 4 above.

Using the form-based approach

The form-based approach uses an HTML form to upload the video. Here’s the procedure:

  1. Step 1. Create the video
  2. Step 2. Deploy the HTML form

Step 1. Create the video

Begin with an authenticated POST request to /me/videos:

POST https://api.vimeo.com /me/videos

Set the Authorization header to bearer {access_token} and Content-Type to application/json, like in Table 3 above.

In the body of the request, set the upload.approach parameter to post, and set the upload.redirect_url parameter to the web address of your completion page:


{
    "upload" : {
        "approach" : "post",
        "redirect_url" : "{url}"
    }
}

Your redirect URL can also include query parameters, as in https://www.example.com?param=value.

NOTE If you don’t specify a redirect URL, we send your end users to a page on vimeo.com, with the Vimeo logo and standard verbiage. It works, but you’re better off with a page of your own.

The upload.form field in the response contains the HTML that you need for the next step.

Step 2. Deploy the HTML form

Take the HTML markup from the upload.form field, which you received in the previous step, and use it to create the upload form for the video.

The upload.form field gives you perfectly adequate HTML, so you can place it in the body element of an HTML document for a functional (though perhaps a tad uninteresting) user interface. More likely, you’ll want to extract the workings from our HTML form and put them in a form of your own:

  • For the action attribute, use the value of the upload.upload_link field from the API response in Step 1.
  • Be sure to include an <input type="file"> element with the name file_data.

After you deploy the HTML form, it’s ready to receive the upload. Direct your end user to the form’s location. Upon submission, the browser goes to the redirect URL, which we append with the video_uri parameter, like this:

{url}?video_uri=/videos/{video_id}

This parameter contains the endpoint of the uploaded video.

NOTE Be sure to use the upload form one time only. To upload a new video, you must make a new POST request to /me/videos.

Using the pull approach

To pull a video file from somewhere else on the Internet, send an authenticated POST request to /me/videos:

POST https://api.vimeo.com /me/videos

The Authorization and Content-Type headers should be bearer {access_token} and application/json respectively, like in Table 3 above.

Use the body of the request to set the upload.approach parameter to pull and the upload.link parameter to the full URL of the video file:


{
    "upload" : {
        "approach" : "pull",
        "link" : "{url}"
    }
}

A link to a web page with an embedded video isn’t enough information for our upload server, unfortunately. The URL should resolve to the video file directly.

The response comes back with the HTTP 201 status code and complete information about our copy of the video.

NOTE Since our uploader accepts a wide range of video codecs and file types, we are unable to analyze the file until it’s on our server. Links to invalid or non-video files (like MP3 or PDF) still return HTTP 201 and generate a video URI. However, in these cases, if you send a GET request to this URI, the status field in the response shows an error.

Setting video metadata

Video uploads on Vimeo include metadata such as the name of the video and the video’s privacy settings. Besides being useful as titles and text descriptors, metadata are also a key component in strategies for search engine optimization.

You can specify values for a video’s metadata fields in the body of the initial POST request of an upload, like this:


{
    "upload" : {
        "approach" : "tus",
        "size" : "800000000"
    },
    "name" : "My Video",
    "privacy" : {
        "view" : "nobody"
    }
}

Table 6 presents some common video metadata fields, but there are many others. For a complete list, see the API Reference.

Table 6. Common video metadata fields
Metadata field Determines Possible values
name The title of the video Any
description A brief description of the video Any
privacy.download Whether people can download the video true | false
privacy.embed Where the video can be embedded private | public | whitelist*
privacy.view Who can view the video anybody | contacts | disable | nobody | password | unlisted | users*

* Some of these values require additional parameters. See the API Reference for more information.

To set metadata in videos that you’ve already uploaded, PATCH the fields and values to https://api.vimeo.com/videos/{video_id}. For more information, see the API Reference.

Replacing the source file of a video

Instead of uploading to an entirely new video, you can replace the source file of an existing video.


NOTE Please keep in mind that the updated video retains all its settings, including its URL and thumbnail image. To change the video’s settings, see Edit a Video in the API Reference. To change the video’s thumbnail, see Edit a Thumbnail. You can’t change the video’s URL, so if you want a new one, you’ll need to create a new video.

The process for replacing the video source depends on the upload method that you use to send us the new file.

Replacing the source file through a resumable upload

Send a POST request to /videos/{video_id}/versions, where video_id is the unique identifier code of the video that you would like to replace:

POST https://api.vimeo.com /videos/{video_id}/versions

Table 7 shows the required headers

Table 7. Required headers for POST to /videos/{video_id}/versions
Header Set value to
Content-Type application/json

In the body of the request, set upload.status to in_progress, upload.size to the size of the new source file in bytes, and upload.approach to tus:


{
        "file_name" : "{filename}",
        "upload" : {
            "status" : "in_progress",
            "size" : {size},
            "approach" : "tus"
        }
    }

The response contains the upload.upload_link field, which gives you the upload URL for the new source file. Take this URL to Step 2 of the resumable upload approach, and continue the upload from there.

Replacing the source file through a form-based upload

Send a POST request to /videos/{video_id}/versions, where video_id is the unique identifier code of the video that you would like to replace:

POST https://api.vimeo.com /videos/{video_id}/versions

Set the Content-Type header to application/json, like in Table 7 above.

In the body of the request, set upload.status to in_progress, upload.size to the size of the new source file in bytes, and upload.approach to post:


{
    "file_name" : "{filename}",
    "upload" : {
        "status" : "in_progress",
        "size" : {size},
        "approach" : "post",
    }
}

The response contains the upload.form field, which gives you the HTML markup for the upload form. To continue the upload, use this markup in Step 2 of the form-based approach.

Replacing the source file through a pull upload

Send a POST request to /videos/{video_id}/versions, where video_id is the unique identifier code of the video that you would like to replace:

POST https://api.vimeo.com /videos/{video_id}/versions

Set the Content-Type header to application/json, like in Table 7 above.

In the body of the request, set upload.status to in_progress, upload.size to the size of the new source file in bytes, upload.approach to pull, and upload.link to the complete URL of the replacement video file:


{
    "file_name" : "{filename}",
    "upload" : {
        "status" : "in_progress",
        "size" : {size},
        "approach" : "pull",
        "link" : "{url}"
    }
}

This is the only step. We promise.

What’s next?

Now that you’ve gotten a feel for upload workflows with our API, it’s time to deepen and broaden your knowledge. Our Getting Started guide is your level up. You can also find complete information about our entire API in our API Reference.

Send Feedback