Backlot API Overview

API Conventions

The following is shorthand notation for "issue a GET HTTP request to https://api.ooyala.com/v2/players".

[GET] /v2/players

Content listed directly below the HTTP verb and the resource url is the body of the request.

Request bodies should be JSON unless otherwise indicated.

[POST] /v2/syndications
{
  "name": "new youtube syndication",
  "type": "youtube"
}

Fields that represent a variable (such as a player id) are prefixed by a colon.

[GET] /v2/players/:player_id

REST Overview

The Backlot and Analytics APIs follow the conventions of REST design. Every resource in the API has its own URL. You can view, modify and delete those resources by sending requests to the resource's URL and using standard HTTP methods ("verbs") in your requests.

All requests must be made using HTTPS.

These are the standard HTTP methods that we use. Any HTTP library or tool will allow you to specify which one of these HTTP methods you want to use when making your request.

Creation calls (POST to /v2/players, for example) can take all the same parameters as an update call (PATCH) to that resource.

When modifying resources using PATCH, PUT or POST requests, the body of the request should contain a JSON representation of the resource. For instance, issuing a GET request to view a player will look like:

[GET] /v2/players/2kj390

The response:

{
  "id": "2kj390",
  "name": "my player",
  "provider_homepage_url": "http://www.ooyala.com",
  ...
}

You could rename that player by sending a PATCH request to /v2/players/2kj390 with this request body:

{
  "name": "my new player name"
}

Sample usage

You can make HTTP requests using any HTTP library for your programming language. These examples will use the unix command line tool "curl" to make requests.

This example gets the details for a player with an ID of "NWI1ZmU4NDNmNmIyODY3ODA0NGNhNDZk":

$ curl -X GET 'https://api.ooyala.com/v2/players/NWI1ZmU4NDNmNmIyODY3ODA0NGNhNDZk'\
'?api_key=ZnMmM6AO3C-iBubra3R2Xd6pXHgK.28riq&expires=1930294539'\
'&signature=p3RfmwGk%2FjwIup%2BUtyTtXjU%2FPpDx2DwHNGyfko07%2B28'

To modify one of the fields in this player resource, use a PATCH request. This example sets the "provider_homepage_url" for this player to be "http://www.ooyala.com". The "-d" flag of curl is being used here to specify the body of the request.

$ curl -X PATCH 'https://api.ooyala.com/v2/players/NWI1ZmU4NDNmNmIyODY3ODA0NGNhNDZk'\
'?api_key=ZnMmM6AO3C-iBubra3R2Xd6pXHgK.28riq&expires=1930294539'\
'&signature=sea6HjJuWCIXvrw4qxPYCidlMepq0UFu%2FQ9MM6Uw%2Fm4' \
-d '{ "provider_homepage_url": "http://www.ooyala.com" }'

HTTP response codes for Ooyala API requests

These are the HTTP response codes that can be returned for API responses. In case of errors, the API response body will explain the reason why the API returned an error response code.

Authenticating your requests

Every request made to Ooyala's APIs requires three querystring parameters for authentication:

What follows is an example of generating a signed GET request to "https://api.ooyala.com/v2/players/HbxJKM".

  1. Start with your 40 character secret key. This can be found in the Developers tab in Backlot; it is unique for each user and should always be kept secure and private. For this example, we're going to use "329b5b204d0f11e0a2d060334bfffe90ab18xqh5" as the secret key.

    329b5b204d0f11e0a2d060334bfffe90ab18xqh5

  2. Append the HTTP method (e.g. "GET", "POST", "PUT"):

    329b5b204d0f11e0a2d060334bfffe90ab18xqh5GET

  3. Append the request path:

    329b5b204d0f11e0a2d060334bfffe90ab18xqh5GET/v2/players/HbxJKM

  4. Append any query string parameters, sorted alphabetically by keys. Parameters should not be URL-encoded when appended to this string. Remember to include the required "api_key" and "expires" parameters. In this example we'll use an api_key of "7ab06" and an expiration of "1299991855".

    329b5b204d0f11e0a2d060334bfffe90ab18xqh5GET/v2/players/HbxJKMapi_key=7ab06expires=1299991855

  5. If your request has a body (usually the case with PATCH and PUT requests, but not GET requests), append the entire request body to the string.
  6. From this string, you can now generate a SHA-256 digest in Base64, truncate the string to 43 characters, and remove any trailing "=" signs. When appending this signature to your request URL, URL encode it (especially the "+", "=" and "/" characters). This example produces a signature of:

    p9DG/+ummS0YcTNOYHtykdjw5N2n5s81OigJfdgHPTA

    which, URL encoded, is:

    p9DG%2F%2BummS0YcTNOYHtykdjw5N2n5s81OigJfdgHPTA

  7. Append this signature to your request URL as a querystring parameter. You can now visit this URL to make your request. This is the final, signed URL:

    https://api.ooyala.com/v2/players/HbxJKM?api_key=7ab06&expires=1299991855&signature=p9DG%2F%2BummS0YcTNOYHtykdjw5N2n5s81OigJfdgHPTA

Sample code for generating signatures.

This Ruby sample code can be used for generating signatures.

require "digest/sha2"
require "base64"

# Both of these values should be obtained from the Developers tab in Backlot.
API_KEY = ""
SECRET = ""

module OoyalaApi
  def self.generate_signature(secret, http_method, request_path, query_string_params, request_body)
    string_to_sign = secret + http_method + request_path
    sorted_query_string = query_string_params.sort { |pair1, pair2| pair1[0] <=> pair2[0] }
    string_to_sign += sorted_query_string.map { |key, value| "#{key}=#{value}"}.join
    string_to_sign += request_body.to_s
    signature = Base64::encode64(Digest::SHA256.digest(string_to_sign))[0..42].chomp("=")
    return signature
  end
end

# Example usage of the generate_signature function:
#
# Set `expires` in 1-hour intervals for higher caching performance:
# t = Time.now
# expires = Time.local(t.year, t.mon, t.day, t.hour + 1).to_i
#
# params = { "api_key" => API_KEY, "expires" => expires }
# signature = OoyalaApi.generate_signature(SECRET, "GET", "/v2/players/HbxJKM", params, nil)

Paging

Responses that include a list of first-class resources will return a paged result set. First-class resources are:

Any response that lists these resources will return paged JSON in the following format.

A list of labels is represented here:

GET "/v2/labels"
{
  items: [
    {
      "name": "Label 1",
      "id": "61b70ba4ded34cc2a3e8096924fe6247",
      "parent_id": null,
      "full_name": "/Label 1"
    },
    {
      "name": "Label 2",
      "id": "3cadabc7066b48afa74f48d396f1f792",
      "parent_id": null,
      "full_name": "/Label 2"
    }
  ],

  "next_page": "/v2/labels?limit=200&page_token=%2FLabel+2"
}

The "next_page" url parameters can be used in a subsequent signed request to retrieve the next page. In this example, I would sign a new request with the limit and page_token parameters added.

You may specify any limit between 1 and 500 for paged requests. The default is 100.

For example, this issues a request for labels with a page size of 1

[GET] /v2/labels?limit=1

You can use the next_page url to request the next page

[GET] /v2/labels?limit=1&page_token=animal%2Bvideos%3B4fcb0f981d70459a9693472d6d05d7b7

User Roles Permissions

The user account permissions that exist in Backlot are also enforced in the APIs. There are five user roles:

Rate Limiting

Each request made to the Ooyala APIs costs a certain number of API credits. Your credits reset every minute.

All API requests cost 1 credit unless otherwise specified.

If you do not have enough credits to make an API request you will receive a 429 response.

Each request made to our APIs, successful or not, will return the following headers:

X-RateLimit-Credits  # The number of credits you have remaining.
X-RateLimit-Reset    # The number of seconds until your credits reset.

View your remaining credits and reset time

[GET] /v2/remaining_credits_and_reset_time

Sample response:

{
  "remaining_credits": 60,   // number of credits you have left
  "remaining_reset_time": 0  // number of seconds you have to wait for the next reset
}

Tips to avoid rate limiting

If you find yourself continually hitting the limit, you might try the following to decrease your API usage:

Using Ooyala's high performance cached API

In addition to our standard API, Ooyala also offers a high performance caching layer for API calls. This caching layer may not be necessary for all applications, but it is ideal for the following cases:

If both of these cases reflect your API usage, we encourage you to use the high performance API and consult with your account manager on best practices.

Here is what you need to know to start using the high performance API:

  1. API calls need to be made to http://cdn-api.ooyala.com instead of http://api.ooyala.com. You cannot use HTTPS.

  2. With Ooyala's caching layer in place, a copy of your response will be cached for a few minutes. However, the expires parameter in your API queries needs to be made "cache friendly." The most important change to make is to ensure that your expires parameter does not change between every single request you make. Instead, you'll find better performance setting it to a fixed time further out in the future.

    For example, you can set the expiration to always be the start of tomorrow using the following snippet (in Ruby for example):

     today = Date.today
     expires = Time.mktime(today.year, today.month, today.day) + 86400
    

    If you're generating urls to be used directly from an embedded Flash or IOS application, you can simply pre-generate a url with an expires time years into the future.

Caveats

"High performance" doesn't mean it is better in all cases. Caching responses in the CDN is ideal for repeated, non-unique requests, but if you're generating unique requests (e.g. based on a user's search terms) each and every time, you'll want to make requests to api.ooyala.com directly. Additionally, in scenarios where you always need the most up-to-date response and can't wait a few minutes for a stale, cached response to be refreshed, you should not use the high performance cached API.

Making API calls from webpages using JSONP

Ooyala's APIs support JSONP, which is used to avoid cross-domain restrictions when invoking API calls from webpages. To enable JSONP, specify the name of your javascript callback function by using the callback query string parameter:

GET /v2/labels?callback=my_javascript_function

You'll see that the response is of the form

my_javascript_function({ "items": [ ... ] })

instead of the usual JSON format:

{ "items": [ ... ]}

The function my_javascript_function will be called with the API's response if this API call is made from a webpage's <script> tag.

Note that JSONP is only available when using the high performance cached API (which uses cdn.api.ooyala.com instead of api.ooyala.com), for performance reasons.