NAV
     

Anvato Feeds API

Feeds API is designed for managing authorized access to JSON feeds, resources (e.g., media assets) and application building blocks in a scalable manner. The objective of this document to describe the REST APIs that a third party application developer (e.g., mobile front-end developer) could use to provide access to authorized users and display the correct error messages to unauthorized users and deny them access.

Features

Scalable Service from Edges

Anvato Feeds queries are scalable and very fast as they are served from the closest edges.

Flexible Queries

Anvato Access allows on-the-fly querying of the MCP media items and generating lightweight feed responses for consumption by clients.

Access Control

Feeds API will enforce access control settings such as IP, country, device and complex combinations of each as specified in MCP while authorizing access to resources.

Subscription and User Management

Aside from read-only query APIs, you can use the Feeds API for write-enabled user management APIs to store data such as user preferences, user history, playback progress, etc.

Monetization

Built-in server side adstitch can be enabled and controlled from MCP.

Development Guide

Feed Queries

Feed urls are generated in MCP and they have the following form:

https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM

There are 4 types of feeds: Program, Video, Live Channel, Live Event. Depending on the use case, you will have access to the appropriate feed. Each type of feed has slightly different but important core fields. For example, a live event feed can power a live schedule API as it always includes a begin/end time for the objects it lists. A program feed follows a well defined hierarchy of videos, seasons and programs. A Video feed provides a flat list of videos, and a live channel feed provides a list of live channels available.

Pagination

You must always paginate the feed requests by specifying an offset and a maximum total item count returned. Maximum item count is capped at 100:

https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?start=20&count=20

Request

GET /v2/feed/{FEED_ID}?start=<start>&count=<count>

Requires:

Basic authentication with API keys.

Parameters:

Parameter Description Optional
start Starting 0 based offset Yes
count Number of items in the page (internally capped at 100) Yes

Ordering

Feed results can be ordered using any of the fields that appear in the feed:

https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?sort=c_media_s+desc

Request

GET /v2/feed/{FEED_ID}?sort=<sort method>

Requires:

Basic authentication with API keys.

Parameters:

Parameter Description Optional
sort comma separated one or more sorting orders: e.g., my_field1 asc, my_field2 asc, my_field3 desc Yes

For descending order you should use DESC, for ascending order use ASC.

Filtering

Filtering is the main tool for carving out specific sub feeds from a master feed. For example,

Master feed contains many videos https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM

A subset of this feed with Action movies is accessed as https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?filters[]=c_category_smv:action

And from the same feed, a subset with Comedy movies is accessed as https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?filters[]=c_category_smv:comedy

Multiple filters can be combined: https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?filters[]=c_category_smv:comedy&filters[]=c_category_smv:action

Request

GET /v2/feed/{FEED_ID}?filters[]=<filter1>&filters[]=<filter2>

Requires:

Basic authentication with API keys.

Parameters:

Parameter Description Optional
filters[] (1 or more) Pair of field name-field value separated by a colon (%3A) Yes

Filter Macros

Filters are internally cachable. If you rely on filtering too much, you should use the provided macros where possible.

For example, the most commonly used macro is the current time macro (ANV_MACRO_NOW) which evaluates to the unix timestamp in seconds. Typical use case for this macro is;

filters[]=c_ts_publish_l:[* TO ANV_MACRO_NOW] (url encoding is skipped for brevity)

Following is the current list of supported macros:

Macro name Evaluates to
ANV_MACRO_NOW Current unix timestamp in seconds.
ANV_MACRO_COUNTRY 2 letter country-code of the requestor.
ANV_MACRO_STATE 2 letter state-code of the requestor.

Media Filtering

Media Filtering allows picking specific mime types from a given feed.

Request

GET /v2/feed/{FEED_ID}?media_filters[]=<filter1>&media_filters[]=<filter2>

Requires:

Basic authentication with API keys.

Parameters:

Parameter Description Optional
media_filters[] (1 or more) Specify mime-types. e.g., media_filters[]=video/mp4 Yes

Free form text search can be performed on the feed. Search includes all of the fields.

https://api.anvato.net/v2/feed/LBIRGALVQJWB3ARM?q=rabbit

Request:

GET /v2/feed/{FEED_ID}?q=<search text>

Requires:

Basic authentication with API keys.

Parameters:

Parameter Description Optional
q Free form text to search for.

Recommendations Feed:

Depending on whether the recommendation engine is enabled or not, a special recommendations feed is auto-generated for every user. It has the same format as a regular feed. It can be accessed at

https://api.anvato.net/v2/recommendations?access_token={ACCESS_TOKEN}

Note that access_token is required which is only available after client side login.

Media Playback

There is no direct media playback as all media urls must be accessed from the feed responses.

Cookies/Security

The playback must be accompanied by the access_token. Existence of an authorized access_token leaves a cookie to identify the client. This cookie will later be passed to the encryption key server as specified in the HLS manifest. The key server only provides the decryption key upon reception of a valid cookie.

Access Control

Content access restrictions are defined in MCP and they apply to configurations. A configuration can be limited to serve a specific IP set, domain, geographical region or user agents.

If content access is blocked, the relevant APIs above will return 403 and an explanation in the body.

You can perform "pre-flight" check to determine whether access to a specific configuration will be blocked as follows:

Request:

GET /v2/whoami

Parameters:

Parameter Description Optional
cfg_id Configuration id created in MCP No

Requires:

Basic authentication with API keys for this configuration.

Response:

{      "ts": <server time>,      "ip": <client ip>,      "geo": {      .... "country": <client country>,      .... "region": <client region>      },      "allowed": <whether access is blocked or not> }

Server Side Signatures

Generating Video Embed Code Tokens

Sample PHP code to generate server side API token

function generate_play_token ( $secret_key, $video_id, $expire=0, $client_ip="" )
{
    $version = 2;
    $pars = array (
        $version,
        $expire,
        $client_ip
    );

    $doc = "{$secret_key}~{$pars[0]}~{$pars[1]}~{$pars[2]}~{$video_id}";

    $sgn = base64url_encode ( hash_hmac ( "sha256", $doc, $anvack['secret_key'], true ) );
    $pars = base64url_encode ( implode ( "~", $pars ) );

    $token = "{$sgn}~{$pars}";

    return $token;
}

function base64url_encode($data) 
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

All embed code must include a valid token. We use HMAC message authentication codes with SHA256 hashes.

The document to sign is created by concatenting secret key, version, (optional) expire time, (optional) client ip:

doc = MYSECRETKEY~2~1463609250~173.164.191.233 signature = Base64MCP ( HASH_HMAC ( "SHA-256", secret_key, doc ) )

then the token is created by concatenating signature and token parameters:

token=Base64MCP(signature), Base64MCP(version~expire_time~client_ip)

where Base64MCP() is a Base64 variant for replacing url sensitive characters with dash(-) and underscore(_) for brevity.

Generating Feed and API Tokens

Sample PHP code to generate server side API token

function anvato_api_tokenize ( $url, $secret, $ip=false, $exp=0 )
{
    $ts = time();

    // url and key are always included.
    $doc = "{$url},{$secret},{$ts}";

    $query = array();
    $kmap = array();
    $token = "";
    if ( $ip )
    {
        $kmap["ip"] = $ip;
    }

    if ( $exp )
    {
        $kmap['exp'] = $exp;
        $query['exp'] = $exp;
    }

    if ( $kmap )
        $doc .= ",".implode(",", $kmap );

    // $doc is ready. Compute the hmac
    $raw_hmac = hash_hmac ( "sha256", $doc, $secret, true );

    $query['k'] = implode ( ",", array_keys($kmap) );
    $query['hmac'] = trim ( base64_encode ( $raw_hmac ), "=" );
    $query['ts'] = $ts;

    // token is built in a slightly custom way to result in a shorter string.
    // Here we combine the above key-value pairs with an equal sign(=) and a tilde (~)
    // e.g., a=aval~b=bval
    $token = "";
    foreach ( $query as $k=>$v )
    {
        if ( $token )
            $token .= "~";
        $token .= "{$k}={$v}";
    }

    return "anvtok=".urlencode ( $token );
}

All resources can be accessed with tokens, thereby assigning an expiration time and optionally associating a request with an IP.

Server side signatures are generated on your backend server using standard hash based message authentication codes (HMAC) using SHA-256 hash.

We will walk-through signing the following URL: https://api.anvato.net/v2/play/92476594328765

Message to sign:

The following pseudo code should be followed to create the message to sign:

message = url_path + "," +private_key + "," +current_time + "," + client_ip + "," + expire_time

where the parameters are string concatenated with comma separators. client_ip and expire_time are optional.

url_path = This is the path portion of a media url, i.e., /v2/play/92476594328765

private_key = The private key obtained from MCP.

current_time = Current UNIX timestamp of your server in seconds.

expire_time = (optional) UNIX timestamp after which the token is invalid.

ip = (optional) Associates this authentication token to this client IP only.

Therefore the message is:

message=/v2/play/92476594328765,YOURPVTKEY,14683719827,173.164.191.236,14683729827

Signature:

Then the signature is the HMAC with SHA256:

signature_hmac = base64_encode(hmac('sha256', message))

Token

Token is made of these components:

The request token is generated by combining the token components with "=" and "~", followed by url encoding :

REQUEST_TOKEN = url_encode ( "hmac=signature~exp=expire_time~k=ip,exp" )

Finally, token is included in the request url as the anvtok query parameter:

https://api.anvato.net/v2/type/id?anvtok=REQUEST_TOKEN

Example: Create a token and enforce an expire time

If we use the following fake keys: private_key = 9losj287

then the safe_signature is: safe_sgn = MJSGh4pfxVq3XhK2DoYz4wq2ycrgcPIWMuccaKzsFTY%3D

Generated signature can be used as follows; https://api.anvato.net/v2/play/924765?sgn=safe_sgn&key=X&flags=ip&age=900&ts=14683719827

Client Side Tokens

Anvato Access applies media playback restrictions via tokens. Tokens can be generated either at the server side or at the client side. Most Anvato customers are encouraged to use client side tokens.

Client side tokens can only be used if integrated Anvato Access user management is active; otherwise, you should generate tokens on the server side and attach to the media playback requests.

Client side tokens support cookies, however does not require cookies if passed as query parameters.

Client side token can safely be used in the client SDKs without having to embed sensitive keys.

Creating a client side access token

HTTP Request:

curl https://api.anvato.net/v2/token \
        -d type=login \
        -d cfg_id=zzz \
        -d email=xxx \
        -d password=yyy

POST /v2/token

Parameters:

Parameter Description
type Must be "login"
cfg_id Configuraton ID in MCP
email User email
password User password

Requires:

Basic authentication with API keys.

HTTP Response

{      "access_token" : "<access token>",      "expires" : "<token is valid until this timestamp>",      "user_id" : "<unique user id>",      "name" : "<user name>",      "appdata" : "<application data if any>" }

User Management

User Management is integrated with payment gateways.

Create a user

Create user API can safely be used on a client side application as it requires a valid third party generated token which is confirmed valid by a server side query confirming the authenticity of said token.

For example, you can generate a stripe token using Stripe.js and the publishable Stripe key.

HTTP Request:

PUT /v2/user

Parameters:

Parameter Description Optional
cfg_id Configuration id from MCP No
auth_token stripe:tok_XXX No
plan selected plan name No
email user email No
name display name. Can be different than name on card No
password login password No
status status code. See below for possible values No

Requires:

Basic authentication with API keys.

Response:

20X on success.

Update a user

All fields except access_token are optional. Note that there is no address field as it is dependent on server side authentication. If address needs to be updated, a new auth_token must be provided which will also update the payment information.

Disabling a user login can be done by updating status to "disabled".

A soft delete can be performed by setting the status to "deleted".

Request:

PUT /v2/user/{USER_ID}

Parameters:

Parameter Description Optional
access_token Access Token received from authentication step No
auth_token Value to replace Yes
plan selected plan id in MCP Yes
email user email Yes
name display name. Can be different than name on card Yes
password login password Yes
status status code. See below for possible values Yes

Requires:

Basic authentication with API keys.

Returns:

20X on success.

Retrieve user

Retrieves the basics of a user account. This is useful for initializing an "Account" page on your application for the users to see their settings.

Request:

GET /v2/user?access_token={access_token}

Requires:

Basic authentication with API keys.

Returns: (JSON) {     "email" : "<...>",     "name" : "<...>",     "plan" : "<...>",     "status" : "<...>",     "cc_summary" : {      "last4" : "...",      "type" : "visa, amex, etc.",      "expires" : "MM/YYYY"     },     "address" : "" }

Store general purpose key-value pairs

Persistently records a user specific key with the given value.

Request

Store a general purpose key named "my_key" for the user EED7D9BC

curl http://api.anvato.net/v2/user/EED7D9BC/store/my_key \
   -d 'access_token=...' \
   -d value=My+Value

Retrieve a general purpose key named "my_key"

curl -G http://api.anvato.net/v2/user/EED7D9BC/store/my_key \
   -d 'access_token=...'

PUT /v2/user/{USER_ID}/store/{KEY_NAME}

GET /v2/user/{USER_ID}/store/{KEY_NAME}

Requires:

Client side user access token.

Parameters:

Parameter Description Optional
access_token Access token No
value Free-form string at most 2048 bytes long No

Returns:

PUT returns 20X on success. GET returns the free-form string.

Store user ratings

Persistently records a user's rating for a given object. If recommendations module is also active, this data is used during recommendation generation.

Request

PUT /v2/user/{USER_ID}/rate/{OBJ_ID}

Requires:

Client side user access token.

Parameters:

Parameter Description Optional
access_token Access token No
score 1...5 No

Returns:

20X on success

Store user watch progress

Persistently records a user's watch progress. Cross-platform resume capability is powered by this API.

Request:

PUT /v2/user/{USER_ID}/progress/{OBJ_ID}

Parameters

Parameter Description Optional
access_token Access token No
progress 0...100 No

Requires:

Client side user access token.

Returns:

20X on success

Store user specific application data

You can use the applicaton data API to store a free-form string per-user. This is useful for sharing cross-platform data for each user.

Request:

PUT /v2/user/{USER_ID}/appdata

Parameter Description Optional
access_token Access token No
data Any free-form string shorter than 1024 bytes. No

Requires:

Basic authentication with API keys.

Returns:

20X on success

Errors

The Feeds API uses the following standard error codes:

Error Code Meaning
400 Bad Request -- There was an error with your request, such as missing mandatory field or invalid value.
401 Unauthorized -- Your API key/token is wrong.
403 Forbidden -- Your access level does not allow the requested operation.
404 Not Found -- Object or endpoint does not exist.
405 Method Not Allowed -- Object or endpoint does not support the specified method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- Object was deleted and is no longer available.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarially offline for maintanance. Please try again later.