Magnite Streaming — Public API Guide

This is the Magnite CTV Platform Public API.

This is API version 1.

The Seller Platform Public API is a RESTful API supporting primarily JSON entity serialization, with notable exceptions.

The API is organized into three main sections - a Authentication section, an Inventory Management section and a Query/Reporting section.

This guide will provide information about each of the API sections, but will begin by describing API Patterns used across the API.

Other documentation available includes

API Patterns

Before describing the details of the API, it is worthwhile to understand the overall style of the API.

The API strives to require the minimum amount of information necessary to complete an operation and to return an appropriate view of the data for the type of operation performed. To that end, many operations accept partial entities and conversely return only partial entities. Specific details are as follows.

Create Operation Patterns

Requests

The API uses the HTTP Method POST for entity creation.

The API accepts partial entities during creation. Not all entity fields must be present in order the operation to be successful. In general, only required fields are necessary. During creation, any field that is not present assumes a default value.

As an example, the Ad Unit entity includes over 20 different fields, but they need not all be part of the creation operation. Only required fields are necessary, which pares down the request to the following:

{
    "name" : "My Ad Unit",
    "supply" : { 
        "id" : 1234
     },
     "status" : {
        "id" : 1
    },
    "isCoppa" : true,
    "hasPrivacyPolicy" : true
    "mimes" : [ 
        "video/flash"
    ]
}

This example illustrates a second pattern in the API. In general, when you need to include an entity within another entity, only the unique identifier is required for the inner entity. In the example above both supply and status are inner entities.

Responses

The API uses HTTP Status Code 201 (Created) to indicate a successful creation. The API always returns the entire entity upon completion of the create operation.

Update Operation Patterns

Requests

The API uses the HTTP Method PUT for entity update.

Similar to creation, the update operation also can accept partial entities for modification. Any field that is not present will remain the same after the operation completes.

Given the above Ad Unit, to update only the description field, a request with the following will update only description, and leave all other fields unchanged.

{
    "description" : "I like monkeys."
}

And in addition to that, some fields may be cleared (or set to null as the default), by passing in null as the field value. To continue from the example, can change the name and clear the description with the following

{
    "name" : "My Monkey Unit",
    "description" : null
}

Responses

The API uses the HTTP Status Code 200 (Ok) to indicate a successful update. The API always returns the entire entity upon completion of the update operation.

Retrieval Operation Patterns

There are two different types of retrieval operations, those that return a single entity, those that return a collection of entities. These both return different view of the data.

Requests

The API uses the HTTP Method GET for retrieval requests.

Entity Responses

When executing a retrieval operation that returns a single value, in general the API responds with a view of all of the fields in the entity, but with limited view of certain child/inner entities.

The following example illustrates how this works. The data returned is for a supply entity. Notice that even though brand, publisher, and seat all contain fields like description and lastUpdated for example, those are excluded from the view of the supply entity.

{
  "creationDate": "2014-06-04T04:49:27.000+0000",
  "updateDate": "2014-06-04T04:49:27.000+0000",
  "id": 2000,
  "name": "My Monkey Game",
  "description": "Play around and learn about Monkeys. I like Monkeys.",
  "code": "q4tty",
  "domain": "monkeysforme.com",
  "paidType": null,
  "storeUrl": null,
  "bundleIdIsOverride": null,
  "bundleId": null,
  "videoQuality": null,
  "keys": [],
  "adParams": [],
  "keywords": [],
  "allowVastWrappers": true,
  "supplyDomainIsFallback": true,
  "type": {
    "id": 2,
    "name": "Site"
  },
  "brand": {
    "id": 3000,
    "name": "My Monkey (TM)",
    "code": "zjq4m",
    "publisher": {
      "id": 4000,
      "name": "Monkey Time, Inc",
      "code": "mnkye"
      "seat": {
        "id": 5000,
        "name": "Monkey Media, LLC",
        "code": "frykr"
      }
    }
  }
}

The API uses HTTP Status Code 200 (Ok) when returning entities.

Collection Responses

While single valued responses are meant to retrieve fine grained details about entities, responses returning collections of entities are typically used iterate through lists of things. The API attempts to minimize the amount of data returned to a smaller view targeted towards entity identification. This typically means only unique identifiers, primary naming fields and in some cases, direct ancestry.

While listing Ad Units, for example, the following is returned. Notice there are very few of the 20 or so Ad Unit fields returned, and even though the ancestry is returned, the ancestor fields are kept to a minimum as well.

[
  {
    "id": 1000,
    "name": "My Monkey Unit",
    "code": "40404",
    "type": {
      "id": 2,
      "name": "Mid-roll"
    },
    "status": {
      "id": 1,
      "name": "Active"
    },
    "linearity": {
      "id": 1,
      "name": "Linear/In-stream"
    },
    "adUnitFormat": {
      "id": 1,
      "name": "VAST"
    },
    "supply": {
      "id": 2000,
      "name": "My Monkey Game",
      "code": "q4tty",
      "brand": {
        "id": 3000,
        "name": "My Monkey (TM)",
        "code": "zjq4m",
        "publisher": {
          "id": 4000,
          "name": "Monkey Time, Inc",
          "code": "mnkye",
          "seat": {
            "id": 5000,
            "name": "Monkey Media, LLC",
            "code": "frykr"
          }
        }
      }
    }
  }
]

The API uses HTTP Status Code 200 (Ok) when returning entity collections.

Errors

The API attempts to standardize a single response payload on any error for any operation.

The API will return a different HTTP Status Code depending on the error. And the payload of the response will be a simple JSON object containing further details of the error

{
  "type" : "error",
  "errorCode" : "invalid-credentials",
  "errorDescription" : "The supplied credentials are not valid.",
  "errors" : null
} 

Authentication

The API uses custom cookie based session management. A session is established using a access-key/secret-key based authentication operation.

Establishing a Session

Authentication is performed by providing your access-key/secret-key pair to the /sessions resource. The access-key/secret-key pair is bound to your Console user account. Once you establish a session you are effectively logged in as your Console user.

Upon successful authentication, the resource returns a session entity as well as setting an ApiSession cookie. The ApiSession cookie must be included in subsequent API operations.

The value of the ApiSession can be retrieved either from the cookie itself, or via the returned entity. Issuing the login request. You will notice the ApiSession header value and the sessionCode JSON value are the same.

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
    "accessKey": "tv-MNdiN3IG1chX-jm",
    "secretKey": "MKmxH7scxxKACcs3BjZd"
}' 'https://api.tremorhub.com/v1/resources/sessions'

Will return the following headers and payload

< HTTP/1.1 201 Created
< Date: Fri, 22 Apr 2016 13:39:08 GMT
< Set-Cookie: VhfpSession=4e7a8e0c-018d-4184-a780-7b8d7d7683fe;Version=1;Path=/
< Content-Type: application/json
< Transfer-Encoding: chunked
< 
{
  "id" : 415284,
  "sessionCode" : "4e7a8e0c-018d-4184-a780-7b8d7d7683fe",
  "sessionStartTime" : "2016-04-22T13:39:08.237+0000",
  "lastValidated" : "2016-04-22T13:39:08.237+0000",
  "lastLogin" : "2016-03-17T00:37:15.000+0000",
  "user" : {
    "creationDate" : "2014-06-11T01:22:55.000+0000",
    "id" : 6,
    "emailAddress" : "cgeorge@magnite.com",
    "firstName" : "Curious",
    "lastName" : "George",
    "countryCode" : "US",
    "timezoneCode" : "America/Los_Angeles",
    "currencyCode" : "USD",
    "localeCode" : "en_US",
    "company" : "Monkey Media, LLC",
    "name" : "Curious George"
  }
}

Maintaining a Session

Sessions have an inactivity timeout. When a request is made after a session has timed out, the API send a response with HTTP Status Code 419 (Authentication Timeout) to indicate the condition. The client will need to authenticate again in order to make additional requests.

Completing a Session

Once you have completed all the updates and changes you would like to make with the API, you should terminate your session. This is accomplished by issuing a DELETE to the /sessions resource including the sessionCode as a path parameter.

Once you have terminated your session, additional requests will be as an unauthenticated user.

See the Sessions and Users groups for the resource definitions.

Inventory Hierarchy

This section of the API allows you to manage your inventory hierarchy. The API allows you to create, update and delete entities within your hierarchy.

The Seller Platform Inventory Hierarchy is organized into the following structure

  • Seat - The root of the hierarchy which all of your inventory is managed
    • Publisher - The publisher offers content, usually through multiple websites or mobile application publications
      • Brand - A brand is a published product, such as a newspaper, a web site, or a magazine, represented by a publisher
        • Supply - Supply refers to the specific ad impression inventory made available for bidding by a publisher
          • Ad Unit - An Ad Unit is a space that is available for rendering an ad, typically for a particular ad format

All these inventory entities have their own resources for the basic CRUD operations.

Its worth noting that currently when creating a entity, you are required to include its parent in the entity you are creating, as well as any required fields. Optional fields, as described earlier, need not be in the JSON submitted in the create operation.

See the Seats, Publishers, Brands, Supply and Ad Units groups for the resource definitions.

Query/Reporting

This Query API allows you to define and execute custom reports against the Seller Platform data warehouse.

Queries are executed asynchronously. When a query is launched, a ticket is returned providing an execution code representing the query. The execution code is then used to poll the status of the query until completion. Upon completion, the code is then used to retrieve results.

The Seller Platform data warehouse organized into multiple data-sets, or query sources, for different reporting purposes. The primary query source is the Publisher Ad Stats query source, which provides detailed metrics on the performance of your Inventory/Supply.

Queries are executed against a specific query source. A query source is a set of data that available for querying. The data is categorized as dimensions and metrics, explained in the next section.

A Query is configured with a Query Definition which is then passed to the API for execution.

Query Source Details

The API provides resources to discover the query sources available and the dimensions and metrics within them.

Dimensions are things that are known about your supply, and the context of the ad request. For example your entire inventory hierarchy is different dimensions, as well as things like the geographical location, the platform, the O/S and so forth.

Metrics, on the other hand, are summarized, aggregated data for your dimensions. They include things like requests, fills, impressions and their rates, as well as revenue numbers.

Query Definition Details

The query definition is how you provide the details of what you are interested reporting against. The Query definition includes the six following sections

  • Source - the query source to execute the query against
  • Fields - the dimensions and metrics you want returned in the report
  • Filters - the dimensions you want to limit the results to, for example, a specific publisher or ad unit.
  • Constraints - the metrics you want to limit the results to, for example, you may only want ad units with a revenue over $100.
  • Order - optionally specify the sort order of the fields in the report
  • Range - The time range to aggregate data for. Both pre-defined ranges like today, and lastWeek and custom ranges are supported.

The query definition is supplied to the API as a JSON structure. For example

{
    "source": "adstats-publisher",
    "fields": [
        "day", "adUnit", "requests", "impressions", "useRate", "netRevenue", "grossRevenue"
    ],
    "filters": [
        {
            "field": "publisher",
            "negate": "false",
            "value": [ 1234 ]
        }
    ],
    "constraints": [
        {
            "field": "requests",
            "operator": ">",
            "value": 0
        }
    ],
    "orderings": [
        {
            "direction": "asc",
            "field": "day"
        },
        {
            "direction": "asc",
            "field": "adUnit"
        }
    ],
    "range": {
        "range": "today",
        "timeZone": "UTC"
      }       
}

Query Source

The query source in the definition is specified with the source field in the JSON, where the value comes from the name field retrieved from the /query/sources operation.

Query Fields

Query fields form the columns that are returned in the results.

Query fields are specified with the fields field in the definition. This is an array of field ids where the values from are id values that come from the /query/sources/{sourceId}/dimensions and /query/sources/{sourceId}/metrics resources.

Query Filters

Filters restrict the set of data that appears in the results.

Filters are specified with the fields field in the definition. This is an array of objects that contain three fields, field, value, and negate. The field value comes from the id values retrieved by the /query/sources/{sourceId}/dimensions resource. Filters can only contain dimensions.

The value can be a collection of items. The values that can be in the collection depend on the dimension, but are typically the unique ids of the entities you are filtering to.

The negate field is simply a true or false indicating whether the filter should include only those items listed - false, or exclude all the items listed true.

Query Constraints

Constraints restrict the values of the metrics that appear in the results.

Constraints are specified with the constraints field in the definition. This is an array of objects that contain three fields, field, operator, and value. The field value comes from the id values retrieved by the /query/sources/{sourceId}/metrics resources. Constraints can only contain metrics.

The operator field is the logical operator to select for filtering (<, <=, =, >=, >).

The value field is the numeric operand in the the comparison.

Query Order

The sort order of the results can be configured in the definition. Sorting by dimensions and metrics is allowed.

Order is specified with the orderings field in the definition. This is an array of objects that contain two fields, field, and direction. The field value comes from the id values that are defined in the dimensions and metrics for the query source.

The direction field is one of (asc, desc).

Query Range

Queries are generally bounded by a time range. The API supports both predefined time ranges and custom time ranges. The API allows a maximum time span of 45 days in a time range.

Ranges are specified in the range field in the query definition.

Predefined time ranges are specified with the range within the range fields. Allowed values include (today, yesterday, thisWeek, lastWeek, thisMonth, lastMonth, lastSevenDays, lastThirtyDays). Week ranges start on Monday.

{
    "fields" : [ "adUnit", "impressions" ],
    "range" : {
        "range" : "lastWeek"
    }
}

Custom time ranges use the fromDate and toDate fields in the range. These dates must be formatted as HHHH-MM-SS.

{
    "fields" : [ "adUnit", "impressions" ].
    "range" : {
        "fromDate" : "2016-01-01",
        "toDate" : "2016-01-08"
    }
}

Query Results

Results can be retrieved in JSON, CSV and Excel formats. The format of the results can be specified at the time you retrieve the results with the /queries/{executionCode}/results resource. This is done by appending the query parameter fmt with one of (json, csv, xlsx).

JSON Results

When requesting query results formatted as JSON, the returned object is a list that contains maps of name/value pairs. The name is the dimension or metric id, and the value depends on the type of field. For dimensions, generally its the dimension name, and for metrics its generally the aggregated value.

For JSON, each dimension in the results generally also has a second name/value pair added to the results, where the name is the dimension name with IdLink appended to it, and the value is the unique identifier for the dimension.

[
    {
        "adUnit": "My Monkey Unit",
        "adUnitIdLink": 1000,
        "day": "2016-04-25",
        "fillRate": 0.79,
        "hour": 14,
        "impressions": 267,
        "requests": 2386,
        "useRate": 0.142
    },
    {
        "adUnit": "My Monkey Unit",
        "adUnitIdLink": 1000,
        "day": "2016-04-25",
        "fillRate": 0.904,
        "hour": 10,
        "impressions": 109,
        "requests": 415,
        "useRate": 0.291
    },
    {
        "adUnit": "My Monkey Unit",
        "adUnitIdLink": 1000,
        "day": "2016-04-25",
        "fillRate": 0.79,
        "hour": 1,
        "impressions": 273,
        "requests": 877,
        "useRate": 0.394
    },
    {
        "adUnit": "My Monkey Unit",
        "adUnitIdLink": 1000,
        "day": "2016-04-25",
        "fillRate": 0.656,
        "hour": 3,
        "impressions": 445,
        "requests": 1714,
        "useRate": 0.396
    }
]

CSV Results

Results formatted as CSV should have been customized to work well with Excel, but should work well for other uses as well.

The results consist of a header row, followed by multiple rows of data. The header row contains the readable name for each of the desired dimensions and metrics.

Excel Results

Data formatted as Excel is similar to CSV, with a few additions.

Before the header and results, there are a few lines that provide a summary of the query definition. This includes query filters, constraints, and orderings.

Then comes the header row, followed by multiple rows of data. The header row contains the readable name for each of the desired dimensions and metrics. There is some formatting applied to the header row to make it stand out.

Query Execution

The API provides asynchronous query execution. To execute a query you perform the following operations:

  1. Initiate the query, with the /queries operation. The response will provide, among other information, a query execution id.
  2. Monitor the status of the query with the /queries/{executionCode} operation. Continue monitoring until returned status is no longer RUNNING.
  3. Retrieve the results using the /queries/{executionCode}/results operation. Optionally specifying the output format with the fmt query parameter.

In step 2, once the query has left the RUNNING state, there is no need to continue polling. Either the query has COMPLETED or ERRORED and you will need to take the appropriate action based on the final status.

Query Cancellation

The API allows you to cancel queries. This can be useful to short circuit complete execution of queries. Queries can be cancelled by issuing a DELETE to the /queries/{executionCode} API, which will attempt to cancel the specified query.

Query Concurrency

The API limits you to running a single query at a time. Attempting to run a second query concurrently will result in an error response with HTTP Status Code 412 (Precondition Failed).