Prebid.js is an increasingly popular open-source solution for gathering bids from a publisher’s demand partners. Using Prebid requires simple to moderate javascript development by the publisher. Broadstreet can be configured to work with Prebid.js.

Here is the general flow of working with Prebid:

  1. Set up Prebid creatives in Broadstreet, optionally separated by demand partner
  2. Include both Prebid and Broadstreet header code onto the publisher’s website
  3. Pass a list of ad units and subsequent demand partner configuration items into Prebid
  4. Wait for a response of bids from demand partners
  5. Collect winning bids for each ad unit
  6. Initialize the adserver, passing targeting that would invoke the campaign of the winning bidder and specify the winning Prebid ad id.

Steps to Implementation

There are several ways that Prebid could be implemented with Broadstreet, although the process is generally similar among all of them.

Set Up Prebid Tags

The first step is to set up Prebid tags inside Broadstreet.

First, we’ll click Advertisers, and click “New Advertiser” on the top right.

Next, we’ll create an HTML advertisement.

Note: You can repeat the steps that follow for each of your demand partners and ad sizes. In this example, we’ll only create one creative that can be used for multiple demand partners in a 300×250 unit.

Once the Prebid advertiser has been created, click “New Advertisement” on the top right. Select the second ad format option, the HTML / 3rd Party Code.

Paste in the following code. When delivered, the creative will tell Prebid to display the creative from the winning bidder inside an iframe. Be sure to change the width and height settings of the iframe in the code to match your needs.

<iframe id="%%RANDOM%%" width="300" height="250" frameBorder="0" scrolling="no"></iframe>
<script>
   if (window.pbjs) {
      window.pbjs.renderAd(document.getElementById('%%RANDOM%%').contentWindow.document, '%%PATTERN:hb_adid%%');
   } else {
      console.warn('No PBJS available');
   }
</script>

The above code in the interface:

Scroll down. Do not set the width and height fields below the HTML field. This will prevent the code from accessing Prebid in the parent window.

Save the ad.

Set Up Prebid Campaign(s)

Once the advertisement is saved, scroll down to the “Quick Campaign” area. Select the ad unit you would like the ad to run in and click “Create Campaign.”

On the next page, click “Edit Campaign.”

On the Weight tab, you can choose “Remnant” if you would like this tag to backfill when there aren’t campaigns of a higher weight competing against it.

You can also optionally set a keyword, such as a partner’s bidder code, along with “Keyword Exclusivity.” This is useful if you intend to set up different prebid creatives for each demand partner, so you can track which partners deliver winning bids most frequently.

Set any other required settings and save the campaign. Your prebid creative should now backfill.

Configure the site for Prebid

Like many adservers, Broadstreet can be initialized programmatically. Typically Prebid acquires bids, the winning bid is determined, and the adserver is initialized with certain targeting parameters.

Example code follows. Note that zone “12345” is an example zone id that would correspond to the Medium Rectangle zone we targeted our campaign to earlier.

<html>
<head>
    <script src="//cdn.broadstreetads.com/init-2.min.js"></script>
    <script>window.broadstreet = window.broadstreet || { run: [] };</script>
    <script>
        // Load the Prebid Javascript Lib
        (function () {
            var d = document;
            var pbs = d.createElement("script");
            pbs.type = "text/javascript";
            pbs.src = 'http://headertag.com/prebid/prebid-0.8-beta.js';
            var target = d.getElementsByTagName("head")[0];
            target.insertBefore(pbs, target.firstChild);
        })();
    </script>
    <script>
        // Get a map of winners from a PBJS bid response object
        function getWinners(bidResponses) {
            var winners = [];
            var zones = Object.keys(bidResponses);
            for (var i = 0; i < zones.length; i++) {
                winners.push({zone_id: zones[i], winner: getWinner(bidResponses[zones[i]]) });
            }
            return winners;
        }

        // Get a winner from an individual ad unit's bid response
		function getWinner(bidResponse) {
			var veryLowNumber = -1 * Math.pow(2,32);
			var highestCPM    = veryLowNumber;
			var bids          = bidResponse.bids;
			for (var i = 0; i < bids.length; i++) {
				if (highestCPM > bids[i].cpm) {
					continue;
				} else {
					highestCPM = bids[i].cpm;
					tmpWinner  = bids[i];
				}
			}
			return tmpWinner;
		}

        var PREBID_TIMEOUT = 5000; // Set your own

        /* initAdserver will be called either when all bids are back, or
         when the timeout is reached. */
        function initAdserver() {
            if (pbjs.initAdserverSet) return;
            pbjs.initAdserverSet = true;
			broadstreet.run.push(function () {
				pbjs.que.push(function () {
					// bid info is back from Prebid
					console.log('Dumping all bid objects to console:', pbjs.getBidResponses());
					var winners = getWinners(pbjs.getBidResponses());
                    console.log('Bid winners: ', winners);
                    var zoneOptions = {};
                    for (var i = 0; i < winners.length; i++) {
                        zoneOptions[winners[i].zone_id] = {
                            // keywords: [winners[i].winner.bidderCode], // optional for separate tags per bidding partner
                            // softKeywords: true, // require for the above
                            targets: { hb_adid: winners[i].winner.adId }
                        }
                    }

					// add a keyword to invoke the remnant placement
					broadstreet.watch({ zoneOptions: zoneOptions });
				});
			});
        }

        // Load when timeout is reached.
        setTimeout(initAdserver, PREBID_TIMEOUT);
        var pbjs = pbjs || {};
        pbjs.que = pbjs.que || [];

        pbjs.que.push(function () {
            /* 1. Register bidder tag Ids
             Registers the bidder tags for your ad units. Once the prebid.js
             library loads, it reads the pbjs.adUnits object and sends out
             bid requests. Find the complete reference on bidders at
             http://prebid.org/bidders.html.
             */
            var adUnits = [
                {
                    code: 12345, // broadstreet zone id (placement at bottom of page). Change as needed
                    sizes: [[300, 250]],
                    bids: [
                        {
                            bidder: 'indexExchange',
                            params: {
                                id: '1',
                                siteID: 999990
                           }
                        },
                        {
                            bidder: 'aol',
                            params: {
                                placement: '3675026',
                                network: '9599.1'
                           }
                        }
                    ]
                }
            ];
            // add the adUnits
            pbjs.addAdUnits(adUnits);
            // register a callback handler
            pbjs.addCallback('adUnitBidsBack', function (adUnitCode) {
                console.log('ad unit bids back for : ' + adUnitCode);
            });
            /* Request bids for the added ad units. If adUnits or adUnitCodes are
             not specified, the function will request bids for all added ad units.  */
            pbjs.requestBids({
                /* The bidsBack function will be called when either timeout is
                 reached, or when all bids come back, whichever happens sooner.  */
                bidsBackHandler: function (bidResponses) {
                    initAdserver();
                }
            });
        });
    </script>
    <script>

    </script>
</head>
<body>
<h2>Prebid + Broadstreet Test</h2>
<broadstreet-zone zone-id="12345"></broadstreet-zone>
</body>
</html>

At this point, your website should be fully configured for prebid. Information is also available for publishers who would only like to execute a Prebid when a zone is empty.