Integration

In-house mediation is not publicly available

In-house bidding with Audience Network is currently in Closed Beta and is not publicly available. We'll provide further updates if this changes.

As an alternative, you can access Audience Network Bidding through one of the mediation platforms we partner with.

There are two options:

Option 1: Use Bidding Kit 3 as client-side adapter

For more details, go to Bidding Kit 3

  • Bidding Kit 3 makes the HTTP request to Bidding Kit Server, which is hosted on the Publisher’s server.
  • BK3 exposes an API to runRemote auction. You'll need to pass the Bidding Kit Server URL and list of waterfall items. BK3 will collect all device signals and construct the HTTP request for BKS.
  • BK3 will respond to the client with the consolidated list of waterfall and bidder items.

Option 2: Call direct from publisher server

  • Does not require integration with BK3 on the client side.
  • You make the HTTP call directly to BKS from one of the your servers.
  • You need to construct the HTTP request on your server.
  • Fields like FB BidderToken or any other corresponding token that other bidders require must be passed in the HTTP request sent to BKS. For auth token, follow the instructions here.
  • The BKS response is consumed by the publisher server. You can use this response to ask for an ad in a prioritized list.

Endpoints

Auction Endpoint

Bidding Kit Server:

  1. Accepts auction request on this endpoint.
  2. Sends bid requests to individual bidders.
  3. Collects responses.
  4. Runs the auction.
  5. Sends notification to bidders.
  6. Merges waterfall (if any) with bidders. (If you're using BK3, waterfall entries are not passed).
  7. Responds with a consolidated list of bidders (and waterfall entries, if passed), sorted according to price.

Request

POST [https://{server_ip}:{port}/bks/auction](https://%7Bserver_ip%7D:{port}/bks/auction)
Body:{
    "bidder_data": {
        "facebook": {
            "id": "{auction_id}", 
            "imp": [{
                "id": "1",
                "tagid": "{placement_id}",
                "banner": { //This is an example for banner. Native and video will 
                            requests will have corresponding fields populated 
                    "h": 30,
                    "w": -1
                }
            }],
            "app": {
                "publisher": {
                    "id": "{app_id}"
                }
            },
            "device": {
                "lmt": 0
            },
            "regs": {
                "coppa": 0
            },
            "at": 1,
            "tmax": 1000, //Timeout for the auction

            "ext": {
                "platformid": "{app_id}",
                "sdk_version": "6.0.web"
            },
            "user": {
                "buyeruid": "{bidder_token}"
            }
        },
        "tapjoy": {
            "id": "{auction_id}",
            "imp": [{
                "id": "TapjoyAdImpression",
                "displaymanager": "facebook",
                "video": {
                    "ext": {
                        "rewarded": 0,
                        "isSkippable": 1
                    }
                }
            }],
            "app": {
                "bundle": "com.facebook.biddingkitsample",
                "ext": {
                    "sdk_key": "{sdk_key}",
                    "placement_name": "BiddingKitSampleApp",
                    "token": "{token}"
                }
            },
            "device": {
                "ifa": "{ifa}",
                "lmt": 0,
                "make": "Google",
                "model": "Android SDK built for x86",
                "os": "{os}",
                "osv": "{os_version}"
            },
            "regs": {
                "coppa": 0
            },
            "at": 1,
            "test": 1
        },
        "applovin": {
            "id": "{auction_id}",
            "imp": [{
                "id": "AppLovinAdImpression",
                "instl": 1,
                "banner": {
                    "h": 480,
                    "w": 320
                },
                "video": {
                    "h": 480,
                    "w": 320
                }
            }],
            "app": {
                "publisher": {
                    "id": "com.facebook.biddingkitsample"
                }
            },
            "device": {
                "lmt": 0
            },
            "regs": {
                "coppa": 0
            },
            "at": 1,
            "test": 1,
            "ext": {
                "platformid": "Android"
            },
            "user": {
                "buyeruid": "{buyeruid}"
            }
        },
        "chartboost": {
            "id":"{auction_id}",
            "imp":[ // This is an example of Interstitial request
                {
                "id":"Fb Ad Impression",
                "banner":{
                    "ext":{
                        "placementtype":"interstitial"
                    }
                },
                "video":{
                    "ext":{
                        "placementtype":"interstitial"
                    }
                },
                "displaymanager":"Chartboost-Android-SDK",
                "displaymanagerver":"8.0.1",
                "instl":1,
                "tagid":"SomeLineItem1"
                }
            ],
            "app":{
                "id":"907175713",
                "name":"BiddingKitSample",
                "bundle":"com.facebook.biddingkit",
                "publisher":{
                "id":"99999",
                "name":"Sample Company"
                }
            },
            "device":{
                "ua":"Dalvik\/2.1.0 (Linux; U; Android 8.0.0; Android SDK built for 
                                        x86 Build\/OSR1.170901.043)",
                "ifa":"IDFA"
            },
            "user":{
                "ext":{
                "consent":1
                }
            },
            "test":1,
            "at":1,
            "tmax":10000,
            "regs":{
                "coppa":0,
                "ext":{
                    "gdpr":0
                }
             }
        },
        "ironsource": {
            "id":"{auction_id}",
            "app":{
                "ext":{
                    "token":"{token}",
                    "instanceId":{instance_id},
                    "applicationKey":"{application_key}"
                },
                "bundle":"com.facebook.biddingkitsample"
            },
            "device": {
                "ip": "{device_ip}"
                "ua": "{browser_user_agent_string}"
            },
            "test":1,
            "imp":[
                {
                    "instl":0, // This is an example of Rewarded Video request
                    "id":"IronsourceAdImpression"
                }
            ]
        }
        "vungle":{
          "id":"{auction_id}",
          "imp":[
             {
               "id":"Vungle Ad Impression",
               "video":{
                  "mimes":[
                     "video/mp4"
                  ]
               },
               "displaymanager":"Vungle",
               "displaymanagerver":"5.0.0",
               "tagid":"{placement_id}",
               "ext":{
                  "vungle":{
                     "bid_token":"{token}"
                 }
              }
            }
           ],
           "app":{
              "id":"{app_id}",
              "bundle":"com.facebook.biddingkitsample",
              "publisher":{
                 "id":"{publisher_id}"
                }
            },
           "device":{
              "ua":"{browser_user_agent_string}",
              "ifa":"{ifa}",
              "lmt":0
            },
           "test":1,
           "at":1,
           "regs":{
              "coppa":0
            },
           "tmax":1000
}
},
    "waterfall_entries": [{"name": "google", "cpm": 1000}]
}
  • If using Bidding Kit 3 on the client side, the request will be created by BK3, so you do not need to use JSON.
  • If using Bidding Kit 3, waterfall_entries will not be passed to the server
  • Top level id should be same across all bidders. facebook.id = applovin.id = tapjoy.id = ironsource.id = chartboost.id = vungle.id

Response

{
    "auction_id": "{auction_id}", // id in the request
    "notification_data": "{notification_data}", // Will be echoed back in display 
                                                    notification api
    "bids": [
        {
            "name": "applovin",
            "price": 0.59792964573476004, // Dollars
            "cur": "USD",
            "is_bidder": true,
            "adunit_id": "",
            "sdk_rendering_data": {
                "bid_payload": "{bid_payload}"
            }
        },
        {
            "name": "facebook",
            "price": 7.1591147058191,
            "cur": "USD",
            "is_bidder": true,
            "adunit_id": "{placement_id}",
            "sdk_rendering_data": {
                "bid_payload": "{bid_payload}"
            },
            "ext":{
                "encrypted_cpm": "{encrypted_cpm}"
            }
        },
        {
            "name": "chartboost",
            "price": 99,
            "cur": "USD",
            "is_bidder": true,
            "adunit_id": "BiddingKitSampleApp",
            "sdk_rendering_data": {
                "bid_payload": "{bid_payload}"
            }
        },
        {
            "name": "tapjoy",
            "price": 99,
            "cur": "USD",
            "is_bidder": true,
            "adunit_id": "BiddingKitSampleApp",
            "sdk_rendering_data": {
                "bid_payload": "{bid_payload}"
            }
        },
        {
            "name": "ironsource",
            "price": 99,
            "cur": "USD",
            "is_bidder": true,
            "adunit_id": "{instance_id}",
            "sdk_rendering_data": {
                "bid_payload": "{bid_payload}"
            }
        },
        {
            "name":"vungle",
            "price":99,
            "cur":"USD",
            "is_bidder":true,
            "adunit_id":"",
            "sdk_rendering_data":{
            "bid_payload":"{bid_payload}"
            }
        },       
        {
            "name": "google",
            "price": 100,
            "cur": "USD",
            "is_bidder": false
        }
    ]
}

Notify Display Endpoint

Request

POST https://{server_ip}:{port}/bks/notifyDisplay
Body
{
    "auction_id": "{auction_id}",
    "clearing_price_cents": 500.0,
    "notification_data": "{notification_data}"
    `"name": "{winner_name}" //optional`
}
* {notification_data} is the value returned as {notification_data} in 
auction_response above

Response

200 OK

Status Endpoint

Request

GET https://{server_ip}:{port}/bks/status

Response

{
    "application": {
        "status": "ok"
    }
}

Logging

Configuration

Bidding Kit Server uses Logback in Java for logging. Find the default logging configuration in src/main/resources/logback-spring.xml. By default, Bidding Kit Server will log in files under the directory ./log.

Default logging level is DEBUG, but Log files could become huge under this logging level. Change to a higher level to reduce the noise.

To use an external logging configuration, add the following as a start up argument to the Java executable:

-Dlogging.config=<LOGGING_CONFIG_FILE>

What gets logged?

  • WARN / ERROR: any errors/warnings throughout the auction process, including invalid requests, bad inputs, errors from bidders, no bid from any bidder, etc.
  • INFO: Each request sent to BKS and the corresponding response as a transaction. Note that all the bids we get from bidders will also be logged to ensure transparency of BKS
  • INFO: win-loss notifications and display notifications are sent to bidders
  • DEBUG: potential errors related to configuration for bidders
  • DEBUG: if test field in the bid request is sent to 1, HTTP requests from BKS sent to the bidder will also be logged

NOTE: By default, user-level data is not marked up in Bidding Kit Server logging. To disable user level data logging, change logging.user-level-data to false in the configuration file. (By default, it’s located at src/main/resources/application.yaml.)

Metrics

Configuration

Bidding Kit Server supports reporting metrics to console, CSV, Graphite and Influxdb. By default, Bidding Kit Server does not send metrics to any of the backend mentioned above. You can modify src/main/resources/application.yaml file or extend the external configuration file:

Console

Available options are:

  • metrics.console.enabled - if true then console will be used to submit metrics.
  • metrics.console.interval - interval in seconds between successive sending metrics.

CSV

Available options are:

  • metrics.file.enabled - if true then metrics will be submitted to CSV files
  • metrics.console.path - path to the directory where CSV files should be created (please make sure that this path exists if CSV is enabled)
  • metrics.console.interval - interval in seconds between successive sending metrics.

Graphite

Available options are:

  • metrics.graphite.enabled - if true then graphite will be used to submit metrics.
  • metrics.graphite.prefix - the prefix of all metric names.
  • metrics.graphite.host - the graphite host for sending statistics.
    • metrics.graphite.port - the graphite port for sending statistics.
    • metrics.graphite.interval - interval in seconds between successive sending metrics.

Influxdb

Available options are:

  • metrics.influxdb.enabled - if true then influxdb will be used to submit
  • metrics.influxdb.prefix - the prefix of all metric names.
  • metrics.influxdb.protocol - external service destination protocol.
  • metrics.influxdb.host - the influxDb host for sending metrics.
  • metrics.influxdb.port - the influxDb port for sending metrics.
  • metrics.influxdb.database - the influxDb database to write metrics.
  • metrics.influxdb.auth - the authorization string to be used to connect to InfluxDb, of format username:password.
  • metrics.influxdb.connectTimeout - the connect timeout.
  • metrics.influxdb.readTimeout - the response timeout.
  • metrics.influxdb.interval - interval in seconds between successive sending metrics.
  • metrics.influxdb.tags - the influxDb tags, optional key-value metrics metadata.

Metrics Produced by BKS

  • General Auction Metrics:
    • app_requests - number of requests received from applications
    • request_time - timer tracking how long did it take for BKS to serve a request
    • imps_banner - number of banner impressions
    • imps_video - number of video impressions
    • imps_native - number of native impressions
    • requests.(ok|badinput|err|networkerr).BKS-app - number of requests broken down by status

  • Auction Per-bidder Metrics:
    • adapter.bidder_name.prices histogram of bid prices received from bidder_name.
    • adapter.bidder_name.bids_received - number of bids received from bidder_name.
    • adapter.bidder_name.(banner|video|audio|native).(adm_bids_received|nurl_bids_received) - number of bids received from bidder_name broken down by bid type and whether they had adm or nurl specified.
    • adapter.bidder_name.requests.(gotbids|nobid|badinput|badserverresponse|timeout|unknown_error) - number of requests made to bidder_name broken down by result status

Adding a New Bidder

Bidding Kit Server currently supports 6 bidders: Facebook, Tapjoy, Applovin, Chartboost, Ironsource and Vungle. To add a new Bidder:

Step 1: Choose a Bidder Name

This name must be unique.

Existing BidderNames are:

  • Facebook (alias FACEBOOK_BIDDER)
  • Tapjoy (alias TAPJOY_BIDDER)
  • AppLovin (alias APPLOVIN_BIDDER)
  • Chartboost (alias CHARTBOOST_BIDDER)
  • Ironsource (alias IRONSOURCE_BIDDER)
  • Vungle (alias VUNGLE_BIDDER)

NOTE: Throughout the rest of this section, substitute {bidder} with the name you've chosen.

Step 2: Configure the Bidder

Add the default configuration properties and metadata (for example, contact email, platform and media type support) for your bidder to src/main/resources/bidder-config/bidder.yaml.

For more information about application configuration, go to Getting Started.

Step 3: Implement the Bidder

Bidder implementation is spread across several files:

  • src/main/java/org/prebid/server/bidder/{bidder}/{bidder}Bidder.java: contains implementation of the BKSBidder abstract class (src/main/java/org/prebid/server/bidder/BKSBidder.java) and the Bidder interface (src/main/java/org/prebid/server/bidder/Bidder.java)
  • src/main/java/org/prebid/server/bidder/{bidder}/{bidder}Notifier.java: contains implementation of Notifier class (src/main/java/org/prebid/server/bidder/Notifier.java)
  • src/main/resources/static/bidder-params/{bidder}.json: A draft-4 json-schema which validates your Bidder's params. Bidder implementations may assume that any params have already been validated against the defined json-schema.

Step 4: Integrate the Bidder

After implementation you should integrate the Bidder with the file: src/main/java/org/prebid/server/spring/config/bidder/{bidder}Configuration.java

This must be a public class, with Spring @Configuration annotation so that framework could pick it up.

This file consists of three main parts:

  • The constant BIDDER_NAME.
  • Injected configuration properties (like endpoint, timeout, etc) needed for the Bidder's implementation.
  • Declaration of BidderDeps bean in one place as a single point-of-truth for application use.

In addition, you can add the @ConditionalOnProperty annotation if the bidder has no default properties. See src/main/java/org/prebid/server/spring/config/bidder/FacebookConfiguration.java as an example.

Step 5: Testing the Bidder

Configure, build and start your server (see Getting Started section)

Send a POST request to http://localhost:8000/bks/auction. If a valid bid request with bidder name {bidder} is passed in request.bidder_data then your bidder is called.