Introducing the new Vimeo upload API

Marc Campbell
Vimeo Engineering Blog
3 min readFeb 7, 2018

Vimeo’s got some pretty big news to share today. We’ve just rolled out an all-new, all-awesome version of our API — and we want you to be the first to use it. (Well, among the first. We did send out an email blast or two to some of you.)

We’re calling this version 3.4, and it’s packed with new features, enhancements, and ways to make your video life better. But if we had to pick just one word to describe it, that word would be uploads. That’s because you get more of everything: reliable file transfers, responsive upload endpoints, streamlined upload workflows, and just-plain-better upload experiences than in any previous Vimeo API.

The best place to get started is our developer site, but before you jump in, here’s a quick look at the topline points.

The tus standard comes standard

Resuming paused or interrupted uploads is easier than ever thanks to our brand new implementation of tus, an open-source protocol for transferring large files over the internet.

A tus upload begins much like any other, with an authorized POST request to /me/videos:

POST /me/videos HTTP/1.1Host: api.vimeo.com
Authorization: bearer {access_token}
Content-Type: application/json
{
"upload" : {
"approach" : "tus",
"size" : "{size}"
}
}

The response comes back with a complete video representation — including the newly consolidated upload object, your one-stop shop for all upload fields:

{

"upload" : {
"status" : "in_progress",
"upload_link" : "{upload_link}",
"approach" : "tus",
"size" : {size}
},

}

Grab the upload link, and PATCH the binary video data to this location, along with some necessary headers:

PATCH {path_from_upload_link} HTTP/1.1
Host: {host_from_upload_link}
Content-Type: application/offset+octet-stream
Upload-Offset: 0
Tus-Resumable: 1.0.0
{binary_video_data}

If the upload stops, whether because of a lost internet connection or because your end user paused the transfer, the API returns a set of headers, including Upload-Offset. The value of this header tells you exactly where to restart the upload, which you do with another PATCH to upload.upload_link:

PATCH {path_from_upload_link} HTTP/1.1
Host: {host_from_upload_link}
Content-Type: application/offset+octet-stream
Upload-Offset: {upload_offset}
Tus-Resumable: 1.0.0
{remaining_binary_video_data}

Of course, the upload might have stopped because we received the entire file. If we did, the value of Upload-Offset is equal to {size} from the original POST.

The old way of resuming uploads through the API called for real-time manual calculations of bytes received and which byte number to pick up from. It was, and we quote, “a royal pain.” But with tus, you don’t need a calculator, because tus is the calculator.

Metadata first

Another improvement in 3.4 is that it gives you the ability to set video metadata during upload. Simply add the metadata fields and their values to the body of the initial POST request:

POST /me/videos HTTP/1.1
Host: api.vimeo.com
Authorization: bearer {access_token}
Content-Type: application/json
{
"upload" : {
"approach" : "tus",
"size" : "{size}"
},
"name" : "{name}",
"description" : "{description}",
"privacy" : {
"view" : "{privacy_view_setting}"
},
"embed" : {
"playbar" : "{embed_playbar_setting}"
}
}

Prior to 3.4, you’d PATCH the metadata to /videos/{video_id}, but only after you uploaded the file. And since the display name of a video is a function of metadata, many uploads started life as Untitled on Vimeo. You can keep that tradition going if you want. But why?

It’s all in the details (and the curly braces)

We’ve also tightened up the high-level logic of the API and improved consistency across the board.

Case in point: when you send a POST request to /me/videos, you get back a complete representation of the video, no matter the value of the approach parameter. And that representation includes the upload object, which you’ve already seen in action in our description of tus.

The upload object gives you everything you need to continue with the upload according to the value of approach. So when approach is tus, upload.upload_link contains the URL for the upload. But when approach is post, our form-based upload approach, upload.upload_link is null, while upload.form contains the markup for the HTML upload form.

And so much more in 3.4

That covers the highlights, but there are many more improvements to discover. See our Changelog for complete details. And when you’re ready to start, our dev site awaits.

--

--

Marc Campbell
Vimeo Engineering Blog

I manage technical writing at Vimeo. Any mistakes on this blog are probably my fault.