NAV Navbar
Logo
shell python json

Introduction

Welcome to the Uru API Documentation!

Authentication

Replace the parameters <your id> and <your secret> with the username and password provided by the Uru team.

//This is the JSON response for the request

{
"access_token":“<your token>”,
"token_type":"bearer",
"expires_in":971989145,
"scope":"read write"
}
curl -X POST 
-d "client_id=<your id>&client_secret=<your secret>&
grant_type=client_credentials" 
http://api.uruvideo.com/cv_backend/oauth/token
uruurl = 'http://api.uruvideo.com/cv_backend/oauth/token'
data = "client_id=<your id>&client_secret=<your secret>&grant_type=client_credentials"
r = requests.post(uruurl,data=data)
if(r.status_code == 429):
            print "Rate limit reached! Try again later after you finish processing your other pending videos"
elif r.status_code != 200:
            print r.text
else:
            print r.json()

Authentication to the API is done through OAuth2 Authentication.

HTTP Request

To request a token:

OAUTH 2.0 endpoint http://api.uruvideo.com/cv_backend/oauth/token

Request Parameters

Parameter Description
Client Id Your client username
Secret Your client password
Grant Type Value is: “Client Credentials”

As a response, you will get the token used to make API calls.

Using the token

Uru expects for the API token to be included in all API requests to the server in a header that looks like the following:

Authorization: Bearer <token>

Brand Safety API

Our Brand Safety API analyzes an inputted video, outputting a brand safety score and details about that score.

The workflow for analyzing a video is divided into two main steps:

Video Upload Endpoint

The code below assumes that you are uploading a file from your local file system. The upload request is performed as part of a multipart form request and the video is sent to the Uru servers. We support .mp4, .mov and .avi media files

curl -XPOST api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze
-H "Authorization: Bearer <your token>" 
-F "file=@<location of your file>"
import requests
uruurl = 'http://api.uruvideo.com/cv_backend/video_upload/brand_safety/analyze'
headers = {"Authorization":"Bearer <your token>"}
files = {'file':open("<your video file path>","rb") }
r = requests.post(uruurl,files=files,headers=headers)
if(r.status_code == 429):
            print "Rate limit reached! Try again later after you finish processing your other pending videos"
elif r.status_code != 200:
            print r.text
else:
            print r.json()["responseBody"]
//This is the JSON response for the request

{
  "error": null,
  "responseBody": {
    "id": 2411248218434,
    "percentage": 20,
    "currentStatus": "SCORING",
    "createdDate": "2017-06-01 00:47:25"
  }
}

This API allows the upload of a video file to Uru. Currently, .mp4 and .avi file formats are supported.

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze

Request type: POST

Request Parameters Passing the following parameters in the body of the request (form data):

Parameter Name Description
file Video file to be analyzed by Uru
url (Optional)(Available on Beta) An URL of the media asset can be passed instead of the actual file.

Response Once the file is uploaded, Uru will return an id that can be used to check if the video has been processed and, after the processing is done, to retrieve the final results.

Response Field Description
id Id of the current task
percentage What percentage of the current task is done
status What is the status of the task being performed
createdDate Timestamp of when the video was uploaded

Get Score Endpoint

curl -x GET api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze/{id}
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze/{id}'
headers = {"Authorization":"Bearer <your token>"}
r = requests.get(uruurl)
if(r.status_code == 404):
            print"The API endpoint you tried to access does not exists"
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]
//This is the JSON response for the request

{
  "error": null,
  "responseBody": {
    "id": 2411248218434,
    "percentage": 100,
    "currentStatus": "SCORING",
    "analysis":{
        "brandSafetyAnalysis":{
            "score": 0.5,
            "unsafeTags": ["alcohol", "gun"],
            "unsafeLanguage":{
                "count" : 4,
                "occurrences":["damn","bloody","hell","turd"]
            },
            "identifiedBrands":{
                "count": 2,
                "occurrences":  ["Reebok", "Nike"]
            },
            "NSFWContent":{
                "count": 1,
                "occurrences":["adult"] // right now we detect adult, gore and violent content
            }
        }
    },
    "scenes":[
        {
            "sceneId":1234,
            "initTime": 0,
            "length": 23.54,
            "analysis":{
                "brandSafetyAnalysis":{
                    "score": 0.8,
                    "unsafeTags": ["alcohol"],
                    "unsafeLanguage":{
                        "count" : 2,
                        "occurrences" : ["damn","bloody"]
                    },
                    "identifiedBrands":{
                        "count": 1,
                        "occurrences":  ["Nike"]
                    },
                    "NSFWContent":{
                        "count": 0,
                        "occurrences":[]
                    }
                }
            }

        },
        {
            "sceneId":1235,
            "initTime": 23.55,
            "length": 40.00,
            "analysis":{
                "brandSafetyAnalysis":{
                    "score": 0.2,
                    "unsafeTags": ["gun"],
                    "unsafeLanguage":{
                        "count" : 2,
                        "occurrences":["hell","turd"]
                    },
                    "identifiedBrands":{
                        "count": 1,
                        "occurrences":  ["Reebok"]
                    },
                    "NSFWContent":{
                        "count": 1,
                        "occurrences":["adult"]
                    }
                }
            }
        }
    ]
  }
}

After your video is processed, you can retrieve its overall brand safety score, along with details about why the video received that score.

API Endpoint api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze/{id}

Request Type: GET

Request Parameters Pass the following parameter in the URL of the request

Parameter Name Description
id Video Upload id from the Video Upload Endpoint
unsafeTags (Optional) Comma separated list of tags that are considered unsafe. Example: unsafeTags=guns,alcohol By default, Uru will use its own internal unsafe tags if nothing is provided.
competitiveBrands (Optional) Comma separated list of brands that are considered competitive. Example: competitiveBrands=Nike By default, Uru will take into account all brands it finds.
url (Optional)(Available on Beta) The analysis can be retrive through the URL of the submitted asset. In this case, id should be fixed as the string external and the URL of the asset should be passed in this parameter. Example: http://api.uruvideo.com/cv_backend/api/video_upload/brand_safety/analyze/external?url=http%3A%2F%2Fwww.somevideo.com%2Fvideo.mp4

Response

The brand safety analysis is divided into three main parts.

  1. Response Body

The response body is the main element of your response and contains the data relevant for the whole video.

Response Field Description
id Id of the current task
percentage What percentage of the current task is done
status What is the status of the task being performed
createdDate Timestamp of when the video was uploaded
analysis Analysis object containing the summary of the brand safe analysis for the whole video
scenes List of Scene objects containing all the scenes inside the video
competitiveBrands Brands logos or mentions that appear inside the video track
  1. Scene

The Scene object has the information about a certain section of the video that composes a scene.

Response Field Description
sceneId Internal Id of the scene
initTime Time (in seconds) the scene starts
length How much time (in seconds) the scene lasts
analysis Analysis object containing the summary of the brand safe analysis for the whole video
  1. Brand Safety Analysis

The Brand Safety Analysis object contains detailed information about the brand safety analysis Uru has performed.

Response Field Description
score Brand safety score calculated by Uru for the Scene or whole Video
unsafeTags Unsafe themes and objects detected inside your video
unsafeLanguage Unsafe language (hate speech, swearing, etc…) identified in the audio track of your video
identifiedBrands Brands logos or mentions that appear inside the video track
NSFWContent Not Safe For Work content detected inside your video: violent graphics or mentions, nudity or gore are flagged in this section.

StoryBreak API

This document explains how to use our API to instantly identify the breaks inside the story that a video tells (and, therefor, where you can insert mid-roll or ad pods in a seamless-feeling, less disruptive way). This process is powered by AI that studies all of the sights, sounds, and text inside the video. If you feed us data about how viewers are interacting with the StoryBreaks that we have found (e.g., viewer drop-off data), our AI will learn from it and adjust the StoryBreaks inside that video (and future ones) accordingly, optimizing engagement based on viewer location, time, device and profile.

Video Upload Endpoint

curl -X POST api.uruvideo.com/cv_backend/api/video_upload/breaks
-H "Authorization: Bearer <your token>"
-F "file=@<location of your file>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/breaks'
headers = {"Authorization":"Bearer <your token>"}
files = {'file':open("<your video file path)","rb"}
r = requests.post(uruurl, files=files, headers=headers)
if(r.status_code == 429):
            print"Rate limit reached! Try again later after you finish processing your other pending videos."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]
//The response will be a VideoUpload entity, such as the example below

{
  "error": null,
  "responseBody": {
    "id": 1177,
    "externalId": "your external id",
    "percentage": 0,
    "currentStatus": "UNDER_ANALYSIS",
    "finalUrl": "",
    "message": "Uploading",
    "thumbnail": null,
    "name": "1.mp4",
    "createdDate": "2017-01-07 15:46:46",
    "totalTime": null,
    "labels": null,
    "warningMessage": null
  }
}

The first request uploads the video content to the Uru servers. This is required in order for Uru to run your video through its artificial intelligence models.

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/breaks

Authentication : API TOKEN(OAuth 2)

Request Type: POST(FORM)

Request Parameters The following parameters are expected inside the request form:

Parameter Name Type Description
videoFile Binary File The Actual video file in one of the supported formats(mp4,mov).
externalId String (Optional) An unique external id to associate with the current video. This can be any kind of string such as an URL, numeric id, etc . .

Get Status Endpoint

//The response will be a VideoUpload entity, such as the example below. Once the percentage field reaches 100, your breaks are ready to be retrieved:

{
  "error": null,
  "responseBody": {
    "id": 1177,
    "externalId": "your external id",
    "percentage": 60,
    "currentStatus": "UNDER_ANALYSIS",
    "finalUrl": "",
    "message": "Uploading",
    "thumbnail": null,
    "name": "1.mp4",
    "createdDate": "2017-01-07 15:46:46",
    "totalTime": null,
    "labels": null,
    "warningMessage": null
  }
}
curl -x GET api.uruvideo.com/cv_backend/api/video_upload/{id}
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/{id}'
headers = {"Authorization":"Bearer <your token>"}
r = requests.get(uruurl, headers=headers)
if(r.status_code == 401):
            print"Your token is invalid. Please re-authenticate or check your username."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

To check the status of the request and review if the breaks are processed, the following request can be made:

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/{id}

Authentication: API TOKEN (OAuth 2)

Request Type: GET

Request Body: NONE

Get Breaks Endpoint

//Example of JSON response with the breaks in seconds:

{
  "error": null,
  "responseBody": {
    "uploadID": 1639,
    "numberOfFrames": 143186,
    "lengthInSecond": 5972.049416666666,
    "numberOfBreaks": 16,
    "splits": [
      {
        "score": 0.040521154029529334,
        "reason": 2,
        "time": 612.9039583333333
      },
      {
        "score": 0.0565970434832556,
        "reason": 2,
        "time": 864.6971666666666
      },
      {
        "score": 0.035541680252746725,
        "reason": 2,
        "time": 1129.1697083333333
      },
      {
        "score": 0.0712440129145001,
        "reason": 2,
        "time": 1372.7880833333331
      },
      {
        "score": 0.928085018002935,
        "reason": 2,
        "time": 1741.364625
      },
      {
        "score": 0.06934087079733757,
        "reason": 2,
        "time": 2076.7413333333334
      },
      {
        "score": 0.04956235887340174,
        "reason": 2,
        "time": 2339.253583333333
      },
      {
        "score": 0.8779198334334315,
        "reason": 2,
        "time": 2579.618708333333
      },
      {
        "score": 0.04844528265170706,
        "reason": 2,
        "time": 2849.4299166666665
      },
      {
        "score": 0.07675993622304964,
        "reason": 2,
        "time": 3127.87475
      },
      {
        "score": 0.048181206726867265,
        "reason": 2,
        "time": 4011.924583333333
      },
      {
        "score": 0.05010503282414913,
        "reason": 2,
        "time": 4261.4655416666665
      },
      {
        "score": 0.026985269735959903,
        "reason": 2,
        "time": 4515.886375
      },
      {
        "score": 0.04863334529880011,
        "reason": 2,
        "time": 4758.712291666667
      },
      {
        "score": 0.5740612045358578,
        "reason": 2,
        "time": 5008.044708333333
      },
      {
        "score": 0.0509798847147153,
        "reason": 2,
        "time": 5275.228291666666
      }
    ]
  }
}
curl -x POST -d "{\r\n\"clientTimezome\" : \"GTM-5\",\r\n\"clientDevice: \"MAC OSX\"\r\n,\r\n\"allBreaks: true\r\n}" api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/breaks
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/breaks'
headers = {"Authorization":"Bearer <your token>"}
data = "{\r\n\"clientTimezome\" : \"GTM-5\",\r\n\"clientDevice: \"MAC OSX\"\r\n,\r\n\"allBreaks: true\r\n}"
r = requests.post(uruurl,data, headers=headers)
if(r.status_code == 500):
            print"Something went wrong with your video request."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

After your video is uploaded to Uru and it has been processed, you can make requests to get the best story breaks inside it. Because these breaks are constantly updated and are also tailored to each individual viewer’s data, these requests are ideally made each time a new viewer comes to watch the video.

API Endpoint api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/breaks

Request Type: POST(JSON)

Request Body A JSON wiht the parameters of the request.

Example of the JSON:

{
"clientTimezone" : "GTM-5",
"clientDevice": "MAC OSX"
}

Request Parameters

Some parameters may be passed on the POST request to customize the breaks return by Uru;

Parameter Parameter type Description
clientTimezone String The timezone where the client is watching the video.
clientDevice String The type of device the client is watching the video.
numberOfBreaks Integer (Optional) You may define how many breaks you want our algorithm to find. The default behavior is for our algorithm to find the optimal number of breaks automatically or return all if the parameter allBreaks is set
minimumInterval Double (Optional) Determine the minimum interval between subsequent ads in seconds. By default, the value is set automatically according to the number of breaks.
responseType String (Optional) Response in result in JSON format.
allBreaks Boolean (Optional) Return all breaks in the video and their respective score.

Dropout Endpoint

curl -x POST
-d "{\r\n\"clientTimezome\" : \"GTM-5\",\r\n\"clientDevice: \"MAC OSX\"\r\n}" api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/dropout
-H "Authorization: Bearer" -H “Content-Type:application/json” <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/dropout'
headers = {"Authorization":"Bearer <your token>", "Content-Type": "application/json"}
data = "{\r\n\"clientTimezome\" : \"GTM-5\",\r\n\"clientDevice: \"MAC OSX\"\r\n}"
r = requests.post(uruurl, data, headers=headers)
if(r.status_code == 500):
            print"Something went wrong with your video request."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]
//
{
"clientTimezome" : "GTM-5",
"clientDevice: "MAC OSX"
}

When a viewer drops out, our system must be notified. This is because:

API Endpoint api.uruvideo.com/cv_backend/api/video_upload/internal/{id}/dropout

Authentication :API TOKEN(OAuth2)

RESPONSE : HTTP 200

Request Type: POST(JSON)

Request Body A JSON with the parameters of the request.

Request Parameters

Parameter name Parameter type Description
clientTimezone String The timezone where the client is watching the video.
clientDevice String The type of device the client is watching the video.

Content Recognition API

This document explains how to use our API to instantly identify objects and themes inside video content. This API is powered by artificial intelligence that studies the sights, sounds, and text inside a video and then, based on what it sees, delivers a set of tags that will help you power search, recommendation, or pair your content with ads and product listings. As users update, add or remove the tags that were automatically identified, our AI also learns to personalize future tags based on that user input. Specifically, it will get better at predicting the tags that are most relevant for that particular user and their use case.

Upload Video Endpoint

//The response will be a VideoUpload entity, such as the example below:

{
  "error": null,
  "responseBody": {
    "id": 1177,
    "percentage": 0,
    "currentStatus": "UNDER_ANALYSIS",
    "finalUrl": "",
    "message": "Uploading",
    "thumbnail": null,
    "name": "1.mp4",
    "createdDate": "2017-01-07 15:46:46",
    "totalTime": null,
    "labels": null,
    "warningMessage": null
  }
}
curl -XPOST api.uruvideo.com/cv_backend/api/video_upload/tag
-H "Authorization: Bearer <your token>" 
-F "file=@<location of your file>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/tag'
headers = {"Authorization":"Bearer <your token>"}
files = {'file':open("<your video file path)","rb"}
r = requests.post(uruurl, files=files, headers=headers)
if(r.status_code == 429):
            print"Rate limit reached! Try again later after you finish processing your other pending videos."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

The first request uploads the video content to the Uru servers. This is required in order for Uru to run your video through its artificial intelligence models. This request is as follows:

API EndPoint: api.uruvideo.com/cv_backend/api/video_upload/tag

Authentication: API TOKEN (OAuth2)

Request Type: POST(FORM)

Request Body: The following parameters are expected inside the request form:

Parameter Name Type Supported Formats Description
file Binary file MP4, MOV The actual video file in one of the supported formats

Get Video Tags Endpoint

//The response will be a VideoUpload entity, with the tags inside the field labels, which is a list of Label Entities, such as the example below:

<!-- CODE SNIPPET -->
{
 "error": null,
 "responseBody": {
 "id": 1907,
 "percentage": 100,
 "currentStatus": "UNDER_TAG",
 "finalUrl": "",
 "message": "Tag video done",
 "thumbnail": "http://url/scene_1/clean_thumbnail.jpg",
 "name": "yogashort.mp4",
 "createdDate": "2017-02-21 22:36:59",
 "totalTime": 12.514104617217754,
 "labels": [
 {
 "id": 31572,
 "name": "hobbies & interest",
 "score": 1,
 "granularity": 1
 },
 {
 "id": 31573,
 "name": "text",
 "score": 0.4743947,
 "granularity": 3
 },
 {
 "id": 31574,
 "name": "leisure",
 "score": 0.47177458,
 "granularity": 3
 },
 {
 "id": 31575,
 "name": "logo",
 "score": 0.4508584,
 "granularity": 3
 },
 {
 "id": 31576,
 "name": "swimming pool",
 "score": 0.414691925,
 "granularity": 3
 },
 {
 "id": 31577,
 "name": "font",
 "score": 0.4100479,
 "granularity": 3
 },
 {
 "id": 31578,
 "name": "product",
 "score": 0.37484885,
 "granularity": 3
 },
 {
 "id": 31579,
 "name": "physical fitness",
 "score": 0.3475046,
 "granularity": 3
 },
 {
 "id": 31580,
 "name": "vacation",
 "score": 0.34696575,
 "granularity": 3
 },
 {
 "id": 31581,
 "name": "advertising",
 "score": 0.3113372,
 "granularity": 3
 }
 ],
 "filters": [],
 "warningMessage": null
 }
}
curl -x GET api.uruvideo.com/cv_backend/api/video_upload/{id}
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/{id}'
headers = {"Authorization":"Bearer <your token>"}
r = requests.get(uruurl, headers=headers)
if(r.status_code == 401):
            print"Your token is invalid. Please re-authenticate or check your username."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

After your video is uploaded to Uru, you can check if the processing is done or not by making a call to get the video tags. If processing is not complete, then the field “percentage” in the VideoUpload entity will show a number less than 100 and the field “labels” will be empty. once the video is done. Once processing is complete, the field “percentage” in the VideoUpload entity will display 100 and the tags for your video will be shown in the “labels” field.

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/{id}

Authentication: API TOKEN (OAuth2)

Request Type :GET

Request Body: None

Response

The Get Video Tags analysis is divided into two parts.

  1. Response Body

The response body is the main element of your response and contains the data relevant for the whole video.

Response Field Description
Id Id of the current task
percentage What percentage of the current task is done
message What is the status of the task being performed
  1. Labels

The Labels object has the information about a certain section of the video that composes a scene.

Response Field Description
Id Internal Id of the scene
name Description of scene
score Label accuracy score calculated by Uru for the Scene or whole Video
granularity granularity object containing the score level of detail within the Scene or whole video

Individual Scenes Endpoint

//The response will be a Video entity, such as the example below. Each Video entity has a list of Scenes inside the field sceneUrls. Those scenes have their tags inside the field label, which is a list of Label Entities:

{
  "error": null,
  "responseBody": {
    "username": "brunno",
    "videoId": "1510",
    "videoUrl": "http://s3.amazonaws.com/brohan/brunno/484d68d3-da32-4adb-a6b3-473a12aba69f/video_analysis_pending.mp4",
    "totalTime": 12.514104617217754,
    "percentage": 100,
    "videoName": "yogashort.mp4.mp4",
    "status": "UNDER_TAG",
    "sceneUrls": [
      {
        "id": 8180,
        "url": "http://url/scene_0/clean.jpg",
        "scene": {
          "initFrame": 0,
          "surfacesList": [],
          "label": [
            {
              "id": 31582,
              "name": "text",
              "score": 0.4743947,
              "granularity": 3
            },
            {
              "id": 31583,
              "name": "logo",
              "score": 0.4508584,
              "granularity": 3
            },
            {
              "id": 31584,
              "name": "font",
              "score": 0.4100479,
              "granularity": 3
            },
            {
              "id": 31585,
              "name": "product",
              "score": 0.37484885,
              "granularity": 3
            },
            {
              "id": 31586,
              "name": "advertising",
              "score": 0.3113372,
              "granularity": 3
            }
          ],
          "motion": false,
          "length": 50,
          "dbId": 8180,
          "imageLocation": "",
          "preview": false,
          "totalTime": 1.6730086386654752,
          "motionValue": null,
          "initTime": 0,
          "confidenceScore": 0,
          "eligible": true,
          "file": null,
          "warp": false,
          "blend": true,
          "shadow": true,
          "facebookSafe": false,
          "logoId": null,
          "initFrameNew": null,
          "endFrameNew": null
        }
      },
      {
        "id": 8181,
        "url": "http://url/scene_1/clean.jpg",
        "scene": {
          "initFrame": 50,
          "surfacesList": [],
          "label": [
            {
              "id": 31587,
              "name": "leisure",
              "score": 0.47177458,
              "granularity": 3
            },
            {
              "id": 31588,
              "name": "swimming pool",
              "score": 0.414691925,
              "granularity": 3
            },
            {
              "id": 31589,
              "name": "physical fitness",
              "score": 0.3475046,
              "granularity": 3
            },
            {
              "id": 31590,
              "name": "vacation",
              "score": 0.34696575,
              "granularity": 3
            },
            {
              "id": 31591,
              "name": "sports",
              "score": 0.2732957,
              "granularity": 3
            }
          ],
          "motion": false,
          "length": 324,
          "dbId": 8181,
          "imageLocation": "",
          "preview": false,
          "totalTime": 10.841095978552278,
          "motionValue": null,
          "initTime": 1.6730086386654752,
          "confidenceScore": 0,
          "eligible": true,
          "logoId": null,
          "initFrameNew": null,
          "endFrameNew": null
        }
      }
    ],
    "labels": [
      {
        "id": 31572,
        "name": "hobbies & interest",
        "score": 1,
        "granularity": 1
      },
      {
        "id": 31573,
        "name": "text",
        "score": 0.4743947,
        "granularity": 3
      },
      {
        "id": 31574,
        "name": "leisure",
        "score": 0.47177458,
        "granularity": 3
      },
      {
        "id": 31575,
        "name": "logo",
        "score": 0.4508584,
        "granularity": 3
      },
      {
        "id": 31576,
        "name": "swimming pool",
        "score": 0.414691925,
        "granularity": 3
      },
      {
        "id": 31577,
        "name": "font",
        "score": 0.4100479,
        "granularity": 3
      },
      {
        "id": 31578,
        "name": "product",
        "score": 0.37484885,
        "granularity": 3
      },
      {
        "id": 31579,
        "name": "physical fitness",
        "score": 0.3475046,
        "granularity": 3
      },
      {
        "id": 31580,
        "name": "vacation",
        "score": 0.34696575,
        "granularity": 3
      },
      {
        "id": 31581,
        "name": "advertising",
        "score": 0.3113372,
        "granularity": 3
      }
    ],
    "videoMonetizationScore": 1
  }
}
curl -x GET api.uruvideo.com/cv_backend/api/video_upload/{id}/video
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/{id}/video'
headers = {"Authorization":"Bearer <your token>"}
r = requests.get(uruurl)
if(r.status_code == 500):
            print"Something went wrong with your video request."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

Uru will also tag individual scenes, based on the scene break information it finds. To access the tags for each scene, after the video is processed, make a request to the URL below:

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/{id}/video

Authentication: API TOKEN (OAuth 2)

Request Type: GET

Request Body: NONE

Response

The Individual Scenes Tags analysis is divided into two parts.

  1. Response Body

The response body is the main element of your response and contains the data relevant for the whole video.

Response Field Description
videoId Id of the current task
videoUrl Unique video url
percentage What percentage of the current task is done
videoName Name of the whole video
sceneUrls Internal Id of the scene
  1. Labels

The Labels object has the information about a certain section of the video that composes a scene.

Response Field Description
Id Internal Id of the scene
name Description of scene
score Label accuracy score calculated by Uru for the Scene or whole Video
granularity granularity object containing the score level of detail within the Scene or whole video

Update Video Tags Endpoint

//The response will be a Video entity, with the updated tags, inside their respective Label Entity, such as the example below.

{
  "error": null,
  "responseBody": {
    "username": "brunno",
    "videoId": "1510",
    "videoUrl": "http://s3.amazonaws.com/brohan/brunno/484d68d3-da32-4adb-a6b3-473a12aba69f/video_analysis_pending.mp4",
    "totalTime": 12.514104617217754,
    "percentage": 100,
    "videoName": "yogashort.mp4.mp4",
    "status": "UNDER_TAG",
    "sceneUrls": [
      {
        "id": 8180,
        "url": "http://url/scene_0/clean.jpg",
        "scene": {
          "initFrame": 0,
          "surfacesList": [],
          "label": [
            {
              "id": 31582,
              "name": "text",
              "score": 0.4743947,
              "granularity": 3
            },
            {
              "id": 31583,
              "name": "logo",
              "score": 0.4508584,
              "granularity": 3
            },
            {
              "id": 31584,
              "name": "font",
              "score": 0.4100479,
              "granularity": 3
            },
            {
              "id": 31585,
              "name": "product",
              "score": 0.37484885,
              "granularity": 3
            },
            {
              "id": 31586,
              "name": "advertising",
              "score": 0.3113372,
              "granularity": 3
            }
          ],
          "motion": false,
          "length": 50,
          "dbId": 8180,
          "imageLocation": "",
          "preview": false,
          "totalTime": 1.6730086386654752,
          "motionValue": null,
          "initTime": 0,
          "confidenceScore": 0,
          "eligible": true,
          "file": null,
          "warp": false,
          "blend": true,
          "shadow": true,
          "facebookSafe": false,
          "logoId": null,
          "initFrameNew": null,
          "endFrameNew": null
        }
      },
      {
        "id": 8181,
        "url": "http://url/scene_1/clean.jpg",
        "scene": {
          "initFrame": 50,
          "surfacesList": [],
          "label": [
            {
              "id": 31587,
              "name": "leisure",
              "score": 0.47177458,
              "granularity": 3
            },
            {
              "id": 31588,
              "name": "swimming pool",
              "score": 0.414691925,
              "granularity": 3
            },
            {
              "id": 31589,
              "name": "physical fitness",
              "score": 0.3475046,
              "granularity": 3
            },
            {
              "id": 31590,
              "name": "vacation",
              "score": 0.34696575,
              "granularity": 3
            },
            {
              "id": 31591,
              "name": "sports",
              "score": 0.2732957,
              "granularity": 3
            }
          ],
          "motion": false,
          "length": 324,
          "dbId": 8181,
          "imageLocation": "",
          "preview": false,
          "totalTime": 10.841095978552278,
          "motionValue": null,
          "initTime": 1.6730086386654752,
          "confidenceScore": 0,
          "eligible": true,
          "logoId": null,
          "initFrameNew": null,
          "endFrameNew": null
        }
      }
    ],
    "labels": [
      {
        "id": 31572,
        "name": "hobbies & interest",
        "score": 1,
        "granularity": 1
      },
      {
        "id": 31573,
        "name": "text",
        "score": 0.4743947,
        "granularity": 3
      },
      {
        "id": 31574,
        "name": "leisure",
        "score": 0.47177458,
        "granularity": 3
      },
      {
        "id": 31575,
        "name": "logo",
        "score": 0.4508584,
        "granularity": 3
      },
      {
        "id": 31576,
        "name": "swimming pool",
        "score": 0.414691925,
        "granularity": 3
      },
      {
        "id": 31577,
        "name": "font",
        "score": 0.4100479,
        "granularity": 3
      },
      {
        "id": 31578,
        "name": "product",
        "score": 0.37484885,
        "granularity": 3
      },
      {
        "id": 31579,
        "name": "physical fitness",
        "score": 0.3475046,
        "granularity": 3
      },
      {
        "id": 31580,
        "name": "vacation",
        "score": 0.34696575,
        "granularity": 3
      },
      {
        "id": 31581,
        "name": "advertising",
        "score": 0.3113372,
        "granularity": 3
      }
    ],
    "videoMonetizationScore": 1
  }
}
curl -x POST 
-d "{\"labels\": \r\n        \"name\": \"hobbies & interest\",\r\n}" api.uruvideo.com/cv_backend/api/video_upload/{id}/video/tag
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/{id}/video/tag'
headers = {"Authorization":"Bearer <your token>", "Content-Type": "application/json"}
data = "{\"labels\": \r\n        \"name\": \"hobbies & interest\",\r\n}"
r = requests.post(uruurl, data, headers=headers)
if(r.status_code == 500):
            print"Something went wrong with your video request."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

This call is an optional one that serves as a feedback loop to our algorithm. By providing a list of updated tags (removing or adding tags that are of your interest), Uru will start learning how to predict tags that are relevant for your particular user profile. This request is as follows:

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/{id}/video/tag

Request Type: POST(JSON)

Request Body: A JSON with the updated list of tags

Authentication: API TOKEN (OAuth2)

Product Listings API

This API flow enables you to recognize what is inside a video and then use that knowledge to fetch relevant product listings. It is powered by our proprietary AI that automatically understands the images and language inside the video, sifts through that data to find the objects and themes that will lead to the most lucrative product listings, then compiles those observations in metadata that you can use to serve high ROI product listings alongside your videos.

Usage flow

The usage flow for this API is quite simple: Step 1 is an offline process where an upload of the raw media file is made to Uru. Uru will then go inside the video and generate the structured data needed to fetch the product listings in Step 2. Step 2 can be performed both through an API call or through or Javascript client. Given an unique identifier of the video, a call to Uru can request the metadata needed to fetch the product listings from an affiliate network OR our Javascript client can be used to automatically fetch those on the fly.

Media File Upload Endpoint

This API allows the upload of a video file to Uru. Currently, .mp4 and .avi file formats are supported.

//The response will be a video upload entity with the id needed for subsequent request:

{
    "error": null,
    "responseBody": {
        "id": 1345312511,
        "externalId": null,
        "percentage": 10,
        "currentStatus": "UNDER_ANALYSIS",
        "finalUrl": "",
        "message": "Ecommerce analysis",
        "thumbnail":"<thumbnailUrl>",
        "name": "<Name of the video>",
        "createdDate": "2017-07-16 15:38:26",
        "totalTime": 12.543333,
        "labels": null
    }
}
curl -XPOST api.uruvideo.com/cv_backend/api/video_upload/ecommerce
-H "Authorization: Bearer <your token>" 
-F "file=@<location of your file>"
import requests
uruurl = 'http://api.uruvideo.com/cv_backend/api/video_upload/ecommerce'
headers = {"Authorization":"Bearer <your token>"}
files = {'file':open("<your video file path>","rb") }
r = requests.post(uruurl,files=files,headers=headers)
if(r.status_code == 429):
            print "Rate limit reached! Try again later after you finish processing your other pending videos"
elif r.status_code != 200:
            print r.text
else:
            print r.json()["responseBody"]

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/ecommerce

Request Type: POST

Request Parameters: Multipart request with the media file as attribute:

Parameter name Description
file Media file to be analyzed
(Optional) externalId Use the parameter passed here as the main identifer inside Uru

Fetch Listing Metadata Endpoint

//The response will be the metadata needed for fetching the product listings


{
  “error”: null,
  “responseBody”: {
    “scenes”: [
      {
        “sceneId”: 2310,
        “initTime”: 0,
        “length”: 10.36,
        “ecommerceAnalysis”: {
          “affiliates”: [
            {
              “id”: “Amazon”,
              “categories”: [
                {
                  “id”: 16310211,
                  “name”: “Grocery & Gourmet Food”
                },
                {
                  “id”: 1063498,
                  “name”: “Home & Kitchen”
                },
                {
                  “id”: 493964,
                  “name”: “Electronics”
                }
              ],
              “keywords”: [
                {
                  “product”: “pan”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “apron”,
                  “productId”: 0
                },
                {
                  “product”: “pot”,
                  “productId”: 0
                },
                {
                  “product”: “orange”,
                  “productId”: 0
                }
              ]
            },
            {
              “id”: “eBay”,
              “categories”: [
                {
                  “id”: 1144,
                  “name”: “Food and Wine”
                },
                {
                  “id”: 69,
                  “name”: “Kitchen”
                },
                {
                  “id”: 96318,
                  “name”: “Kitchen Electrics Accessories”
                }
              ],
              “keywords”: [
                {
                  “product”: “pan”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “apron”,
                  “productId”: 0
                },
                {
                  “product”: “pot”,
                  “productId”: 0
                },
                {
                  “product”: “orange”,
                  “productId”: 0
                }
              ]
            }
          ]
        }
      },
      {
        “sceneId”: 2311,
        “initTime”: 10.37,
        “length”: 19,
        “ecommerceAnalysis”: {
          “affiliates”: [
            {
              “id”: “Amazon”,
              “categories”: [
                {
                  “id”: 1063498,
                  “name”: “Home & Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “pan”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “pot”,
                  “productId”: 0
                }
              ]
            },
            {
              “id”: “eBay”,
              “categories”: [
                {
                  “id”: 69,
                  “name”: “Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “pan”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “pot”,
                  “productId”: 0
                }
              ]
            }
          ]
        }
      },
      {
        “sceneId”: 2312,
        “initTime”: 19.38,
        “length”: 10,
        “ecommerceAnalysis”: {
          “affiliates”: [
            {
              “id”: “Amazon”,
              “categories”: [
                {
                  “id”: 1063498,
                  “name”: “Home & Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “apron”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “kitchen rack”,
                  “productId”: 0
                },
                {
                  “product”: “kitchen decoration”,
                  “productId”: 0
                }
              ]
            },
            {
              “id”: “eBay”,
              “categories”: [
                {
                  “id”: 69,
                  “name”: “Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “apron”,
                  “productId”: 0
                },
                {
                  “product”: “wooden spoon”,
                  “productId”: 0
                },
                {
                  “product”: “kitchen rack”,
                  “productId”: 0
                },
                {
                  “product”: “kitchen decoration”,
                  “productId”: 0
                }
              ]
            }
          ]
        }
      },
      {
        “sceneId”: 2313,
        “initTime”: 29.39,
        “length”: 18.16,
        “ecommerceAnalysis”: {
          “affiliates”: [
            {
              “id”: “Amazon”,
              “categories”: [
                {
                  “id”: 16310211,
                  “name”: “Grocery & Gourmet Food”
                },
                {
                  “id”: 1063498,
                  “name”: “Home & Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “pasta”,
                  “productId”: 0
                },
                {
                  “product”: “bowl”,
                  “productId”: 0
                },
                {
                  “product”: “cutlery”,
                  “productId”: 0
                }
              ]
            },
            {
              “id”: “eBay”,
              “categories”: [
                {
                  “id”: 1144,
                  “name”: “Food and Wine”
                },
                {
                  “id”: 69,
                  “name”: “Kitchen”
                }
              ],
              “keywords”: [
                {
                  “product”: “pasta”,
                  “productId”: 0
                },
                {
                  “product”: “bowl”,
                  “productId”: 0
                },
                {
                  “product”: “cutlery”,
                  “productId”: 0
                }
              ]
            }
          ]
        }
      }
    ]
  }
}
curl -x GET api.uruvideo.com/cv_backend/api/video_upload/ecommerce/{id}
-H "Authorization: Bearer <your token>"
import requests
uruurl = 'api.uruvideo.com/cv_backend/api/video_upload/ecommerce/{id}'
headers = {"Authorization":"Bearer <your token>"}
r = requests.get(uruurl, headers=headers)
if(r.status_code == 401):
            print"Your token is invalid. Please re-authenticate or check your username."
elif r.satus_code != 200:
            print r.text:
else:
            print r.json()["responseBody"]

This is the API for fetching the metadata needed for product listings. Instead of the API, we strongly encourage this step to be used together with our Javascript plugin (put link of the JS plugin here).

API Endpoint: api.uruvideo.com/cv_backend/api/video_upload/ecommerce/{id}

Request Type: GET

Request Parameters: The following attributes are passed in the URL

Parameter name Description
id Id of the video upload

Response

Response Body

The response body is the main element of your response and contains the data relevant for the whole video.

Response Field Description
sceneId Internal Id of the scene
scenes.initTime Time (in seconds) the scene starts
scenes.length How much time (in seconds) the scene lasts
scenes.affiliates A list of recognized partner or subsidary groups to the organization
affiliates.id Name of specfic partners
affiliates.categories A group name that best categorizes the items found within the video
categories.name Description of scene
keywords This will output if any unique tags for the given scene
product The specific name of the item recongized by our system
productId A unique number that identifies the item in the video

Errors

These are the potential error codes and their description inside the Uru platform:

Error Code Description
429 You have hit your limit of requests in parallel. By default, Uru allows 3 videos to be processed in parallel. For increasing your limit, please contact brunno@uruvideo.com
401 Your token is invalid. Please re-authenticate or check your username
404 The API endpoint you tried to access does not exists.
500 Something went wrong with your video request.