Developer API

Bidstream Optimizer API Guide

The Authenticated Digital Bidstream Optimizer is driven by a RESTful API. The following document explains the basic concepts behind Optimizer, and how to use the Optimizer API.

Your Account

Your account with Authenticated is needed to access any part of the Authenticated API. The most important thing to know about your account is how to get a token. A user must first log in to access the API and obtain a token to be used for all subsequent requests. The Optimizer API uses the JSON web tokens (JWT) methodology.

Obtaining JWT token:

To obtain a JSON web token, you must send your username and password as follows:

curl -v -X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{ "email": "<email>", "password": "<password>" }' \
'https://optimizer.authenticated.digital/api/login'

Note: Change <email> and <password> above with the email account and password associated with your Optimizer user account.

The response will look similar to this:

HTTP/1.1 200 OK
authorization: Bearer eyJhbGciOiABC6IkpXVCJ9.eyJhdWQiOiJVc2VyOjEiLCJleHAiOjE0NzDEFXNzIjoiUnRiUHJveHlXZWIiLCJqdGkimqIlMmEtOGIzNi1lNmIzNjYxZmY3ZjciLCJwZW0iOnt9LCJzdWIKyOjEiLCJ0eXAiOiJ0b2tlbiJ9.vIUenWRk9Zu9weBLhfbvcc9pgAXKsw-8ltdkNclfpDJiTR_DvaunI_ipEI5zx4hTDCDpeVT5olFQ
cache-control: max-age=0, private, must-revalidate
content-type: application/json; charset=utf-8
date: Fri, 09 Sep 2016 13:56:02 GMT
server: Cowboy
x-expires: 1476021363
x-request-id: b2avdie34gqnls4ubvahab18tg474
Content-Length: 323
Connection: keep-alive

* Connection #0 to host optimizer.authenticated.digital left intact
{"data":{"jwt":"eyJhbGciOiABC6IkpXVCJ9.eyJhdWQiOiJVc2VyOjEiLCJleHAiOjE0NzDEFXNzIjoiUnRiUHJveHlXZWIiLCJqdGkimqIlMmEtOGIzNi1lNmIzNjYxZmY3ZjciLCJwZW0iOnt9LCJzdWIKyOjEiLCJ0eXAiOiJ0b2tlbiJ9.vIUenWRk9Zu9weBLhfbvcc9pgAXKsw-8ltdkNclfpDJiTR_DvaunI_ipEI5zx4hTDCDpeVT5olFQ","exp":1476021363}}

Note the authorization header and the data/jwt node in the JSON contain the same string of characters. These characters are a token which will be used for all subsequent requests to the API. Copy this token down, and replace in the authorization header for all other requests, as follows:

curl 'https://optimizer.authenticated.digital/api/filters' \
-H 'Authorization: Bearer eyJhbGciOiABC6IkpXVCJ9.eyJhdWQiOiJVc2VyOjEiLCJleHAiOjE0NzDEFXNzIjoiUnRiUHJveHlXZWIiLCJqdGkimqIlMmEtOGIzNi1lNmIzNjYxZmY3ZjciLCJwZW0iOnt9LCJzdWIKyOjEiLCJ0eXAiOiJ0b2tlbiJ9.vIUenWRk9Zu9weBLhfbvcc9pgAXKsw-8ltdkNclfpDJiTR_DvaunI_ipEI5zx4hTDCDpeVT5olFQ

Remember to replace the above (non-working) token above with your token!

Bidstreams

Optimizer accepts inbound bidstreams from various suppliers, filters the bidstreams, and then passes the bid requests on to your bidder. The Authenticated streams endpoint refers to a bidstream from a supplier. Because suppliers can have more than one bidstream, they are grouped by a suppliers endpoint.

Streams

To view all of the streams that are configured for your account, use the streams endpoint:

curl 'https://optimizer.authenticated.digital/api/streams' \
-H 'Authorization: Bearer <enter your token here>'

You will get a JSON response similar to the following:

{  
   "data":[  
      {  
         "supplier":{  
            "name":"OpenX",
            "id":1
         },
         "seat_id":"123",
         "id":3,
         "endpoint_path":"/42eaaaaaaa4eeabeeeecc77836adde6/bids",
         "customer_endpoint":"http://bidder.customer.com/bids",
         "client_id":"42eaaaaaaa4eeabeeeecc77836adde6"
      },
      {  
         "supplier":{  
            "name":"OpenX",
            "id":1
         },
         "seat_id":"123",
         "id":4,
         "endpoint_path":"/42eaaabbbbdd444dde6/bids",
         "customer_endpoint":"http://bidder.customer.com/bids",
         "client_id":"42eaaabbbbdd444dde6"
      }
   ]
}

Here is a description of the fields in the streams endpoint:

FIELD TYPE DESCRIPTION
id integer The autogenerated internal ID for the stream
client_id string The unique ID of the bidstream that Optimizer will use to identify the customer/stream
supplier.name string The name of the SSP / Exchange / Publisher that provides a raw input bidstream
supplier.id integer Autogenerated ID for this supplier
seat_id string The seat ID that the bidder uses to identify their bids to a supplier bidstream
endpoint_path string The path of the URL for the Optimizer raw bidstream endpoint
customer_endpoint string The URL of the upstream bidder that Optimizer will pass filtered bids to

Note that streams are organized in hierarchical fashion by supplier. If you subscribe to multiple bidstreams more than one stream will share the same suppler (like the example above).

Suppliers

To get a list of suppliers, use the suppliers endpoint:

curl 'https://optimizer.authenticated.digital/api/suppliers' \
-H 'Authorization: Bearer <enter your token here>'

You will get a response similar to the following:

{
   "data":[
      {
         "name":"OpenX",
         "id":1
      },
      {
         "name":"Opera",
         "id":2
      }
   ]
}

Here is a description of the fields in the suppliers endpoint:

FIELD TYPE DESCRIPTION
id integer Autogenerated ID for this supplier
name string The name of the SSP / Exchange / Publisher that provides a raw input bidstream

Customer Settings

Customer settings can be viewed and updated. This includes a global qps as well as rules around how the customer will receive bids and wins.

Customer Definition

FIELD TYPE DESCRIPTION
id integer Autogenerated ID for the customer record
name string The customer name
slug string Human readable unique identifier for customer
qps integer Designated maximum qps
redirect_wins boolean If true, a 302 code with upstream win url is responsed on a win notice
inject_tag boolean If true, injects the authenticated digital tag in customer creative
keep_nurl boolean If true, keeps customer bidder nurl instead of proxying through optimizer

Usage

To get customer information curl 'https://optimizer.authenticated.digital/api/customer' \ -H 'Authorization: Bearer <enter your token here>'

Customer information can be updated for the following fields qps, redirect_wins, inject_tag, keep_nurl.

curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer <your jwt token>' -d '{ "customer": { "qps": 1000,"redirect_wins": false, "inject_tag": true, "keep_nurl": false }}' 'http://localhost:4000/api/customer'

Filters

A core feature of Optimizer is to use filters to tune the traffic that is sent to your bidder. By default, a filter will be added to all new accounts. Filters are highly configurable, and while it takes a bit of time to understand why they work the way they do, they are extremely powerful.

Filter Definition

A single filter is a simple set of instructions that control whether or not a bid request is blocked (e.g. a 204 HTTP response is sent back) or passed through to the upstream bidder. A filter takes the shape of a simple JSON object, like the following example:

{
    "id": 1,
    "field_type": "size",
    "operator": "equals",
    "list": ["300x250","320x100","320x50"],
    "filter_type": "white"
}

The filter attributes are defined below.

Filter Attributes

ATTRIBUTE DESCRIPTION TYPE VALUES NOTES
id The ID of the filter, which is auto-generated when the filter is created. When filters are chained together in hierarical fashion, this ID is used as the reference in the parent_filter_id field. integer
field_type The type of field. There are different field types, which generally represent a) bid request fields; b) enriched data from the fields (such as the recycled field from Authenticated); c) composites (and and or) which then chain filters together. string user, country, size, stream, supplier, authed, and, or More information about field types below
operator The operation to perform on the filter. For example, the equals operator checks to see if one of the values in the list is the same as the specified field. string lessthan, equals, greaterthan
list A JSON array list of values from which to apply the operator. array For list filters only
threshold The threshold score value for threshold filter types float For threshold filters only
filter_type The filter type. string white, black, boolean, threshold More information about filter types below
parent_filter_id The parent filter which connects this filter to its siblings integer Parent filter can only have filter_type of boolean

Field Type Descriptions

FIELD TYPE VALID FILTER TYPES DATA ELEMENT DESCRIPTION
country white, black bidrequest.device.geo.country Country where the visitor is located from the bid request - 2 char uppercase ISO code
user white, black bidrequest.user.id The ID of the visitor's device
stream white, black stream.id The Authenticated Digital ID of the bidstream
supplier white, black supplier.id The ID of the supplier from the bid request
size white, black bidrequest.imp.banner.[wxh] The size of the impression (e.g. 300x250)
authed threshold bidrequest.ext.authenticated.authed.score The score value of the authed model from Authenticated
and boolean Combines child filters (that have a parent_filter_id of this filter's ID) and evaluates using AND boolean logic.
or boolean Combines child filters (that have a parent_filter_id of this filter's ID) and evaluates using OR boolean logic.

Operator Descriptions

OPERATOR DESCRIPTION
lessthan A model's predicted score is less than the specified threshold
equals A field value is the same as an item in the list array
greaterthan A model's predicted score is greater than the specified threshold

Filter Type Descriptions

FILTER TYPE DESCRIPTION
white A white list - the field must exist in the list array
black A black list - field must not exist in the list array
threshold A threshold contains a prediction model score to filter quality and commercial traffic
boolean A filter that connects other filters together, and evaluates all filters according to boolean logic (e.g. AND, OR)

Examples

Creative Size Filter

The following filter passes through bids with creatives of the specified sizes (300x250, 320x100, 320x50):

{
    "id": 2,
    "field_type": "size",
    "operator": "equals",
    "list": ["300x250","320x100","320x50"],
    "filter_type": "white"
}

Bid Quality Filter

The following filter passes thorugh bids with a quality threshold of at least 0.5:

{
    "id": 3,
    "field_type": "authed",
    "operator": "greaterthan",
    "threshold": 0.5,
    "filter_type": "threshold"
}

Combining Filters

Filters can be combined, to contain more sophisticated and powerful logic. For example, the creative size filter and the quality filter above can be combined if you want to only show bid inventory with the three creative sizes with a quality threshold:

[{
    "id": 2,
    "field_type": "size",
    "operator": "equals",
    "list": ["300x250","320x100","320x50"],
    "filter_type": "white",
    "parent_id": 4
},
{
    "id": 3,
    "field_type": "authed",
    "operator": "greaterthan",
    "threshold": 0.5,
    "filter_type": "threshold",
    "parent_id": 4
},
{
    "id": 4,
    "field_type": "and",
    "filter_type": "boolean"
}]

Filter Hierarchy

Filters can continue to be constructed in a hierarchical fashion. For example, if you only want the combined filter above to run with UK traffic, and with the other traffic you want to run a high quality threshold:

First, update or create the top level filter which will be an "OR" filter, meaning that there are more than one scenarios that could be run:

[{
    "id": 1,
    "field_type": "or",
    "filter_type": "boolean"
}]

Next, use the filter criteria created in the "Combining Filters" section above and add the UK geotargeting filter:

[{
    "id": 2,
    "field_type": "size",
    "operator": "equals",
    "list": ["300x250","320x100","320x50"],
    "filter_type": "white",
    "parent_id": 4
},
{
    "id": 3,
    "field_type": "authed",
    "operator": "greaterthan",
    "threshold": 0.5,
    "filter_type": "threshold",
    "parent_id": 4
},
{
    "id": 4,
    "field_type": "and",
    "filter_type": "boolean",
    "parent_id": 1
},
{
    "id": 5,
    "field_type": "country",
    "operator": "equals",
    "list": ["UK"],
    "filter_type": "white",
    "parent_id": 4
}]

Note the parent IDs of the filters connect the AND filter, except for the AND filter itself, which is connected to the top-level OR filter.

At this point, you have configured a filter which has the following functionality in boolean logic:

IF ANY OF THE STATEMENTS IS TRUE:
   IF ALL OF THE STATMENTS IS TRUE:
      CREATIVE SIZE IS EITHER 300x250,320x100 OR 320x50
      QUALITY THRESHOLD IS AT LEAST 0.5
      COUNTRY IS UK

Finally, create the filter for the other traffic:

[{
    "id": 6,
    "field_type": "authed",
    "operator": "greaterthan",
    "threshold": 0.7,
    "filter_type": "threshold",
    "parent_id": 8
},
{
    "id": 7,
    "field_type": "country",
    "operator": "equals",
    "list": ["UK"],
    "filter_type": "black",
    "parent_id": 8
},
{
    "id": 8,
    "field_type": "and",
    "filter_type": "boolean",
    "parent_id": 1
}]

Now you have the filtering scheme you want! The boolean logic is now as follows:

IF ANY OF THE STATEMENTS IS TRUE:
   IF ALL OF THE STATMENTS IS TRUE:
      CREATIVE SIZE IS EITHER 300x250,320x100 OR 320x50
      QUALITY THRESHOLD IS AT LEAST 0.5
      COUNTRY IS UK
   IF ALL OF THE STATMENTS IS TRUE:
      QUALITY THRESHOLD IS AT LEAST 0.7
      COUNTRY IS NOT UK

Lists

In general, filters are set up and not changed often - sort of like firewall rules. However, the lists referenced by filters change often - sometimes multiple times per day. Bidstream Optimizer is engineered for this use case.

For example, if a bidder only wants to see a bid if it comes from a pool of device IDs that they have verified, they could update the list as follows:

To create a device ID filter:

curl -X POST -H 'Authorization: Bearer <enter your token here>' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{ "filter": { "operator": "equals","list": [4] }}' 'http://localhost:4000/api/filters'

A response would be as follows:

To update this filter:

curl -X PUT -H 'Authorization: Bearer <enter your token here>' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{ "filter": { "operator": "equals","list": [4] }}' 'http://localhost:4000/api/filters/36'

A successful response contains the tree based list of your filters

{
    "data": {
        "id": 24,
        "filters": [{
            "id": 27,
            "filters": [{
                "operator": "equals",
                "list": ["4", "5", "6"],
                "id": 29,
                "filter_type": "black",
                "field_type": "user"
            }, {
                "operator": "equals",
                "list": ["5x5"],
                "id": 30,
                "filter_type": "black",
                "field_type": "size"
            }],
            "filter_type": "boolean",
            "field_type": "or"
        }, {
            "operator": "equals",
            "list": ["1", "2", "3"],
            "id": 28,
            "filter_type": "black",
            "field_type": "user"
        }, {
            "id": 32,
            "filters": [{
                "id": 33,
                "filters": [{
                    "operator": "equals",
                    "list": "List too long to return: 5000000",
                    "id": 31,
                    "filter_type": "white",
                    "field_type": "user"
                }, {
                    "operator": "equals",
                    "list": [3],
                    "id": 35,
                    "filter_type": "white",
                    "field_type": "stream"
                }],
                "filter_type": "boolean",
                "field_type": "and"
            }, {
                "operator": "equals",
                "list": [3],
                "id": 36,
                "filter_type": "black",
                "field_type": "stream"
            }],
            "filter_type": "boolean",
            "field_type": "or"
        }],
        "filter_type": "boolean",
        "field_type": "and"
    }
}

Updating Filter:

This would update filter id 36 curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer <your jwt token>' -d '{ "filter": { "operator": "equals","list": [4] }}' 'http://localhost:4000/api/filters/36' A successful response will return the updated filter { "data": { "operator": "equals", "list": [ 3 ], "id": 36, "filter_type": "black", "field_type": "stream" } }

Field Types

Filter Examples

The following example is a filter that allows different users for different countries using or and and filters.

It also limits the second country set to just one size:

{
  "filter_type": "boolean",
  "field_type": "and",
  "filters": [{
          "filter_type": "boolean",
          "field_type": "and",
          "filters":[{
            "filter_type": "white",
            "field_type": "country",
            "operator": "equals",
            "list":["US","CA"]

          },
          {
            "filter_type": "white",
            "field_type": "user",
            "operator": "equals",
            "list":["user1","user2"]
          }
          ]
      },
      {
          "filter_type": "boolean",
          "field_type": "and",
          "filters":[{
            "filter_type": "white",
            "field_type": "country",
            "operator": "equals",
            "list":["GB","IE","DE"]

          },
          {
            "filter_type": "white",
            "field_type": "size",
            "operator": "equals",
            "list":["300x250"]
          },
                    {
            "filter_type": "white",
            "field_type": "user",
            "operator": "equals",
            "list":["user3","user4"]
          }
          ]
      }
      ],
      "filter_type": "boolean",
      "field_type": "or"
  }]
}

Here is how this would be created when no filters are set.

First get your existing filters there should only be one.

curl -H 'Authorization: Bearer <your jwt token> 'http://localhost:4000/api/filters'

Take the id of the topmost filter. Then create the or filter.

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer <your jwt token>' -d '{ "filter": { "filter_type": "boolean", "field_type": "or", "parent_filter_id": <parent_filter_id> }}' 'http://localhost:4000/api/filters'

The filter should return with the generated filter id.

The and filters can be added in bulk.

curl -X POST 'https://optimizer.authenticated.digital/api/filters' \
-d '{ "filters": [
   { "filter_type": "boolean", "field_type": "and", "parent_filter_id": 1 },
   { "filter_type": "boolean", "field_type": "and", "parent_filter_id": 1 },
   { "filter_type": "boolean", "field_type": "and", "parent_filter_id": 1 }
   ]}' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <your jwt token>'

The corresponding list filters can now be added in bulk as well

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer <your jwt token>' -d '{ "filters": [{"filter_type":"white","field_type":"country","operator":"equals","list":["US","CA"],"parent_filter_id":"<first_and_filter_id>"},{"filter_type":"white","field_type":"user","operator":"equals","list":["user1","user2"],"parent_filter_id":"<first_and_filter_id>"},{"filter_type":"white","field_type":"country","operator":"equals","list":["GB","IE","DE"],"parent_filter_id":"<second_and_filter_id>"},{"filter_type":"white","field_type":"size","operator":"equals","list":["300x250"],"parent_filter_id":"<second_and_filter_id>"},{"filter_type":"white","field_type":"user","operator":"equals","list":["user3","user4"],"parent_filter_id":"<second_and_filter_id>"}] }' 'http://localhost:4000/api/filters'