Overview
Equativ's Holistic+ offer 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 Holistic+
Holistic+, as described in this article, requires many technical integration steps to be taken. Equativ also offers the much easier to use"
Managed Holistic+" version, where you simply add a single line of code in the website and do the rest of the setup and management in
EMP. If interested, get back to your sales and service contact at Equativ; more about Managed Holistic+
here.
Sign Up
To use Holistic+ 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 |
---|
Glossary | description of key concepts and features |
Setting up inventory | setup of websites, pages, formats |
Tagging guide | technical guide explaining Equativ's ad tags and javascript library (oneCall, Standard Call etc.) |
RTB Insertions | setup of RTB insertions (general settings, placement selection, script template etc. |
About the setup
Setting up Holistic+ 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 EMP
NoteIn 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
Tagging Accelerated Mobile Pages (AMP HTML) 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 be 2; also, async must be true (more about the smart.js library in the Tagging guide); make sure you replace the <networkid> by the one of your Equativ account
- the header bidding wrapper configuration (prebid.js) including the PREBID_TIMEOUT and the registered adUnits; 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 the formatId which is part of the tagId (the tagId format is sas_<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
<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).
Important noteFor Holistic+, 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>
Keep in mind: 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 User Identification 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 the hbRenderSuccessUrl from Equativ’s noad response; to be called when the header bidding winner’s creative has been rendered successfully (e. g. using prebid.renderAd()).
- sas.hbRenderFailed() - triggers the hbRenderFailedUrl from Equativ’s noad response; to be called when the rendering of the header bidding winner’s creative failed (e. g. using prebid.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() documentationSample implementation of the
sas.hbRenderFailed() method:
pbjs.onEvent('adRenderFailed', function () {
// publisher-specific logic with sas.hbRenderFailed();
});
In case of
Managed Holistic+, 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
here.
Additionally,
keep in mind:
- in the RTB insertion, you must enable the checkbox "Activate Holistic yield mode:" (in the "General settings" section of the insertion)
- RTB must be enabled and configured (global settings in the network)
- the Holistic+ feature must be enabled on the network
- you must use the official and Holistic RTB script 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.
Note: 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 |
---|
EUR | Euro |
USD | US Dollar |
GBP | British Pound |
CHF | Franc Suisse |
CAD | Dollar Canadien |
PLN | Polish Zloty |
RUB | Russian Ruble |
CZK | Czech Koruny |
HUF | Hungarian Forint |
UAH | Ukrainian Hryvnia |
AED | Emirati Dirham |
ARS | Peso Argentino |
LVL | Latvian Lats |
LTL | Lithuanian Litas (Lt) |
HRK | Croatian Kuna |
BRL | Real Brasileiro |
DKK | Danish Krone |
NOK | Norwegian kroner |
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”)