Tag Management

Kevel Tag Management enables you to serve any combination of third-party tracking tags (for example, cookie syncing and user matching tags) alongside ad requests by reducing calls to these tags to a single request. This single request is made at the same time as the ad request.

Tag Management also supports targeting (location based, device based, etc.) and frequency capping logic to ensure that the correct set of tags are served with the correct ad requests.

🚧

Tag Management is in Beta. The feature and this documentation is subject to change at any time.

How It Works

❗️

Some Assembly Required

Talk to your account manager or sales engineer before using Tag Manager. They will recommend the best solution given your tags and use case.

Your account manager or sales engineer will either recommend to:

  • Use the Tag Manager API to upload your tags to Kevel directly and then generate a hosted HTML page.

  • Present you with a hosted HTML page that contains your tags and Tag Manager logic.

This hosted page is called the Tag Manager URL. (See the "Generating a Tag Manager URL" section below.)

👍

If you upload your tags directly, your developers will use the Tag Management API to upload tags and their associated settings. For example, you can use macros, set custom timeouts, and custom properties to match tags to properties coming in from the request.

Insert the Tag Manager URL into your ados.js ad request to enable tag management. The ados_loadTags function applies tag management (and any custom timeouts and properties) to each placement. See the "Integrating Tag Management With Ados.js" section below.

ados_add_placement(1234, 123456, "azk424242", 5);
 ados_loadTags("http://t-1234.adzerk.net/1234/i.html", "azk424242");
 ados_load();

When a request is made to Kevel, the ados_loadTags function writes an iframe to the page that loads any eligible tags for the request.

Once all tags have loaded or timed out, a postMessage is sent to ados.js which triggers the ad decision for the request. By ensuring all tags load prior to an ad request, this maximizes match rates and fill rates.

📘

Each network is limited to 100 saved tags.

Tag Properties

A tag uploaded and stored via the Tag Manager API contains the following properties:

ParameterDescriptionTypeRequiredExampleDefault
IdThe unique ID of the tag. If no Id is specified when the tag is created, a random string will be used as the IdstringN66a171706ebd460c847c64f38dacc157randomly generated string
BodyThe HTML template of the tag. Supports the use of macrosstringY<img src="https://e.com/match?interest={{interest}}&cb={{cookieSyncUrl}}">N/A
EnabledWhether the tag is enabled to be rendered with ad requests.booleanNtruetrue
PriorityThe render order of the tag when tags are called. Tags are rendered in ascending order (1 is first).integerN5100
TargetingValid Zerkel markup used for targeting the tag to properties in the client.stringN$device.brandName like "*Samsung*"N/A
FrequencyCapHow often to render this tag per user (seconds). A frequency cap
less than or equal to zero disables frequency capping.
integerN600 (i.e. no frequency capping)

Generating a Tag Manager URL

The Tag Manager URL follows the schema:

http://t-<networkId>.adzerk.net/<networkId>/i.html

At this time, you should ask your sales engineer or account manager to generate the Tag Manager URL for you. It will be hosted on a unique t-networkId.adzerk.net domain.

Integrating Tag Management With Ados.js

After your Tag Manager URL has been generated, you will need to add the ados_loadTags(); function to your ados.js request before the ados_load(); function.

📘

ados_loadTags is for use with asynchronous tags only.

ados_loadTags(url, divId, timeout, properties)
ParameterDescriptionRequiredExample
urlThe Tag Manager URL. Also supports query parameters described in the Create Tag endpointY"http://t-1234/1234/i.html"
divIdThe ID of placement div, found in ados_add_placementY"azk424242"
timeoutHow long to wait for all tags to finish loading before loading
before loading async ad tags. Ads will be loaded either when the
postMessage is received from the tag manager or this timeout
expires, whichever is sooner.
N10000
propertiesA JavaScript object providing additional properties to be used for
targeting and macro expansion in the tag templates.
N{foo: 10}
<!-- In the document HEAD element. -->
<script type="text/javascript">
  var protocol = document.location.protocol == "https:" ? "https" : "http";
  var z = document.createElement("script");
  z.type = "text/javascript";
  z.src = protocol + "://static.adzerk.net/ados.js";
  z.async = true;
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(z,s);
</script>
<script type="text/javascript">
  var ados = ados || {};
  ados.run = ados.run || [];
  ados.run.push(function() {
    /* load placement for account: My Network,
                          site: My Wonderful Site,
                          size: 300x250 - Medium Rectangle */
    ados_add_placement(1234, 123456, "azk424242", 5);
    ados_loadTags("http://t-1234.adzerk.net/1234/i.html", "azk424242", 10000, {foo: 10});
    ados_load();
  });
</script>

<!-- In the document BODY element. -->
<div id="azk424242"></div>

When the ad request is called, the Tag Manager URL will be rendered on the page in an iframe:

<iframe width="0"
        height="0"
        style="display:none;visibility:hidden"
        src="https://t-1234.adzerk.net/1234/i.html">
</iframe>

📘

i.html can be used with the query parameters described in the List Tags endpoint. This includes passing additional properties, which will be merged with any properties from the request. See "Properties" section below.

👍

You can also call the Tag Manager URL without using ados.js by adding the above iframe to every page on your site.

PostMessages

When all tags have finished loading, a postMessage is sent to all parent iframes with the data set to "KevelTagManager:complete". This can be used to delay loading asynchronous ad tags until tag manager tags have finished loading.

<!-- Assuming tag manager snippet loaded at top of HEAD element. -->
<script>
  window.addEventListener("message", function(event) {
    if (event && event.data == "AdzerkTagManager:complete") {
      loadAsyncAdTags(); // Your ad code entry point here.
    }
  });
</script>

This can be useful to ensure that cookies have been synced with RTB partners before the ad requests are sent to the ad server.

Using Properties and Reserved Keys (Advanced)

Properties are a JSON object of keys and values that can be passed to the tag manager for targeting and template macro expansion. They can be passed via ados_loadTags/the Tag Manager URL or when uploading tags via the API.

📘

If custom properties are passed on both the Tag Manager URL and the uploaded tags, then the properties will be combined. If there is a conflict, the properties on the uploaded tags will take precedence.

Some keys are reserved by the tag manager:

KeyDescription
$userJavaScript object of a user's UserDB record. May be modified by tags. Stored in local storage in the client and persisted across requests.
$tagThe current tag object.
$tagViewsJavaScript object mapping tag IDs to last viewed timestamps. These are managed by the tag manager and updated automatically whenever tags are loaded. Tag view times are saved to local storage automatically and are persisted across requests.
$deviceObject containing device type information, with the following fields:

desktop: Set to true when client is a desktop browser.

mobile: Set to true when client is a mobile device.

smarttv: Set to true when client is a smarttv browser.

tablet: Set to true when client is a tablet device.

Note that more than one of the above properties may be set to true. For example, a user may be on a mobile tablet device.
$acceptLanguageSet to the value of the Accept-Language HTTP header sent by the client to the iframe endpoint.
$userAgentObject containing user agent information, with the following fields:

text: The user agent string as reported by the device.
$locationObject containing geolocation information, with the following fields:

countryCode: The ISO 3166-1 alpha-2 country code associated with the user's IP address.

For more information about how reserved keys work, see the main reserved keys in Zerkel article.

Tag Manager Client API (Advanced)

Tags that include object:

MethodDescription
ztm.envReturns the Properties object.
ztm.onload(element)Records a successful loading of the element.
ztm.onerror(element)Records an unsuccessful loading of the element.
ztm.waitFor(timeout)Returns a callback function. When this is called, the Tag Manager pauses and does not load the next tag until either the timeout has expired, OR
the returned callback function is called. Use this to force the Tag Manager to wait for some asynchronous process (e.g. cookie syncing) to
complete before rendering subsequent tags.
ztm.log(args...)Logs messages to the console when in debug mode (see below). Does nothing when not in debug mode.
<script> var cb = ztm.waitFor(500); </script>
<img src="http://e.com/usermatch" onload="cb()" onerror="cb()">

This example tag pauses the tag manager until ether 500ms has elapsed or the callback has loaded. The next tag will not be rendered until the Tag Manager has resumed execution.

👍

When waitFor is used, subsequent tags render synchronously in a new iframe when the timeout expires or the callback is called.

*Frequency Capping via the Client API

By default, tag view times are updated for each tag immediately when it is rendered, regardless of whether the HTML elements in the tag template load successfully or not. However, it is possible to ensure that a given set of HTML elements load successfully before updating tag view times so that view times are not updated for tags that do not load all of their HTML successfully.

A data-wait attribute in the HTML element and onload and onerror handlers will report to the Tag Manager that loading of that element is complete.

<img data-wait
     src="http://e.com/i.gif"
     onload="ztm.onload(this)"
     onerror="ztm.onerror(this)">

🚧

Note that when the data-wait attribute is specified, the onload and onerror attributes MUST be set to either ztm.onload(this) or ztm.onerror(this) or the Tag Manager will not be able to detect that the element has finished loading and will wait forever.

The data-wait attribute ensures that the tag manager only updates view times for the tag when all elements with data-wait set have called the ztm.onload(this) callback. If any element calls the ztm.onerror() handler, the view time for that tag will not be updated.

You can also use the waitFor function:

<script>
  var f1 = ztm.waitFor(500);
  var f2 = function(e) { ztm.onload(e); f1(); };
</script>
<img data-wait src="http://e.com/usermatch" onload="f2()" onerror="f2()">

Debug Mode

The Tag Manager will print debug info to the console when in Debug Mode.

To enable Debug Mode, set debug=true as a query string of the Tag Manager URL. The results in the console includes:

  • Which tags load
  • Whether they match targeting conditions
  • Whether they are frequency capped
  • When the postmessage is sent