Set up and manage unified auction
Overview
Equativ's unified auction, formerly called Holistic+ allows you to run a full competition between direct (premium) campaigns, Equativ's RTB and 3rd party SSPs (server-side and client-side header bidding): the highest bid will win while making sure that direct campaigns will deliver their guaranteed targets (volumes).
Managed unified auction
The unified auction, as described in this article, requires many technical integration steps to be taken. Equativ also offers the much easier to use managed unified auction, where you simply add a single line of code in the website and do the rest of the setup and management in Monetize. If interested, get back to your sales and service contact at Equativ. For more information, see Set up and manage unified auction (managed).
Sign Up
To use unified auctions you need to sign up for the offer. Get back to your Sales/Service contact to start using it.
How it works
- the publisher implements the prebid.js header bidding wrapper in the
<head>
of the website - the header bidding wrapper calls the connected SSPs (header auction) and determines a winner (Note: Equativ is not part of the SSPs in this header auction)
- the Equativ tag on the publisher's page executes the ad call to Equativ, passing the header auction winner’s data (bidder name, CPM, currency)
- Equativ calls its monetization partners to attempt to retrieve a bid that is higher than the winner from the client-side header bidding auction
- Equativ operates a full optimization of all sales channels (direct campaigns, RTB, client-side header bidding)
- Equativ gives the impression to the highest bid while taking direct (guaranteed) campaign targets into account
Required reading
Before you start the setup, Equativ strongly recommends to get familiar with the basic concepts in Equativ's technology - especially if you are new to Equativ. This table lists articles with relevant content:
Article name | Relevant content |
---|---|
Activate open auctions | setup of RTB insertions (general settings, placement selection, script template etc. |
Create placements | setup of websites, pages, formats |
Tagging guide: get started | technical guide explaining Equativ's ad tags and javascript library (oneCall, Standard Call etc.) |
About the setup
Setting up unified auctions consists of 3 steps:
- Implementation of the client-side header bidding wrapper on the website for monetization through header bidding (at this time, Equativ supports prebid.js only)
- Implementation of Equativ's new tag on the website to take header bidding responses in Equativ RTB calls into account
- Setup in Monetization
In case of AMP inventory, use "Real Time Config (RTC)" rather than the setup described below — read section "Configuration of <amp-ad> with RTC in Holistic+ implementations" in the Supply AMP inventory article for more details.
Step 1 - Implementing the client-side header bidding wrapper
At this time, Equativ supports prebid.js only (other header bidding technologies are not supported). Proceed as follows:
- go to the prebid.js download page
- select the relevant bidder adapters (partners) and optionally an analytics adapter
- select the Supply Chain Object module and the Currency module (more details in chapter "Currency management" below)
- have the code sent to you by e-mail
- go to the Bidders' Params page to get help regarding the parameters for each partner
- finally, specify the timeout; the timeout is the maximum time to wait until the next step (the Equativ ad call) is executed - even if some partners have not responded yet
Step 2 - Implementing Equativ's new tag
Standard Call
If you are using Equativ's standard call, the only change to be done is to call sas.setHeaderBiddingWinner
before the Equativ ad call. View the sample here or copy its source code below. In this sample you will find:
- the
smart.js
library in the<head>
; Note:renderMode
must be2
; also,async
must betrue
(more about thesmart.js
library in the Tagging guide: get started; make sure you replace the<networkid>
by the one of your Equativ account - the header bidding wrapper configuration (
prebid.js
) including thePREBID_TIMEOUT
and the registeredadUnits
; Note: this sample has one registered bidder (bidder1
) - the
sendAdserverRequest
callback, which is triggered when a winner has been determined; it passes the winner's currency (see chapter "Currency management" below), bidder name and CPM to the Equativ ad call - the
sas.call
function which includes the placement information (tagId
,siteId
,pageId
,formatId
); make sure you replace all Ids by the ones of your account, including theformatId
which is part of thetagId
(thetagId
format issas_<formatId>
(e. g.:sas_1234
). - the callback function
onNoad
; this code manages the rendering of the header auction winner's ad in case the RTB auction did not result in a winner with a higher CPM
Standard call example
<html>
<head>
<!-- /!\ ATTENTION: replace the "<networkid>" below with your network's ID /!\ -->
<script src='https://ced.sascdn.com/tag/<networkid>/smart.js' type="text/javascript"></script>
<script type="text/javascript">
var sas = sas || {};
sas.cmd = sas.cmd || [];
sas.cmd.push(function() {
sas.setup({
/* /!\ ATTENTION: replace the domain below with your network's Equativ domain */
domain: 'https://prg.smartadserver.com',
renderMode: 2,
async: true
});
});
</script>
<script type="text/javascript" src="prebid.js" async></script>
<script>
var PREBID_TIMEOUT = 5000; /* custom prebid.js timeout value */
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
pbjs.que.push(function() {
var adUnits = [{
/* replace "3" with the formatID of your ad unit */
code: 'sas_3',
mediaTypes: {
"banner": {
sizes: [[300,250]]
},
},
bids: [{
bidder: 'bidder1',
params: {
placementId: '5756256'
}
}]
}];
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
// This callback gets triggered when all bids for this
// ad unit come back.
bidsBackHandler: sendAdserverRequest
});
});
var sendAdserverRequest = function(bidResponses) {
//pushes the bidResponse information to the Equativ platform, and triggers the placement render
sas.cmd.push(function() {
pbjs.que.push(function() {
var bid = pbjs.getHighestCpmBids("sas_3")[0]; /* replace "3" with the formatID of your ad unit */
if (bid) {
bid.currency = bid.currency || "USD";
sas.setHeaderBiddingWinner("sas_3", bid); /* replace "3" with the formatID of your ad unit */
sas.render();
}
});
});
};
//safety timeout for prebid response
setTimeout(function() {
sendAdserverRequest();
sas.cmd.push(function() {
sas.render();
});
}, PREBID_TIMEOUT);
</script>
</head>
<body>
<!-- /!\ ATTENTION: replace the "3" below with the formatID of your ad unit */ /!\ -->
<div id="sas_3">
<span>ad content</span>
<script type="text/javascript">
//Equativ ad unit setup
//note the ad unit will only be called after prebid.js
sas.cmd.push(function() {
sas.call("std", {
/* replace "3" with the formatID of your ad unit */
tagId: 'sas_3',
/* replace this ID by your tag's site ID */
siteId: 132432,
/* replace this ID by your tag's site ID */
pageId: 742455,
/* replace this ID by your tag's format ID */
formatId: 249770
}, {
onNoad: function() {
//called if Equativ has no fill
var bid = pbjs.getHighestCpmBids("sas_3")[0]; /* replace "3" with the formatID of your ad unit */
if (bid) {
var i = document.createElement("iframe");
i.style.width = 300;
i.style.height = 250;
i.style.overflow = "hidden";
i.setAttribute('frameBorder', 0); //to remove the default iframe border
i.setAttribute('scrolling', 'no'); //to remove any scrollbars
document.getElementById("sas_3").appendChild(i); /* replace "3" with the formatID of your ad unit */
pbjs.renderAd(i.contentWindow.document, bid.adId);
i.contentWindow.document.body.style.padding = '0'; //so there is no extra spacing in our iframe
i.contentWindow.document.body.style.margin = '0'; //so there is no extra spacing in our iframe
}
});
});
</script>
<!-- /!\ ATTENTION: the portion below is optional, for non-javascript supporting users. Replace with the proper IDs if used. /!\ -->
<noscript>
<a href="https://prg.smartadserver.com/ac?jump=1&nwid=73&siteid=132432&pgname=callwithecpm&fmtid=1000018334&visit=m&tmstp=[timestamp]&out=nonrich" target="_blank">
<img src="https://prg.smartadserver.com/ac?out=nonrich&nwid=73&siteid=132432&pgname=callwithecpm&fmtid=1000018334&visit=m&tmstp=[timestamp]" border="0" alt="" /></a>
</noscript>
</div>
</body>
</html>
OneCall
When using OneCall, you can set header bidding data per tagId
. The tagId
is the Id of the container (<div>
), where the ad will be displayed. The tagId
format is sas_<formatId>
(e. g.: sas_1234
).
For the unified auction, you must use Equativ's new OneCall tagging, which uses POST requests with all the necessary information in the request body. If you are a new Equativ customer this should not be of any concern: simply check if you see the formats
array in your tag (see new OneCall sample below). If you see formatId
, you are still dealing with an old tag - in this case, please get back to your service contact at Equativ. The rendering of the ad is identical for both old and new OneCall tags. Example old OneCall tag (in website <head>
):
<script src="https://ced.sascdn.com/tag/<networkid>/smart.js" type="text/javascript" async></script>
<script type="text/javascript">
var sas = sas || {};
sas.cmd = sas.cmd || [];
sas.cmd.push(function() {
sas.setup({ networkid: <networkid>, domain: "https://prg.smartadserver.com", async: true });
});
sas.cmd.push(function() {
sas.call("onecall", {
siteId: 53008,
pageId: 384769,
formatId: '23028,23030,23040',
target: ''
});
});
</script>
Example new OneCall tag (in website <head>
):
<script src="https://ced.sascdn.com/tag/<networkid>/smart.js" type="text/javascript" async></script>
<script type="text/javascript">
var sas = sas || {};
sas.cmd = sas.cmd || [];
sas.cmd.push(function() {
sas.setup({ networkid: <networkid>, domain: "https://prg.smartadserver.com", async: true });
});
sas.cmd.push(function() {
sas.call("onecall", {
siteId: 53008,
pageId: 384769,
formats: [{
id: 23028
},{
id: 23030,
tagId: "custom_TagId"
},{
id: 23040,
}],
target: ''
});
});
</script>
OneCall example
This example is a page with 3 placements. In the client side wrapper, there is one bidder for each placement.
<html>
<head>
<script type="text/javascript" src="prebid.js" async></script>
<!-- /!\ ATTENTION: replace the "<networkid>" below with your network's ID /!\ -->
<script src="https://ced.sascdn.com/tag/<networkid>/smart.js" type="text/javascript" async></script>
<!-- PREBID Start -->
<script>
// client side wrapper : Timeout + adunits definition for each placement to monetise
var PREBID_TIMEOUT = 5000; /* custom prebid.js timeout value */
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
var adUnits = [{
code: 'habillage',
mediaTypes: {
"banner": {
sizes: [[1800,1000]]
},
},
bids: [{
bidder: 'appnexus',
params: {
placementId: '5756253'
}
}]
}, {
code: 'pave',
mediaTypes: {
"banner": {
sizes: [[300,250]]
},
},
bids: [{
bidder: 'appnexus',
params: {
placementId: '5756256'
}
}]
}, {
code: 'megaban',
mediaTypes: {
"banner": {
sizes: [[670,90]]
},
},
bids: [{
bidder: 'appnexus',
params: {
placementId: '5756253'
}
}]
}];
// PREBID - AdUnits configuration
pbjs.que.push(function() {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
// This callback gets triggered when all bids for this
// ad unit come back.
bidsBackHandler: sendAdserverRequest
});
});
var sendAdserverRequest = function(bidResponses) { // Define the winner for each placement and give it to our adserver to handle the competition with Equativ RTB and direct
// PREBID - Responses --> One per format
sas.cmd.push(function() {
pbjs.que.push(function() {
var bid = pbjs.getHighestCpmBids("habillage")[0];
if (bid) {
sas.setHeaderBiddingWinner("habillage", bid);
}
bid = pbjs.getHighestCpmBids("pave")[0];
if (bid) {
sas.setHeaderBiddingWinner("pave", bid);
}
bid = pbjs.getHighestCpmBids("megaban")[0];
if (bid) {
sas.setHeaderBiddingWinner("megaban", bid);
}
sas.render(); //As to be present or the adserver won't be aware it's ok
});
});
};
setTimeout(function() {
sendAdserverRequest();
}, PREBID_TIMEOUT);
</script>
<!-- PREBID End -->
<!-- Equativ Start -->
<script type="text/javascript">
var sas = sas || {};
sas.cmd = sas.cmd || [];
sas.cmd.push(function() {
sas.setup({
/* ATTENTION: replace the "<networkid>" below with your network's ID */
networkid: < networkid > ,
/* /!\ ATTENTION: replace the domain below with your network's Equativ domain */
domain: "https://prg.smartadserver.com",
async: true,
renderMode: 2 //Important, has to be specified as 2 or it won't deliver
});
});
// Equativ OneCall Function for monetized formats on the page ( new onecall tag )
sas.cmd.push(function() {
sas.call("onecall", {
/* replace this ID by your tag's site ID */
siteId: 179962,
/* replace this ID by your tag's site ID */
pageId: 864366,
formats: [{
/* replace this ID by your tag's format ID */
id: 51284,
tagId: "habillage" /* tagID for the respective formatID */
}, {
/* replace this ID by your tag's format ID */
id: 60321,
tagId: "pave" /* tagID for the respective formatID */
}, {
/* replace this ID by your tag's format ID */
id: 60320,
tagId: "megaban" /* tagID for the respective formatID */
}, ],
target: ''
}, {
// IF No Equativ Over bid or Premium --> Rendering Ads from Header Bidding best bidder (one per HB placement)
onNoad: function(a) {
// Display Habillage from best bidder
if (a.tagId == "habillage") {
var bid = pbjs.getHighestCpmBids("habillage")[0];
if (bid) {
var i = document.createElement("iframe");
i.style.width = 1800; //bid.width
i.style.height = 1000; //bid.height
//+ ajouter modification CSS pour clean affichage
i.style.overflow = "hidden";
i.setAttribute('frameBorder', 0); //to remove the default iframe border
i.setAttribute('scrolling', 'no'); //to remove any scrollbars
document.getElementById("habillage").appendChild(i);
pbjs.renderAd(i.contentWindow.document, bid.adId);
i.contentWindow.document.body.style.padding = '0'; //so there is no extra spacing in our iframe
i.contentWindow.document.body.style.margin = '0'; //so there is no extra spacing in our iframe
}
}
// Display Pave from best bidder
if (a.tagId == "pave") {
var bid = pbjs.getHighestCpmBids("pave")[0];
if (bid) {
var i = document.createElement("iframe");
i.style.width = 300;
i.style.height = 250;
i.style.overflow = "hidden";
i.setAttribute('frameBorder', 0); //to remove the default iframe border
i.setAttribute('scrolling', 'no'); //to remove any scrollbars
document.getElementById("pave").appendChild(i);
pbjs.renderAd(i.contentWindow.document, bid.adId);
i.contentWindow.document.body.style.padding = '0'; //so there is no extra spacing in our iframe
i.contentWindow.document.body.style.margin = '0'; //so there is no extra spacing in our iframe
}
}
// Display Megaban from best bidder
if (a.tagId == "megaban") {
var bid = pbjs.getHighestCpmBids("megaban")[0];
if (bid) {
var i = document.createElement("iframe");
i.style.width = 670;
i.style.height = 90;
i.style.overflow = "hidden";
i.setAttribute('frameBorder', 0); //to remove the default iframe border
i.setAttribute('scrolling', 'no'); //to remove any scrollbars
document.getElementById("megaban").appendChild(i);
pbjs.renderAd(i.contentWindow.document, bid.adId);
i.contentWindow.document.body.style.padding = '0'; //so there is no extra spacing in our iframe
i.contentWindow.document.body.style.margin = '0'; //so there is no extra spacing in our iframe
}
}
}
});
});
</script>
<!-- Equativ End -->
</head>
<body>
<!-- RENDERING Habillage -->
<div id="habillage"></div>
<script type="text/javascript">
sas.cmd.push(function() {
sas.render("habillage"); //trigger the delivery, has to be put in the targeted div which has to be already created
});
</script>
<!-- RENDERING Pave -->
<div id="pave"></div>
<script type="text/javascript">
sas.cmd.push(function() {
sas.render("pave"); //trigger the delivery, has to be put in the targeted div which has to be already created
});
</script>
<!-- RENDERING Megaban -->
<div id="megaban"></div>
<script type="text/javascript">
sas.cmd.push(function() {
sas.render("megaban"); //trigger the delivery, has to be put in the targeted div which has to be already created
});
</script>
</body>
</html>
The sas.setHeaderBiddingWinner
function must be called before the sas.call
function of the corresponding tagId
.
Sending extended Ids
If you have implemented user identification providers, you can send extended Ids to Equativ - see chapter "Sending extended Ids in Holistic+ integrations" in the Extended ID integration (alternative/universal IDs) article.
Counting successful or failed rendering of header bidding winner’s creative
If Equativ’s RTB has no higher bid than the Header Bidding winner, Equativ returns a “no ad” response, counts this as a “no ad” impression and lets the header bidding winner render its creative. However, Equativ has no knowledge if the header bidding winner’s creative was rendered successfully or if the rendering failed. To overcome this constraint, Equativ’s smart.js library contains these methods to trigger additional events:
-
sas.hbRenderSuccess()
- triggers thehbRenderSuccessUrl
from Equativ’s noad response; to be called when the header bidding winner’s creative has been rendered successfully (e. g. usingprebid.renderAd()
). -
sas.hbRenderFailed()
- triggers thehbRenderFailedUrl
from Equativ’s noad response; to be called when the rendering of the header bidding winner’s creative failed (e. g. usingprebid.renderAd()
).
Samples of the URLs included in Equativ’s noad response:
sas.noad("sas_79589", {
"HbRenderFailedUrl":"https://eqx.smartadserver.com/track/action?pid=1216704&acd=1626940232586&opid=8d83a86f-f917-4c8f-a132-100ebffa09d3&opdt=1626940232553&uii=235419703685161232&hb_bid=appnexus&key=hbRenderFailed",
"HbRenderSuccessUrl":"https://eqx.smartadserver.com/track/action?pid=1216704&acd=1626940232586&opid=8d83a86f-f917-4c8f-a132-100ebffa09d3&opdt=1626940232553&uii=235419703685161232&hb_bid=appnexus&key=hbRenderSuccess"
});
The methods sas.hbRenderSuccess()
and sas.hbRenderFailed()
can be used along with the prebid.js implementation by listening to the prebid events adRenderSucceeded
and adRenderFailed
available since v 5.3.0; more details in the pbjs.getEvents() documentation.
Sample implementation of the sas.hbRenderFailed()
method:
pbjs.onEvent('adRenderFailed', function () {
// publisher-specific logic with sas.hbRenderFailed();
});
In case of managed unified auctions, the adRenderSucceeded
/ adRenderFailed
mechanism is managed automatically.
Step 3 - Setup in EMP
There is no need to create any insertions for the header bidding itself, since this is done by the header bidding wrapper. However, you must have at least one RTB insertion on each placement (combination of site, page, format) where the header bidding wrapper is used. The creation of RTB insertions is explained in Activate open auctions.
Additionally, keep in mind:
- in the RTB insertion, you must enable the option "Holistic yield" (in the "General settings" section of the insertion)
- RTB must be enabled and configured (global settings in the network)
- the unified auction feature must be enabled on the network
- you must use the official RTB creative templates in the insertions
Currency management
With the optional Prebid.js Currency Module, publishers can specify an ad server currency and convert all bids to this currency before the auction. The Currency Module is added to a page by calling the setConfig
API as shown in the snippet below.
pbjs.setConfig({
"currency": {
"adServerCurrency": "EUR",
"defaultRates": { "USD": { "EUR": 0.8 }}
}
});
In the snippet above, the adServerCurrency
is set to EUR
. Note that the defaultRates
attribute is optional, but recommended in case there is an issue loading the currency file. The full documentation of the currency module is available here.
If the currency module is not installed, the header auction winner’s bid is passed to Equativ in the default currency USD. If the Currency Module is installed on the published page, and if an adServerCurrency
is defined, the header auction winner’s bid is passed to Equativ in the adServerCurrency
using the hb_ccy
parameter.
Equativ supports the currencies in the following list only! In case of any other currencies (unknown currencies), the header bidding response will be considered as invalid.
Currency code | Description |
---|---|
AED | Emirati Dirham |
ARS | Peso Argentino |
BRL | Real Brasileiro |
CAD | Dollar Canadien |
CHF | Franc Suisse |
CZK | Czech Koruny |
DKK | Danish Krone |
EUR | Euro |
GBP | British Pound |
HRK | Croatian Kuna |
HUF | Hungarian Forint |
LTL | Lithuanian Litas (Lt) |
LVL | Latvian Lats |
NOK | Norwegian kroner |
PLN | Polish Zloty |
RUB | Russian Ruble |
UAH | Ukrainian Hryvnia |
USD | US Dollar |
About header bidding in a “Equativ2Equativ” setup
A “Equativ2Equativ” setup is a setup where ad calls from a primary placement (siteId, pageId, formatId) in a primary network are “forwarded” to a secondary placement in a secondary network. This is done by an insertion with the creative script template “Smart server-side backfill” on the primary placement. In this script template, the siteId/pageId/formatId of the secondary placement are registered. Header bidding with full stack usage in a Equativ2Equativ setup works as follows:
- at least one RTB insertion must exist in the secondary network on the secondary placement
- the header bidding winner CPM is transmitted to the secondary network and used as a floor price there
- if the secondary network does not win the auction, Equativ
- will log a “noad” (unfilled impression) in the secondary network without any header bidding data and provide the according reports
- will log a “noad” with the header bidding data in the primary network and provide the reports as described below (see “Available reports”)