VHX Dev Blog and Documentation

xxxxxx
menu
xxxxxx
0XXXXo         OXXXXKXXXX0       'KXXX00XXXXKd       ,0XXXXk
;0000O'       c0000O:0000O       ,0000d.x00000o     ;O0000o 
 cxxxxd      .xxxxx;.xxxxd       'xxxxl  :xxxxxo.  cxxxxx;  
  lllll;     cllll: .lllll       .llll:   .clllll;lllllc.   
  .:::::.   '::::;  .:::::.      .::::,     ,:::::::::'     
   .'''''   '''''.   ''''''''''''.''''.      .'''''''.      
    ;cccc:.ccccc,   .cccccccccc: .cccc;      ,ccccccc,      
    .OOOOOOOOOOk    .OOOOO.....  ,OOOOd    .kOOOOOOOOOx.    
     lKKKKKKKKK,    .KKKK0       ;KKKKk   cKKKKK0:kKKKK0,   
      OXXXXXXXo     .XXXXK       ;XXXXk .OXXXXXk.  lXXXXXd  
      .KXXXXXO      .XXXXK       ;XXXXO;KXXXXXl     'KXXXXO.
       lXXXXX,      .KXXXO       .XXXXXXXXXXXc       .0XXXX0

############# DEVELOPMENT BLOG & DOCUMENTATION ##############

API Documentation

Overview

The VHX API provides a simple and secure HTTP REST interface to VHX. Registered applications (via OAuth 2) can access user, site, package, video, and file resources.

Getting Started

  1. Currently API application registration is private. Please email api@vhx.tv to register an application and provide your app name, description, url, and callback url.

Schema

All API access is over HTTPS and accessed via the api.vhx.tv domain. All data is sent and received as JSON. Blank fields are included as null and timestamps are in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ. Only the UTF-8 character encoding is supported for both requests and responses. We support JSONP (send a ?callback parameter) and Cross Origin Resource Sharing (CORS) for AJAX requests.

HTTP Verbs

Verb Description
HEAD Can be issued against any resource to get just the HTTP header info.
GET Used for retrieving resources.
POST Used for creating resources, or performing custom action.
PUT Used for replacing or updating resources. For PUT requests with no body attribute, be sure to set the Content-Length header to zero.
DELETE Used for deleting resources.

Hypermedia

All resources have a _links property. These are explicit and permanent URIs that API clients should use for navigational purposes (instead of constructing their own URIs via id). It is highly recommended that API clients utilize the _links property.

Errors

All responses use standard HTTP status codes. This status code should solely be used to determine the success or failure of a request. If a failure, there additionally will be an message key in the JSON response with a detailed error message. Outline of all HTTP status codes are below:

Status Code Description
200 OK
201 Created
304 Not Modified
400 Bad Request (Client error)
401 Unauthorized (Invalid authentication)
402 Payment Required (Premium video content)
404 Not Found
406 Not Acceptable
500...505 Internal Server Error or Unavailable

Authentication

All requests to the VHX API require that the application be registered. Please email api@vhx.tv to register an application.

OAuth Token

Once your application is registered, requests can be authenticated via an OAuth2 access token. See below on how to request an access token:

Request:

$ curl -X POST "https://api.vhx.tv/oauth/token" \
  -d client_id=<your client id> \
  -d client_secret=<your client secret> \
  -d grant_type=password \
  -d username=<your vhx email> \
  -d password=<your vhx password>

Response:

{
  "access_token": "<your access token>",
  "token_type": "bearer",
  "expires_in": 7200,
  "refresh_token": "<your refresh token>",
  "scope": "public"
}

Refresh OAuth Token

OAuth2 access tokens expire after 2 hours. You can refresh your access token by using the previously provided refresh_token in the request below:

Request:

$ curl -X POST "https://api.vhx.tv/oauth/token" \
  -d grant_type=refresh_token \
  -d refresh_token=<your refresh token>

Response:

{
  "access_token": "<your new access token>",
  "token_type": "bearer",
  "expires_in": 7200,
  "refresh_token": "<your new refresh token>",
  "scope": "public"
}

Scopes

By default applications are of the public scope. This allows you to read your profile, site, package, and video data.

Rate Limits

The API limits applications to a certain number of calls per hour, per authenticated user. The current limit is 250 requests per hour. We provide headers in every response that help you monitor this:

X-RateLimit-Limit: 250
X-RateLimit-Remaining: 249
Last-Modified: Tue, 25 Feb 2014 12:00:00 GMT

If you have been incorrectly rate limited, please email api@vhx.tv.

Caching and Conditional Requests

The best way to prevent getting rate limited is to cache your API responses locally. Additionally, we support conditional requests (which do not count against your rate limit), so you can use the ETag or Last-Modified header we include in responses to do a GET request to a specific resource with the If-None-Match or If-Modified-Since header. If the resource has not changed, we will return a 304 Not Modified.

Methods

Here is a quick summary of all our available resources/methods. Please see below for a more detailed explanation of each of these.

/me
/me/videos

/settings

/users/:id
/sites/:id
/packages/:id

/videos/:id
/videos/:id/files

Users

A user is an individual in the VHX system. A user can be one who purchases and watches content and/or one who sells content (via sites and packages).

Profile

Profile returns all top level information pertaining to a user. The /me resource can be used to get the profile of the authenticated user and /users/:id can be used for all other VHX users. Currently this is the packages that a user owns and the sites where a user is selling. This data can be retrived via the call below:

Definitions:

GET /me
GET /users/:id

Requests:

$ curl -X GET "https://api.vhx.tv/me" \
  -H "Authorization: Bearer <access_token>"


$ curl -X GET "https://api.vhx.tv/users/:id" \
  -H "Authorization: Bearer <access_token>"

Response:

{
  "_links": {
    "self": { "href": "https://api.vhx.tv/users/1" }
  },
  "id": 1,
  "name": "Kevin Sheurs",
  "packages": [{
    "_links": {
      "self": { "href": "https://api.vhx.tv/packages/1" }
    },
    "id": 1,
    "title": "My package",
    "description": "My package description.",
    "sku": "my-sku",
    "price": {
      "cents": 500,
      "currency": "USD",
      "formatted": "$5"
    },
    "trailer_url": "https://www.youtube.com/watch?v=dINgx0y4GqM",
    "thumbnail": {
      "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
      "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
      "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
    },
    "is_presale": false,
    "is_locked": false,
    "site_id": 1,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  }],
  "sites": [{
    "_links": {
      "self": { "href": "https://api.vhx.tv/sites/1" }
    },
    "id": 1,
    "title": "My site",
    "description": "My site description.",
    "url": "http://mymovie.com",
    "domain": "mymovie.com",
    "subdomain": "mymovie.vhx.tv",
    "key": "mymovie",
    "color": "#000000",
    "facebook_url": "https://facebook.com/ksheurs",
    "twitter_name": "ksheurs",
    "packages_count": 10,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  }],
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}

Video Collection

Video collection is all of the video the authenticated user owns. This collection is the result of the distinct set of videos across all purchased packages. To retrieve this data see the call below:

Definition:

GET /me/videos

Request:

$ curl -X GET "https://api.vhx.tv/me/videos" \
  -H "Authorization: Bearer <access_token>"

Response:

[{
  "_links": {
    "self": { "href": "https://api.vhx.tv/videos/1" }
  },
  "id": 1,
  "title": "My video",
  "description": "My video description.",
  "duration": {
    "seconds": 7200,
    "formatted": "2 hours"
  },
  "thumbnail": {
    "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
    "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
    "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
  },
  "subtitles_count": 3,
  "files_count": 5,
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}]

Sites

A site is the destination or marketplace for an individual, distributor, or curator that has packages of videos available for purchase.

Information for a site, including the available packages and videos, can be retrived via the call below:

Definition:

GET /sites/:id

Request:

$ curl -X GET "https://api.vhx.tv/sites/:id" \
  -H "Authorization: Bearer <access_token>"

Response:

{
  "_links": {
    "self": { "href": "https://api.vhx.tv/sites/1" }
  },
  "id": 1,
  "title": "My site",
  "description": "My site description.",
  "url": "http://mymovie.com",
  "domain": "mymovie.com",
  "subdomain": "mymovie.vhx.tv",
  "key": "mymovie",
  "color": "#000000",
  "facebook_url": "https://facebook.com/ksheurs",
  "twitter_name": "ksheurs",
  "packages": [{
    "_links": {
      "self": { "href": "https://api.vhx.tv/packages/1" }
    },
    "id": 1,
    "title": "My package",
    "description": "My package description.",
    "sku": "my-sku",
    "price": {
      "cents": 500,
      "currency": "USD",
      "formatted": "$5"
    },
    "trailer_url": "https://www.youtube.com/watch?v=dINgx0y4GqM",
    "thumbnail": {
      "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
      "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
      "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
    },
    "is_presale": false,
    "is_locked": false,
    "site_id": 1,
    "videos_count": 1,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  }],
  "videos": [{
    "_links": {
      "self": { "href": "https://api.vhx.tv/videos/1" }
    },
    "id": 1,
    "title": "My video",
    "description": "My video description.",
    "duration": {
      "seconds": 7200,
      "formatted": "2 hours"
    },
    "thumbnail": {
      "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
      "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
      "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
    },
    "subtitles_count": 3,
    "files_count": 5,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  }],
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}

Packages

A package is the unit for sale via a site. A package has a price tag and has videos and bonus materials inside of it.

Information for a package and the videos included in it can be retrieved via the call below:

Definition:

GET /packages/:id

Request:

$ curl -X GET "https://api.vhx.tv/packages/:id" \
  -H "Authorization: Bearer <access_token>"

Response:

{
  "_links": {
    "self": { "href": "https://api.vhx.tv/packages/1" }
  },
  "id": 1,
  "title": "My package",
  "description": "My package description.",
  "sku": "my-sku",
  "price": {
    "cents": 500,
    "currency": "USD",
    "formatted": "$5"
  },
  "trailer_url": "https://www.youtube.com/watch?v=dINgx0y4GqM",
  "thumbnail": {
    "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
    "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
    "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
  },
  "is_presale": false,
  "is_locked": false,
  "site": {
    "_links": {
      "self": { "href": "https://api.vhx.tv/sites/1" }
    },
    "id": 1,
    "title": "My site",
    "description": "My site description.",
    "url": "http://mymovie.com",
    "domain": "mymovie.com",
    "subdomain": "mymovie.vhx.tv",
    "key": "mymovie",
    "color": "#000000",
    "facebook_url": "https://facebook.com/ksheurs",
    "twitter_name": "ksheurs",
    "packages_count": 10,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  },
  "videos": [{
    "_links": {
      "self": { "href": "https://api.vhx.tv/videos/1" }
    },
    "id": 1,
    "title": "My video",
    "description": "My video description.",
    "duration": {
      "seconds": 7200,
      "formatted": "2 hours"
    },
    "thumbnail": {
      "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
      "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
      "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
    },
    "subtitles_count": 3,
    "files_count": 5,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  }],
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}

Videos

A video is the container for something that can be watched. A video has a thumbnail image, duration, subtitles, and knowledge of the various available files to be streamed or downloaded.

A subtitle can be an external SRT or WebVTT file or a separate burned in video. Check the returned subtitle uri and type to determine the best action for your client.

A file is the streamable or downloadable resource for a video. It has a specific quality, format, and method of viewing:

Property Available values
quality 1080p-51, 1080p, 720p, 540p, 480p, 360p, adaptive
format m3u8, mp4, webm, ogg, flv
method hls, dash, rtmp, progressive

Files are private and the user must purchase the content before accessing it. If the authenticated user has access to a requested file uri, we will return a signed version of the final resource. This signed uri has a TTL of 30 seconds, so it should be the call right before the stream or download action.

Information for a video and the files included in it can be retrieved via the call below:

Definition:

GET /videos/:id

Request:

$ curl -X GET "https://api.vhx.tv/videos/:id" \
  -H "Authorization: Bearer <access_token>"

Response:

{
  "_links": {
    "self": { "href": "https://api.vhx.tv/videos/1" }
  },
  "id": 1,
  "title": "My video",
  "description": "My video description.",
  "duration": {
    "seconds": 7200,
    "formatted": "2 hours"
  },
  "thumbnail": {
    "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
    "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
    "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
  },
  "subtitles": [
    { "language": "Spanish", "type": "srt", "uri": "https://cdn.vhx.tv/assets/spanish.srt" },
    { "language": "German", "type": "webvtt", "uri": "https://cdn.vhx.tv/assets/german.vtt" },
    { "language": "Chinese", "type": "video", "uri": "https://api.vhx.tv/videos/2" }
  ],
  "files": [
    { "quality": "adaptive", "format": "m3u8", "method": "hls", "uri": "https://api.vhx.tv/videos/1/files?quality=adaptive&format=m3u8", "size": { "bytes": 1073741824, "formatted": "1 GB" } },
    { "quality": "1080p", "format": "webm", "method": "dash", "uri": "https://api.vhx.tv/videos/1/files?quality=1080p&format=webm", "size": { "bytes": 1073741824, "formatted": "1 GB" } },
    { "quality": "720p", "format": "mp4", "method": "progressive", "uri": "https://api.vhx.tv/videos/1/files?quality=720p&format=mp4", "size": { "bytes": 1073741824, "formatted": "1 GB" } },
  ],
  "site": {
    "_links": {
      "self": { "href": "https://api.vhx.tv/sites/1" }
    },
    "id": 1,
    "title": "My site",
    "description": "My site description.",
    "url": "http://mymovie.com",
    "domain": "mymovie.com",
    "subdomain": "mymovie.vhx.tv",
    "key": "mymovie",
    "color": "#000000",
    "facebook_url": "https://facebook.com/ksheurs",
    "twitter_name": "ksheurs",
    "packages_count": 10,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  },
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}

Tickets

A ticket is what grants a user access to view a package (or the videos inside of it). If a user purchases a package or redeems a free coupon, we create a ticket for that user. The tickets endpoint currently let's applications directly create tickets on behalf of the user.

Definition:

POST /packages/:id/tickets

Request:

$ curl -X POST "https://api.vhx.tv/packages/:id/tickets" \
  -H "Authorization: Bearer <access_token>" \
  -d user[email]=kevin@vhx.tv \
  -d subscription[campaign]=promo \
  -d send_email=1

Response:

Status: 201 Created

{
  "id": 1,
  "access_uri": "https://mymovie.vhx.tv/watch?auth_token=x",
  "user": {
    "_links": {
      "self": { "href": "https://api.vhx.tv/users/1" }
    },
    "id": 1,
    "name": "Kevin Sheurs",
    "email": "kevin@vhx.tv",
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  },
  "package": {
    "_links": {
      "self": { "href": "https://api.vhx.tv/packages/1" }
    },
    "id": 1,
    "title": "My package",
    "description": "My package description.",
    "sku": "my-sku",
    "price": {
      "cents": 500,
      "currency": "USD",
      "formatted": "$5"
    },
    "trailer_url": "https://www.youtube.com/watch?v=dINgx0y4GqM",
    "thumbnail": {
      "small": "https://cdn.vhx.tv/assets/vhx-disco-240x135.png",
      "medium": "https://cdn.vhx.tv/assets/vhx-disco-640x360.png",
      "large": "https://cdn.vhx.tv/assets/vhx-disco-1280x720.png"
    },
    "is_presale": false,
    "is_locked": false,
    "site_id": 1,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  },
  "site": {
    "_links": {
      "self": { "href": "https://api.vhx.tv/sites/1" }
    },
    "id": 1,
    "title": "My site",
    "description": "My site description.",
    "url": "http://mymovie.com",
    "domain": "mymovie.com",
    "subdomain": "mymovie.vhx.tv",
    "key": "mymovie",
    "color": "#000000",
    "facebook_url": "https://facebook.com/ksheurs",
    "twitter_name": "ksheurs",
    "packages_count": 10,
    "videos_count": 10,
    "created_at": "2014-02-25T20:19:30Z",
    "updated_at": "2014-02-25T20:19:30Z"
  },
  "status": "enabled",
  "created_at": "2014-02-25T20:19:30Z",
  "updated_at": "2014-02-25T20:19:30Z"
}