Filmon REST Api v2.2

Intro

what's not described:

  • how to buy a subscription
  • how to buy a subscription
  • how to get an order info for the customer orders
  • user authentication for Roku devices (initSerial+generateAuthKey)
  • documentation for managing credit cards is not up to date
  • some examples may not work, please post all comments to contact-api@filmon.com

Changes from version 2.0

  • some cleanup

Changes from version 1.0

API main URL: http://www.filmon.com/tv/api

API can work only in client(your app)-server(filmon API) mode.

Each request except "init" should include parameter session_key with a session key which must be obtained within "init" request. Client requests without correct+not expired session_key will be declined (Server will send response HTTP/1.1 400 Bad Request). Client is responsible for keeping session_key from expiring via keep-alive requests or any other API request within session_key expiration time. All requests with session_key which does not exists (for example is invalid, empty or expired) server will decline with http status code HTTP/1.1 410 Gone.

Each request can contain additional optional parameters :

  • format : either "xml" or "json". Defines format of the data in the server’s response. If this parameter is included in the "init" request - all further server responses will be in this format. Default value: json. If wrong value is set - will be used default value. Please try to use json as its using less HTTP traffic.

Each POST request can define the format of the posted data by using HTTP header "content-type". Default value "application/x-www-form-urlencoded". Possible values:

  • "application/x-www-form-urlencoded" - server assume that posted data in urlencoded format.
  • "application/json" - server assumes that the posted data is json object. Recommended.
  • "application/xml" - server assumes that the posted data is an XML.

Example:

posted data:

email=user.email@filmon.com, password=verysecretpassword

Request body for urlencoded format:

email=user.email@domain.com&password=userpassword&session_key=randomsessionkey

Request body for json format:

{"email"  : "user.email@domain.com", "password": "userpassword", "session_key" : "randomsessionkey"}

Request body for xml format:

<request>
    <email>user.email@domain.com</email>
    <password>userpassword</password>
    <session_key>randomsessionkey</session_key>
</request>

Default session timeout: X = 300 seconds. If server will not receive any request from a client during this period of time the session will be expired. To keep session alive either periodically send keep-alive requests (see method keep-alive) or any other request each X seconds.

go to table of contents

Methods

Method: init

Link : http://www.filmon.com/tv/api/init

Description: Init new API session.

Parameters:

app_id : - a secret key , email to contact-api@filmon.com to get one (use ‘foo’ for testing).

app_secret : - a secret passphrase, which will be provided with app_id (use ‘bar’ for testing).

Response: HTTP/1.1 200 Ok if success and apiInfo response in body

{
    "session_key" : "randomuniquesessionkeyprovidedbyserver"
}

Received session_key should be added to each further API request, otherwise all requests will fail with http response HTTP/1.1 403 Forbidden

Additional optional parameters:

  • format - if set this format will be used in all further server’s responses. Possible values: json, xml. Default value: "json" - this is also a recommended format due to it’s relatively small bandwidth usage.

go to table of contents

Method: groups

Link: http://www.filmon.com/tv/api/groups

Description: retrieve all channel’s groups.

Response example:

[
     {
        "group" : "Lifestyle",
        "description":"lifestyle channels",
        "weight":"2",
        "group_id":"11",
        "logo_uri":"http:\/\/static.filmon.com\/theme\/images\/category\/lifestyle.png",
        "channels_count":"29",
        "channels" : [ 1, 14,21,34,56,....,237]
    },
    {
        "group":"Music",
        "description":"",
        "weight":"2",
        "group_id":"12",
        "logo_uri":"http:\/\/static.filmon.com\/theme\/images\/category\/music.png",
        "channels_count":"14",
        "channels" : [ 1, 14,21,34,56,....,237]
    }
]

go to table of contents

Method: channels

Link: http//www.filmon.com/tv/api/channels

Description: Retrieve all available channels

Response example:

[
    {  
        "id" : 11,
        "title" : "ITV 1",
        "logo" : "http://www.filmon.com/tv/themes/filmontv/images/channels/11.png",
        "content_rating" : "0",
        "group" : "Main"
    },
    {  
        "id" : 12,
        "title" : "ITV 2",
        "logo" : "http://www.filmon.com/tv/themes/filmontv/images/channels/12.png",
        "content_rating" : "0",
        "group" : "Coming Soon"  // channel group title. See /groups method to receive a full list of
                                 // categories and info about each category
    }
]

Some explanations:

content_rating - Channel Content Rating using UK system. that is a 2-bytes integer which contains information about a broadcasting content.

See example: (ansi C)

const char * describe_content_rating( unsigned int content_rating ) {

          static char buffer[1024];
        memset(buffer, 0, sizeof(buffer));
          const char * level ;
          const char *attributes[] = {
              "Drugs",
              "Violence",
              "Prejudice",
              "Sex",
              "Nudity",
              "Language"
          };
          if ( content_rating & 1 )      level = "Childs";
          else if ( content_rating & 2 ) level = "Childs 7+";
          else if ( content_rating & 4 ) level = "General";
          else if ( content_rating & 8 ) level = "Parental Guidance";
          else if ( content_rating & 16) level = "14+";
          else if ( content_rating & 32) level = "17+";
          else level = "Unknown";

          sprintf(buffer, "Level: %s, Attributes: ", level);

          char *p = buffer + strlen(buffer);
          int i;
          for (  i=9;  i<15; i++ ) {
              if ( content_rating & ( 1<
                  sprintf(p, "%s; ", attributes[i-9]);
                  p = buffer + strlen(buffer);
              }
          }
          return buffer;
}

go to table of contents

Method: channel

Description: Retrieve channel’s info and channel’s stream

Link: http://www.filmon.com/tv/api/channel/ [channel-id]

Parameters:

channel-id : Filmon ChannelID

Request example:

  • javascript + jquery:
      var channel_id = 11;
      $.getJSON( "http://www.filmon.com/tv/api/channel/" + channel_id , {},
          function(channelInfo) { alert(channelInfo); } );

Response example:

{
    "id" : 11,
    "title" : "ITV 1",
    "streams" : [
                    {  
                        "id" : 1 ,
                        "quality" : "480p",
                        "url" : "http://69.55.55.55/live.11/stream.high/playlist.m3u8?hash=1ef2eab"
                    },        
                    {
                        "id" : 2,
                        "quality" : "240p",
                        "url" : "http://69.55.55.55/live.11/stream.low/playlist.m3u8?hash=9ef11eab"
                    }
                ],
    "watch-timeout" : 300,  // how many seconds from the moment of receiving the reply user can watch these streams.
                            // after 300 seconds both streams will be disconnected server-side. you must implement a GUI action to handle that
                            // This value depends on the current session - for guest mode it could be something like
                            // 90 seconds, for an authorized user without any subscription - same 90 seconds, but for authorized  user who has a
                            // subscription to the channel 11 - the expiration time will be the expiration time of his purchased subscription 
    "logo" : "http://www.filmon.com/images/channels/11.png",
    "subscriptions" : [ 14,15,34,37 ]
 }

go to table of contents

Method: tvguide

Description: retrieve tvguide for a channel

Link: http://www.filmon.com/tv/api/channel/ [channel-id]

Response Example: (xml)

<response>
    <programme>6443</programme>
    <startdatetime>1307480400</startdatetime>
    <enddatetime>1307481900</enddatetime>
    <duration>1500</duration>
    <programme_description>
        The latest national and international news stories, followed by Weather.
    </programme_description>
    <channel_id>14</channel_id>
    <channel_category>Entertainment</channel_category>
    <programme_name>BBC News</programme_name>
    <rating>0</rating>
    <programme_category>News</programme_category>
    ...
</response>

JSON:

[{
    "programme":"6443", // filmon’s internal programme id
    "startdatetime":"1307480400", // unix timestamp. GMT
    "enddatetime":"1307481900",  // unix timestamp. GMT
    "duration":"1500", // duration in seconds
    "programme_description":"The latest national and international news stories, followed by Weather.",
    "channel_id":"14", // filmon’s channel id
    "channel_category":"Entertainment", // Channel Category (channel genre). Can be NULL.
    "programme_name":"BBC News", // Programme Name.
    "rating":"0", // Programme Content Rating (not implemented yet, UK rating system)
    "programme_category":"News" // Programme category (genre). Can be NULL
  }, ….
]

go to table of contents

Method: subscriptions

Description: Retrieve list of available subscriptions

Url: http://www.filmon.com/tv/api/subscriptions

Response example:

[
   {
        "id" : 14,
        "title" : "UK & World Monster Pack Month"
        "description" : "Some subscription description. Html can be here"
        "price" : "9.95",
        "currency" : "EUR",
        "expiration_period" : 744,      // subscription length in hours before the subscription expires
        "channels" : [ 1,2,4,5,14,239,142, 65 ]
   },
   {
        "id": 15,
        "title" : "UK & World Monster Pack Year",
        "description" : "another subscription description, possibly with html",
        "price" : "149.99",
        "currency" : "EUR",
        "expiration_period" : 8760
   }
]

go to table of contents

Method: subscription

Parameter: subscription-id - id of subscription

Description: Get Subscription’s info

Link: http://www.filmon.com/tv/api/subscription/ [subscription-id]

Response example:

{
    "id": 15,
    "title" : "UK & World Monster Pack Year",
    "description" : "another subscription description, possibly with html",
    "price" : "149.99",
    "currency" : "EUR",
    "expiration_period" : 8760,
    "buy_link" : "https://divx.filmon.com/checkout/onepage/index/product/7002?token=usertoken"
    "channels" : [ 1,2,4,5,14,239,142, 65 ]
}

go to table of contents

Method: login

Parameters: POST parameters in urlencoded format :

login: user login must be provided here

password: md5 encoded user’s password

Description: authenticates session with the user login. The user previously should be registered on filmon.com.

Url: http://www.filmon.com/tv/api/login

Server will return HTTP/1.1 200 Ok if login ok (all future API requests with this session will be linked to the user’s account) and HTTP/1.1 404 Not Found if a user with such combination of login/password was not found.

Special note about userlogin: New users (that registered using this api, or registered on filmon.com since October, 31, 2010) should use their’s email as user login. Old users (registered on www.filmon.com before October 31,2010) can use both their email and their old non email login.

Response body will contain user’s info.

Response example:

{
    "id" : 132281, // filmon UserID
    "email" : "vasya.doe@filmon.com",
    "nickname": "vasya",
    "subscriptions" : [{
        "subscription_id" : 14, 
        "expire-timestamp" : 1298460769, 
        "expire-timeout" : 86478,
        "start-timestamp" : 1298460769,
        "channels" : [13,42,14,23,94] 
        }],
    "favourite-channels" : [13, 42, 15, 231, 1] // not used currently
}

Explanations:

expire-timestamp: Time when the subscription is going to expire

expire-timeout: amount of seconds from the moment of receiving API reply (now) to the moment when the subscription is going to expire. It’s calculated as expire-timestamp - now()

start-timestamp: Time when subscription has started

Client example (javascript + jquery):

var session_key = "abyrabyr" ; // a session key received from init request.
var login = $(‘input.login’).val(); // passing user’s login
var pass = md5encode($(‘input.password’).val()) ; // passing user’s password 
var filmon_url = "http://www.filmon.com/tv/api/"; // base url for filmon API.
$.post(filmon_url + "login", // method url
    {‘login’ : login, ‘password’ : pass , ‘session_key’ : session_key  }, // method params
     function(data) { // success callback function
            alert(‘login success, userInfo : ’ +data);
            userInfo = $.parseJSON(data);
    })
    .error(function(xhr) { // error callback function
        if ( xhr[‘status’] == ‘404’) alert(‘invalid login or password’);
    });

Client can call this method many times (for example to synchronize userSubscriptions, favorite channels, etc)

go to table of contents

Method: logout

Description: logout user

Url: http://www.filmon.com/tv/api/logout

Parameters: none

Response: HTTP 200 Ok (without body)

go to table of contents

Method: registerg

Description: Register user on filmon.

Url: http://www.filmon.com/tv/api/register

Parameters: POST parameters in urlencoded format.

email - User Email

password - User password. Plaintext. Not encoded by any way.

Response: HTTP/1.1 200 Ok if registration success.
As body server will return userInfo and automatically associate user with current session. For success response example see login method HTTP/1.1
400 StatusText if registration failed. XHR statusText will contains possible reason (one of "Wrong email", "Email already registered", "Bad Password", etc).
Email will be validated on server using common and simple email check regexp. Something like this :
/^[a-z0-9-]+[a-z0-9.-]@[a-z0-9-]+[a-z0-9.-].[a-z]{2,4}$/i
We dont allow to register email from IDN ccTLD and emails from .travel, .museum, etc.
Password should contains at least 5 characters.
Additional Note For Lookee clients:
    with email and password client application can also provide a valid user’s credit card info. If provided - user will be subscribed to 1 Month subscription (UK or US pure pack ). See method ‘addCard’ for required fields.

go to table of contents

Method: accountUpdate

Description: provides ability to change user password.

Parameters: password and new_password

password : Old user's password. Required. User have to enter his current password to change it. Similar to /login method it should be md5 encoded user password.

new_password : new user password. Required. Minimum password length - 5 characters. Plaintext (must not be encoded).

Works only in authorized mode (user must be logged in before calling this method);

Server replies 400 Bad Request if new_password length less than 5 symbols.

Server replies 404 if user entered wrong password.

Example (jquery + javascript):

$.get( main_api_url + "/accountUpdate",
    { password: $('input#password').value(),
    new_password : $('input#new_password').value() },
        function( response) {
            alert('Password has been changed') ;
        }
    )
    .error( function(xhr) { alert('Wrong password'); } );

go to table of contents

Method: passwordReset

Parameters:

email - User Email

Description: provides ability to reset user’s password.

User will receive mail with link where he can reset his password. Of course user have to use PC and browser to reset his password.

Errors:

{
    "result":false,
    "reason":"Email address missed in request",
    "code":400
}

Example: (javascript + jquery):

$.get( main_api_url + "/passwordReset",  { email : $('input#email').value() },
    function() {
        alert( 'Password recovery email has been sent. Check your mail ' );
    });

go to table of contents

Method: keep-alive

Description: Keep-Alive requests to prolong session.

Parameters: none

Url: http://www.filmon.com/tv/api/keep-alive

Response:

HTTP/1.1 200 Ok if success
HTTP/1.1 410 Gone if session expired.

REQUIRED for client-server connections to keep connection alive.

go to table of contents

Method: checkout/add-to-cart

Description: Adds subscription to server side user’s cart

Url: Link: http://www.filmon.com/tv/api/checkout/add-to-cart/ [subscription-id]

Parameters:

subscription-id is integer value

Response:

success = true | false in answer’s body

go to table of contents

Method: checkout/remove-from-cart

Description: Removes subscription from server side user’s cart

Url: http://www.filmon.com/tv/api/checkout/remove-from-card/ [subscription-id]

Parameters:

subscription-id is integer value

Response:

success = true | false in answer’s body

go to table of contents

Method: checkout/clear-cart

Description: Clears user cart stored on server

Url: http://www.filmon.com/tv/api/checkout/clear-cart

Parameters: none

Response:

success = true | false in answer’s body

go to table of contents

Method: userSubscriptions

Link: http://www.filmon.com/tv/api/userSubscriptions

Parameters: none

Description: Retrieve list of user’s subscriptions

Response:

HTTP/1.1 200 Ok if success.
HTTP/1.1 403 Forbidden if method called in guest mode (you must call ‘login’ method before request userSubscriptions)

go to table of contents

Method: redirect

Description: method may be useful when client application need to transparently redirect customer from ClientApp to website, preserving authorization, checkout cart contents and so on.

Parameters:

url - required. Absolute or relative percent-encoded URL to FilmOn website (affiliated or not).

This action, like all others requires valid session_key parameter.

Response: method should not be called directly from client applications. Instead of calling this method from client applications UA must pass link to API method to browser.

Example:

Link to add subscription #41 to checkout cart and immediately go to checkout:
http://www.filmon.com/api/redirect?session_key=api_session_key&url=https://www.filmon.com/checkout/buyOne?product_id=13616&product_type=1

Direct link to user recordings (DVR) on website:

http://www.filmon.com/api/redirect?session_key=api_session_key&url=http%3A%2F%2Fwww.filmon.com%2Fmy%2Frecordings

Please note: all this links will work while session [api_session_key] is active. Do not forget to add affId parameter to affiliate links.

go to table of contents

Method: dvr/list

Description: retrieve a list of recordings

Url: http://www.filmon.com/tv/api/dvr/list

Response example:

{
    recordings: [
        {  

            channel_title : "ITV 1",
            deletedAt : null,
            description : "Daniel finally attempts to brush off his arty hoard for good 
                - and can Aggie Mackenzie help ninety year old war veteran Frank solve a 
                27-year storage situation?",
            download_link : "http://s1.dvr.gv.filmon.com/schdld/11/33/224/2013.08.13/563806.mp4",
            duration : "01:00",
            id : "563806",
            images : {
                channel_logo : "http://static.filmon.com/couch/channels/11/big_logo.png",
                images : null,
                screenshots : []
            },
            isSoftDeleted : false,
            length : 3600, /* seconds */
            start_timestamp : "1376398800", /* UNIX TIMESTAMP */
            status : "Recorded",
            status_code : "3",
            stream_name : "schdld/11/33/224/2013.08.13/563806.mp4",
            stream_url : "http://s1.dvr.gv.filmon.com/dvr/_definst_/schdld/11/33/224/2013.08.13/563806.mp4/playlist.m3u8",
            time_start : "1376398800",
            title : "Storage Hoarders",
        },
    ],
    userStorage: {
        available : 0.2, /* hours */
        recorded : 9.8, /* hours */
        total : 10 /* hours */
    }
}

go to table of contents

Method: dvr/add

Description: Record a selected programme

Url: http://www.filmon.com/tv/api/dvr/add

Parameters:

channel_id – id of Filmon Channel

programme_id – id of the programme

start_time – start time of the programme

Response:

success = true | false in answer’s body

go to table of contents

Method: dvr/remove

Description: Delete a recording

Url: http://www.filmon.com/tv/api/dvr/remove

Parameters:

record_id – id of the recording

Response:

success = true | false in answer’s body

go to table of contents

Work Flow

A.1 Buying subscriptions

Since current API does not support any In-App purchase - client applications must redirect customer to website to checkout or subscriptions page. The problem that session in API and session on website are not connected and information between this sessions not shared. So, when customer authorized (logged in) in app and trying to open some webpage on www.filmon.com - user will not be authorized on website. To avoid this client applications must use api method ‘redirect’

Few fast links:

  • Add subscription to checkout cart and process to checkout:

http://www.filmon.com/api/redirect?session_key%3Dapi_session_key%26url%3Dhttps%3A%2F%2Fwww.filmon.com%2Fcheckout%2FbuyOne%3Fproduct_id%3Did%26product_type%3Dtype

go to table of contents

A.2 Client-Server standard session

Client                                                            Server
   |                          Init Request                          |
   |--------------------------------------------------------------->|
   |                Server Response: session_key=blabla             |
   |<---------------------------------------------------------------|
   |                                                                |
   |                          Login request                         |
   |--------------------------------------------------------------->|
   |                    Login response: userInfo                    |
   |<---------------------------------------------------------------|
   |                                                                |
   |                   ChannelInfo :11 (format xml)                 |
   |--------------------------------------------------------------->|
   |                Channel Info response (ITV 1 info)              |
   |<---------------------------------------------------------------|
   |                           keep-alive                           |
   |--------------------------------------------------------------->|
   |<---------------------keep-alive response-----------------------|                                                                
                      .    .         .          .         .
   |                                                                |
   |-----------------------------logout---------------------------->|
   |<----------------------------200 ok-----------------------------|
Client                                                            Server

go to table of contents

Messages

  1. Client->server Init request

    GET http://www.filmon.com/tv/api/init HTTP/1.1

    Host: www.filmon.com

    Content-Length: 0

    Connection: Keep-Alive

    User-Agent: Bob Marley Spec Browser (win32, 1.0)

  2. Server->Client Init response

    HTTP/1.1 200 Ok

    Server: www.filmon.com

    Content-Length: 59

    Content-Type: application/json

    Connection: close

  3. Client->Server login request

    POST http://www.filmon.com/tv/api/login?session_key=blablabla HTTP/1.1

    Host: www.filmon.com

    Content-Length: 59

    Content-Type: application/x-www-form-urlencoded

    Connection: Keep-Alive

    User-Agent: Bob Marley Spec Browser (win32, 1.0)

    login=vasya.pupkin@filmon.com&password=1a1dc91c907325c69271ddf0c944bc72

  4. Server->Client Login response

    HTTP/1.1 200 Ok

    Server: www.filmon.com

    Content-Length: 59

    Content-Type: application/json

    Connection: close

    {"id":8539, "email":"vasya.pupkin@filmon.com", "login":"vasya.pupkin@filmon.com", "subscriptions":[], "favourite_channels":[] }

  5. client->server Channel Info request

    GET http://www.filmon.com/tv/api/channel/11?format=xml&session_key=blablabla HTTP/1.1

    Host: www.filmon.com

    Content-Length: 0

    Connection: Keep-Alive

    User-Agent: Bob Marley Spec Browser (win32, 1.0)

  6. server->client channel info response

    HTTP/1.1 200 Ok

    Server: www.filmon.com

    Content-Length: 59

    Content-Type: application/xml

    Connection: close     11

    16:9 -1                 14                 16                 40                 41

  7. Client->Server Keep-Alive

    GET http://www.filmon.com/tv/api/keep-alive?session_key=blablabla HTTP/1.1

    Host: www.filmon.com

    Content-Length: 0

    Connection: Keep-Alive

    User-Agent: Bob Marley Spec Browser (win32, 1.0)

  8. Server->Client keep-alive response

    HTTP/1.1 200 Ok

    Server: www.filmon.com

    Content-Length: 0

    Connection: close

  9. Client->Server Logout request

    GET http://www.filmon.com/tv/api/logout?session_key=blablabla HTTP/1.1

    Host: www.filmon.com

    Content-Length: 0

    Connection: Keep-Alive

    User-Agent: Bob Marley Spec Browser (win32, 1.0)

10: Server->Client logout response

HTTP/1.1 200 Ok

Server: www.filmon.com

Content-Length: 0

Connection: close

go to table of contents

A.3 Google IMA (Interactive Media Ads) settings

If Google IMA is enabled by configuration, there will be related settings in the response of init method:

"google-ima": {
    "vastUrl": "http://pubads.g.doubleclick.net/?&url=[referrer_url]&correlator=[timestamp]",
    "custom_vars": {
        "channel": "{channelId}",
        "app-name": "{appname}",
        "devicetype": "tablet",
        "affid": "__yourAffId__",
        ...
    }
}

To get Google IMA working, client application should generate VAST URL by these steps:

  • In vastUrl replace all placeholders with actual values
    • [referrer_url]
    • [timestamp]
  • Generate cust_params value using all custom_vars from response of init method and replace all placeholders in this manner:
    • channel={actual-channel-id}&app-name={your-app-name}&devicetype=tablet&affid={your-real-affid}&and-so-on=...
  • Add url-encoded value of cust_params to vastUrl.

As result final VAST url should look like:

http://pubads.g.doubleclick.net/...?...&url=http%3A%2F%2F...&correlator=1385391353&cust_params=channel%3D14%26app-name%3Dyour-app-name%26devicetype%3Dtable%26affid%3Dyour-affid

Please refer to https://developers.google.com/interactive-media-ads/ for additional information about using Google IMA SDK

go to table of contents