Google Ad Manager (GAM) - Criteo Onsite Display

Introduction

📘

About GAM

GAM (Google Ad Manager) is a comprehensive ad management platform that enables publishers and retailers to manage, sell, and optimize both direct and programmatic ad inventory across web, mobile, and app environments.

👍

GAM online Documentation

You can find the full Google Ad Manager documentation here.

This guide provides an overview of integrating with Google Ad Manager (GAM) to serve Criteo Onsite Display Ads on your retail website. This integration enables monetization of your onsite inventory with demand from Criteo's network of advertisers while giving you full control through your existing GAM setup.

The GAM integration allows Criteo to serve display ads via creatives trafficked into your GAM network. Retailers can maintain control over inventory, placements, and rules while benefiting from Criteo’s demand.


GAM workflow

Overview of the GAM workflow

Overview of the GAM workflow

📘

A Google Ad Manager (GAM) Javascript Tag (GPT) is already available on the Retailer Website in this example. This documentation assumes the Retailer has already made an integration with GAM.

The GAM workflow follows these steps:

Step 1: Ad Call Initialization

On each page load, the retailer’s site triggers a GAM ad request using the GPT (Google Publisher Tag) JavaScript on the client side. This ad call should include relevant contextual information — such as search keywords, product categories, or a retailer visitor ID — which GAM will use to serve the Criteo line item.

Step 2: Criteo Creative Setup in GAM

The retailer sets up a new line item in GAM for the placement to be monetized with Criteo demand. This line item includes the Criteo Standalone JavaScript Tag as creative.

GAM will collect all relevant targeting parameters server-side via the Google macro : %%PATTERN:TARGETINGMAP%%, to feed the Criteo tag and substitute all relevant targeting infos.

Step 3: Criteo Tag Execution

The substituted Criteo JavaScript tag is served and executed on the retailer's webpage. At this point, the tag contains all required contextual values, enabling Criteo to process the ad request accurately.

Step 4: Criteo Demand Call

Criteo’s system (CYield) is then called to evaluate the request and determine whether an ad is eligible to be served.

Step 5: Ad Rendering or Passback

Depending on Criteo's availability:

  • Option A – Ad Served: Criteo returns a valid ad response along with its rendering library (rm.js). This script is responsible for rendering the creative on the page and firing the appropriate tracking beacons.
  • Option B – No Ad: If no eligible ad is available, the Criteo library (rm.js) executes a customizable JavaScript-based passback. This gives GAM the opportunity to serve an alternative line item.

GPT configuration & ad call

The example below demonstrates the modification of a Google Publisher Tag (GPT) that was auto-generated from the Ad Unit. Because the GPT is implemented as a JavaScript library, it is also possible for the Retailer to have a more advanced configuration for their GPTs.

GPT (Google Publisher Tag) Configuration

In order to pass all relevant targeting infos, the Google Publisher Tag will need to be modified. The .setTargeting invocations in the example below show an example with hard-coded values. In practice, the rvid and context values would have to be populated dynamically with real user data.

<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
<script>
  window.googletag = window.googletag || {cmd: []};
  googletag.cmd.push(function() {
    googletag.defineSlot('/2729856/BEN_TEST', [1024, 768], 'div-gpt-ad-1720721740722-0').addService(googletag.pubads())
    
    // RETAILER VISITOR ID = "TUoQPO58Wkr1dIYn234Eao"
    .setTargeting("rvid","TUoQPO58Wkr1dIYn234Eao")
    // CONTEXT (Keyword) = "laptop"
    .setTargeting("context","laptop")
    // Extra parameter example with the language : lang == "french"
    .setTargeting("lang","french")

    googletag.pubads().enableSingleRequest();
    googletag.enableServices();
  });
</script>

<!-- /2729856/BEN_TEST -->
<div id='div-gpt-ad-1720721740722-0' style='min-width: 1024px; min-height: 768px;'>
  <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1720721740722-0'); });
  </script>
</div>

GAM Ad call Debugging

The above tag will generate a call to GAM looking like the following:

https://securepubads.g.doubleclick.net/gampad/ads?pvsid=1920534727927771&correlator=4328069051982008&eid=31086815%2C31089864%2C31090092%2C83321073&output=ldjh&gdfp_req=1&vrg=202501290101&ptt=17&impl=fifs&iu_parts=2729856%2CBEN_TEST&enc_prev_ius=%2F0%2F1&prev_iu_szs=1024x768&ifi=1&dids=div-gpt-ad-1720721740722-0&sfv=1-0-40&sc=1&abxe=1&dt=1738351792324&lmt=1738351756&adxs=8&adys=8&biw=757&bih=934&scr_x=0&scr_y=0&btvi=0&ucis=1&oid=2&u_his=1&u_h=1080&u_w=1920&u_ah=1055&u_aw=1920&u_cd=24&u_sd=1&u_tz=-300&dmc=8&bc=31&nvt=2&uach=WyJtYWNPUyIsIjE1LjIuMCIsImFybSIsIiIsIjEzMi4wLjY4MzQuMTExIixudWxsLDAsbnVsbCwiNjQiLFtbIk5vdCBBKEJyYW5kIiwiOC4wLjAuMCJdLFsiQ2hyb21pdW0iLCIxMzIuMC42ODM0LjExMSJdLFsiR29vZ2xlIENocm9tZSIsIjEzMi4wLjY4MzQuMTExIl1dLDBd&uas=3&url=file%3A%2F%2F%2FUsers%2Fb.chapuzet%2FDownloads%2Findex.html&vis=1&psz=741x918&msz=1024x768&fws=0&ohw=0&topics=9&tps=9&htps=10&nt=1&psd=WzE1LFtdLG51bGwsM10.&dlt=1738351784028&idt=8274&prev_scp=rvid%3DTUoQPO58Wkr1dIYn234Eao%26pa%3DviewSearchResult_API_desktop%26pl%3DInGrid%26kwd%3Dlaptop&adks=1933767165&frm=20&td=1&tan=2ceb47bf-5516-425e-93fb-3739f388a083&tdf=2

To be able to see those newly created parameter on your ad call, you must examine the request made to GAM:

  • Reload the retailer’s page with Chrome Developer Tools open.
  • Filter by “gam” in the Network tab.

On the “Payload” tab of this request, find the prev_scp (slot level) and/or cust_params (page level) query string parameters.

Those two parameters (prev_scp and/or cust_params) will carry all relevant parameters that our newly created standalone tag needs. Both cust_params (page level) and/or prev_scp (slot level) are going to be passed to the GAM Ad Server, and any information inside will be accessible via a macro.


Criteo JS standalone tag

A new line item in GAM needs to be created to host and deliver the following tag. Configuring the line item in GAM is largely up to the Retailer.

A modified version of the following tag needs to be uploaded in your GAM Ad Server as a new third party creative within a new line item:

Criteo Tag (Copy & Modify)

<script src="https://d.us.criteo.com/Delivery/ClientPaths/Library/rm.js?a=[TO_BE_REPLACED]"></script>
<script>
  var targeting = %%PATTERN:TARGETINGMAP%%;
  var criteoPartnerId = "[TO_BE_REPLACED]";
  var pageId = "[TO_BE_REPLACED]";
  var placementId = "[TO_BE_REPLACED]";
  var context = targeting.[TO_BE_REPLACED][0];
  var retailerVisitorId = targeting.[TO_BE_REPLACED][0];
  var cacheBuster = %%CACHEBUSTER%%;

  var passbackData = { [TO_BE_REPLACED] };
  var renderData = { [TO_BE_REPLACED] };

  var scriptSrc = "https://d.us.criteo.com/delivery/v2/rmgam"
    + "?criteo-partner-id=" + criteoPartnerId
    + "&page-id=" + pageId
    + "&placement-id=" + placementId
    + "&context=" + context
    + "&retailer-visitor-id=" + retailerVisitorId
    + "&passbackData=" + encodeURIComponent(JSON.stringify(passbackData))
    + "&renderData=" + encodeURIComponent(JSON.stringify(renderData))
    + "&cb=" + cacheBuster;

  document.write('<scr' + 'ipt type="text/javascript" src="' + scriptSrc + '"></scr' + 'ipt>');
</script>

Detailed Criteo Tag (Example)

// "345123" is the Retailer dedicated Criteo Partner ID
<script src="https://d.us.criteo.com/Delivery/ClientPaths/Library/rm.js?a=345123"></script>
<script>

// %%PATTERN:TARGETINGMAP%% is used to collect all targeting infos from the GAM ad call
// In this example, it will contain: ("rvid","TUoQPO58Wkr1dIYn234Eao") and ("context","laptop") and ("lang","french")
var targeting = %%PATTERN:TARGETINGMAP%%;

// "345123" is the Retailer dedicated Criteo Partner ID
var criteoPartnerId = "345123";

// "pageId" is the page name as exposed in the Criteo configuration 
var pageId = "viewSearchResult_GAM_desktop";

// "placementId" is the placement name as exposed in the Criteo configuration 
var placementId = "search_bigbox_1_1_300x250";

// "context" can be a keyword, a category, a SKU ID. Criteo will use the page type to determine how to use this context
// In this example, context == "laptop" is inferred dynamically from the GPT tag: .setTargeting("context","laptop")
var context = targeting.context[0];

// "retailerVisitorId" is a unique `UserID` that is persistent across sessions on the same device
// In this example, retailerVisitorId == "TUoQPO58Wkr1dIYn234Eao" is inferred dynamically from the GPT tag: .setTargeting("rvid","TUoQPO58Wkr1dIYn234Eao")
var retailerVisitorId = targeting.rvid[0];

// %%CACHEBUSTER%%\ is a macro generating a random number to prevent caching
var cacheBuster = %%CACHEBUSTER%%;

// "passbackData" is used to pass extra data to populate dynamically the passback tag only.
// In this example, "passbackData" == {"targetingMap":{"rvid":["TUoQPO58Wkr1dIYn234Eao"],"context":["laptop"],"lang":["french"]}}
var passbackData = { targetingMap: targeting };

// "renderData" is used to pass extra data for to populate dynamically the ad only.
// In this example, "renderData" == {"rendering":"french"}, so that the library can select only French descriptions for example
  var renderData = { rendering: targeting.lang };

// The Criteo ad call is built here
  var scriptSrc = "https://d.us.criteo.com/delivery/v2/rmgam"
    + "?criteo-partner-id=" + criteoPartnerId
    + "&page-id=" + pageId
    + "&placement-id=" + placementId
    + "&context=" + context
    + "&retailer-visitor-id=" + retailerVisitorId
    + "&passbackData=" + encodeURIComponent(JSON.stringify(passbackData))
    + "&renderData=" + encodeURIComponent(JSON.stringify(renderData))
    + "&cb=" + cacheBuster;

  document.write('<scr' + 'ipt type="text/javascript" src="' + scriptSrc + '"></scr' + 'ipt>');
</script>

Passback management (Example)

In the event Criteo does not have any ads to serve, Criteo needs to give the hand back to GAM in order to serve another ad. For this reason, you need to provide a GAM passback tag to Criteo so that Criteo can call back GAM. This tag looks like the following:

<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js" crossorigin="anonymous"></script>
<div id="gpt-passback">
  <script>
    window.googletag = window.googletag || {cmd: []};
    googletag.cmd.push(function() {
    googletag.defineSlot('/2729856/BEN_TEST', [1024, 768], 'gpt-passback').addService(googletag.pubads())

    // To avoid calling the same line item if no ad and create an infinite loop, add an exclusion targeting keyword to your newly created line items and in your passback tag
    .setTargeting("exclusionTargeting","CRITEO")

    // To dynamically inject all the targeting to your passback tag, you can use "passbackData.targetingMap"
    .updateTargetingFromMap(passbackData.targetingMap);

    googletag.enableServices();
    googletag.display('gpt-passback');
    });
  </script>
</div>

In this example, to avoid infinite loop, an exclusion targeting keyword ("exclusionTargeting = CRITEO") has been added to the passback tag and in the line item so that this specific line item will not serve again.

Also, you have the option to dynamically populate your passback tag, in this example, the GAM Targeting map (all the targeting) is dynamically passed via the passbackDataparameter from the Criteo Ad Call (cf passbackData) using passbackData.targetingMap. More extra data can be passed using the same method.


Criteo Ad call Parameters

ParameterTypeExample(s)DescriptionRequired
criteo-partner-idint1234567The key that corresponds with your specific partner ID within Criteo. Please reach out to your Technical Account Manager to set up if needed.Yes
page-idstringviewSearchResult_API_desktopThe page name as exposed in the Criteo configuration. Please reach out to your Technical Account Manager to set up if needed.Yes (can be hardcoded)
placement-idstringInGridThe placement name as exposed in the Criteo configuration. Please reach out to your Technical Account Manager to set up if needed.Yes (can be hardcoded)
retailer-visitor-idstringTUoQPO58Wkr1dIYn234EaoA unique UserID that is persistent across sessions on the same device.Yes
contextstringlaptop or Beverages>Beverages>Soda, or 1000068949Contextual data that can be any of: A keyword, A category, A SKU ID. Delivery will use the page type to determine how to use this context data to look up ads.Required for all page types except homepage
renderDataURL encoded JSONURL Encoded: %7B%22lang%22%3A%22french%22%7D
URL Decoded: {"lang":"french"}
Used to pass extra data for rendering purpose only. In this example, the lang parameter would be used to select the ad language to render.
It can be accessed from the creative response using: renderData.lang for example
No (optional)
passbackDataURL encoded JSONURL Encoded: %7B%22targetingMap%22%3A%7B%22rvid%22%3A%5B%22TUoQPO58Wkr1dIYn234Eao%22%5D%2C%22context%22%3A%5B%22laptop%22%5D%2C%22lang%22%3A%5B%22french%22%5D%7D%7D
URL Decoded: {"targetingMap":{"rvid":["TUoQPO58Wkr1dIYn234Eao"],"context":["laptop"],"lang":["french"]}}
Used to pass extra data for to populate dynamically the passback tag only.
It can be accessed from the Passback tag using: passbackData.targetingMap for example
No (optional)
cbstring 2032430748cb should be populated via the%%CACHEBUSTER%% macro that will generate a random number to prevent cachingNo (optional)
regionIdstring42Store ID selected by the user when browsing the retailer’s site. It should match the store IDs in the product feed. See more details here.Yes, if Store IDs are defined in the product feed
gdprstring1, 2Indicates if GDPR applies to this user. (1: yes, the user is in Europe and GDPR applies; 2: no, the user is outside Europe).Yes, if using TCFv2 standard
gdpr_consentstringCAGgAagBEADEAIQAfoB...The encoded TCFv2 consent string.Yes, if using TCFv2 standard
blockbit1, 0Value '1' is for opt-out users. (Value '0' can also be passed for opt-in users.)No, only when the user is opt-out and not using the TCFv2 standard