Anatomy of an online ad

I’ve been asked to explain how online ads are delivered many times and every time I’m surprised by the complexity of covering even the most basic elements of how ads appear on Web pages. Since Wikipedia’s article on ad serving is not much help, I’ll try to explain one common way ads are delivered using a concrete example.

Side note: this is not how Swoop works. At Swoop we use a much simpler and more efficient model because we’ve built an end-to-end system. This eliminates the need for lots of different systems to touch (+ cookie + track) users. It also allows us to create deeper and more relevant matches by placing Swoop content not in arbitrary fixed slots but in dynamic slots right next to the part of a page it relates to. If you are looking for an analogy, think about Google Adwords on SERPs. It’s an end-to-end system where Google has complete control over ad placement and no ads are shown if there are no relevant ads to show.

Tools of the trade

If you want to know how adtech works, there is no better tool than Ghostery. Ghostery was created by my friend David Cancel and, later, when he was starting Performable (now part of Hubspot), my previous startup, Evidon, became the custodian of the Ghostery community. Ghostery will show you, page-by-page, all the different adtech players operating on a site. For example, on’s sports page, there are 35 (!) separate adtech scripts running today.

ghostery-on-boston-sportsGhostery will show you what is happening but not how it happened. If you are technical and want to understand the details of how ad delivery works, there no better tool than a debugging proxy such as Charles or Fiddler. Just be prepared for the need to use code deobfuscators. If you don’t have time for wading through obfuscated code and you really want to know what’s going with your sites(s) or campaign(s), it is worth taking a look at Evidon Encompass. It’s an advanced analytics suite built on top of the Ghostery data.

The example

The example we’ll use is the arthritis page on Yahoo!’s health network. We will focus on the leaderboard ad at the top, which is a Celebrex (arthritis drug) ad from Pfizer.


What Yahoo! sent the browser

The initial response my browser got from Yahoo!’s server included the following chunk of HTML about the leaderboard ad unit, which I’ve formatted and added comments to. (Not sure what’s up with the empty lines that WP is adding to the bottom of the gists–they’re not on GitHub).

<!– Leaderboard slot on Yahoo!'s health network –>
<div id="yahoohealth-n-leaderboard-ad" style="border:0;margin-top:0;">
<div style="margin-bottom:9px;text-align:center">
<!– Ad unit delivery script if scripting is available –>
<script language="JavaScript" type="text/javascript" src=";p=health&amp;l=N&amp;c=r&amp;rs=cnp:healthline&amp;at=hlids%3Dx%26hlk1%3D8234384%26hlk2%3D8317112%26hlkwa%3D2790905%20refurl%3D%22%22">
<!– Yahoo 1×1 tracking pixel delivery script –>
<script language="JavaScript" type="text/javascript" src=";p=health&amp;l=FSRVY&amp;c=sr">
<!– Ad unit delivery as HTML if scripting is not available –>
<iframe frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="728" height="106" src=";p=health&amp;l=N&amp;c=h&amp;rs=cnp:healthline&amp;at=hlids%3Dx%26hlk1%3D8234384%26hlk2%3D8317112%26hlkwa%3D2790905%20refurl%3D%22%22">

This content was mostly likely emitted by the Yahoo publishing system without direct coordination with the Yahoo ad server but instead using conventions about categories, page types, etc. and hence parameters like rs=cnp:healthline that you see on the URLs.

Display advertising units use standard IAB formats. In this case, we are dealing with a 728×90 leaderboard unit. The DIV with id yahoohealth-n-leaderboard-ad sets up the location where the ad unit will be displayed. The DIV under it serves the dubious function of controlling some styling related to the ad content.

Beyond this there are two things going on here. The first is the delivery of the ad script and the second is the delivery of a tracking pixel via a tracking pixel script.

Tracking pixels

Tracking pixels are 1×1 invisible images served from highly-parameterized URLs. They are not used for their content but for the request they generate to a server. The request parameters are used for record-keeping and the response could be used to cookie the user, though this did not happen in this case.

The tracking pixel is delivered via the script inside the <center> tag. It’s contents are shown below.

The script uses the JavaScript document.write function to write some HTML into the page. In this case the HTML is for an invisible image (display: none, height: 0, width: 0) whose URL is that of the tracking pixel, whose unencoded value is the long URL:

As you can see, lots of data getting sent, most likely to record the impression opportunity parameters.

Yahoo! ad delivery script

There are two ways to deliver an ad unit. The preferred way is via a script. If scripting is disabled in the browser, however, Yahoo doesn’t want to lose the ad impression opportunity and so there is the <noscript> option to show the ad in an iframe, probably as an image.

The code for the Yahoo! ad delivery script, which comes from the Yahoo! ad server, is shown below with reformatting and comments from me.

// This sets up AdChoice notice
document.write("<style type=\"text/css\">\n");
// AdChoice image:
document.write(".can_ad_slug {font-family:arial;font-size:11px;color:#999;text-decoration:none;background-image:url(\'\');background-repeat:no-repeat;background-position:right;padding:0px 14px 0px 1px !important;margin:1px 0px 1px 0;cursor:hand;height:12px;display:block;line-height:12px;}\n");
document.write(".ad_slug_table a {text-decoration:none;}\n");
document.write(".ad_slug_table div.CAN_marker { display:none }\n");
document.write("<div class=\"CAN_ad\">\n");
document.write("<table class=\"ad_slug_table\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n");
// Link to click on to learn more
// It will record which ad unit the clicks is for and
// then redirect to
document.write("<tr><td align=\"right\"><a href=\"*\" class=\"CAN_link\" target=\"_blank\"><span class=\"can_ad_slug\">AdChoices</span></a></td></tr>\n");
document.write("<tr><td><!– APT Vendor: Doubleclick –>\n");
// Random number for cache busting
var ord = window.ord || Math.floor(Math.random() * 1e16);
// Google ad delivery script
document.write('<script type="text/javascript" src=";sz=728×90;ord=&#39; + ord + '?"><\/script>');
// If no scripting is available
// Yahoo click tracking (will redirect to Google)
document.write("<!– %SCBT% –><a HREF=\"**;sz=728×90;ord=1366163270.625997?\"><!– %ECBT% –>\n");
// Google ad as a simple image
document.write("<img src=\";sz=728×90;ord=1366163270.625997?\" width=\"728\" height=\"90\" />\n");
document.write("</noscript><!–QYZ 1739617051,3351929051,;;N;96843138;1;–></td></tr>\n");
// Yahoo impression tracking pixel
document.write("</div><img style=\"display:none\" width=0 height=0 alt=\"\" src=\"$TwVA0jc2LjFQGJ6UTYvtUwUSMTczLlFt_0b__70k,st$1366163270583644,si$4453051,sp$96843138,pv$0,v$2.0))&t=D_3&al=(as$12rveflk1,aid$0COQOkwNPfQ-,bi$1739617051,cr$3351929051,ct$25,at$0,eob$-1)\">");

There are several things going on here:

  • AdChoice notice
  • Cache busting
  • Google ad delivery script activation
  • Yahoo impression tracking
  • No script handling

Let’s consider them one at a time.

AdChoice notice

AdChoice came about in 2010 as the online advertising industry’s response to FTC pressure to reign in some poor privacy practices and provide consumers with more transparency and choice when it comes to interest-based advertising, a.k.a., behavioral targeting (BT in adtech parlance).

The AdChoice icon is a triangle with an i in it. Its color can vary. Yahoo!’s is gray (). Next time you see an ad with it, click on the AdChoice notice. You should see information about who targeted the ad at you and get some options to opt-out of interest-based advertising. We started Evidon back in 2009 to bring more transparently to adtech and we helped create AdChoice. Evidon is now the leading independent player in this space.

In the case of the Celebrex ad from our example, the AdChoice icon is tied to a very long URL:*

If you click on the AdChoice icon, Yahoo! will record information about which ad you are selecting to learn more about and then redirect you to the page at the end of the URL, which is the Yahoo learn more about this ad page. The long URL is just for bookkeeping.

BTW, the reason why you don’t see AdChoice notice with Swoop is because Swoop does not do any behavioral targeting at this time. Still, because we want to make it clear that Swoop is serving content, you’ll see our logo on our units.

Cache busting

After the AdChoice notice setup comes a line of script that creates a random number. This is used for cache busting.

A cache-buster is a unique piece of code that prevents a browser from reusing an ad it has already seen and cached, or saved, to a temporary memory file.

Adding a random number to a URL does that nicely.

Google ad delivery script activation

The following script tag loads Google’s ad delivery script from We will look at this later on.

Yahoo impression tracking

Remember how Yahoo already fired one tracking pixel to record the impression opportunity. Well, here, at the end of the script they are going to fire another tracking pixel but this time the purpose will be to record the impression of the Google ad. As before, you can see lots of data being passed.$TwVA0jc2LjFQGJ6UTYvtUwUSMTczLlFt_0b__70k,st$1366163270583644,si$4453051,sp$96843138,pv$0,v$2.0))&t=D_3&al=(as$12rveflk1,aid$0COQOkwNPfQ-,bi$1739617051,cr$3351929051,ct$25,at$0,eob$-1)

Noscript processing & click tracking

As before, in the case that the browser does not have JavaScript enabled, Yahoo doesn’t want to miss the opportunity to deliver an ad, which is why they have the option to display the Google ad as an image.

In that case, Yahoo is also positioned to capture the click and then redirect to Google. This is achieved by wrapping the image (<img>) in a link (<a>). Getting click feedback data would be valuable for Yahoo as it allow is to optimize better. If the unit is sold on a cost-per-click (CPC) basis, then getting click data is a requirement for good record-keeping.

Google/DoubleClick ad delivery script

It’s time for us to take a look at what Google’s ad delivery script does. Alas, the guys at Google don’t want to waste bandwidth so they’ve packed everything into a single unreadable document.write call. You can scroll to the right for a very long time…

document.write('\x3c!– Template Id \x3d 13,901 Template Name \x3d Banner Creative (Flash) – In Page Multiples – [DFA] –\x3e\n\x3c!– Copyright 2006 DoubleClick Inc., All rights reserved. –\x3e\x3cscript src\x3d\x22\x22\x3e\x3c/script\x3e\n\x3cSCRIPT LANGUAGE\x3d\x22JavaScript\x22\x3e\n\x3c!–\nfunction DCFlash(id,pVM){\nvar swf \x3d \x22\x22;\nvar gif \x3d \x22\x22;\nvar minV \x3d 8;\nvar FWH \x3d \x27 width\x3d\x22728\x22 height\x3d\x2290\x22 \x27;\nvar url \x3d escape(\x22\x3dL\x26ai\x3dBkkTr1ABuUYnfKOz56AHh_4HQCbOj0YsDAAAAEAEgADgAUIC6g9b______wFYs4bGy0xgyYb2iISk7A-CARdjYS1wdWItNjc2MDQyMjg4NTEzMDEyMrIBGHd3dy5kY2xrLWRlZmF1bHQtcmVmLmNvbboBCWdmcF9pbWFnZcgBCdoBIGh0dHA6Ly93d3cuZGNsay1kZWZhdWx0LXJlZi5jb20vmAKIpAHAAgLgAgDqAi00Nzg4L2huLnVzLmhtbnloLmRpci54LngueC9DZWxlYnJleF9BcnRocml0aXP4AoHSHpAD4AOYA-ADqAMB4AQBoAYe\x26num\x3d0\x26sig\x3dAOD64_2y2kW7wNSq8iMKhxr0rN1gC3lDFA\x26client\x3dca-pub-6760422885130122\x26adurl\\x3d92295057|266113741|53480227\x22);\nvar wmode \x3d \x22opaque\x22;\nvar bg \x3d \x22same as SWF\x22;\nvar dcallowscriptaccess \x3d \x22never\x22;\n\nvar openWindow \x3d \x22false\x22;\nvar winW \x3d 600;\nvar winH \x3d 400;\nvar winL \x3d 0;\nvar winT \x3d 0;\n\nvar moviePath\x3dswf.substring(0,swf.lastIndexOf(\x22/\x22));\nvar sm\x3dnew Array();\nsm[1] \x3d \x22\x22;\nsm[2] \x3d \x22\x22;\nsm[3] \x3d \x22\x22;\nsm[4] \x3d \x22\x22;\nsm[5] \x3d \x22\x22;\n\nvar ct\x3dnew Array();\nct[0]\x3d\x22\x22;if(ct[0].substr(0,4)!\x3d\x22http\x22){ct[0]\x3d\x22\x22;} \nct[1] \x3d \x22\x3dCLXHAFL\x26o\x3d92295057|266113741|53480227\x22;\nct[2] \x3d \x22\x22;\nct[3] \x3d \x22\x22;\nct[4] \x3d \x22\x3dCLXHAFL\x26o\x3d92295057|266113741|53480227\x22;\nct[5] \x3d \x22\x3dCLXHAFL\x26o\x3d92295057|266113741|53480227\x22;\nct[6] \x3d \x22\x22;\nct[7] \x3d \x22\x22;\nct[8] \x3d \x22\x22;\nct[9] \x3d \x22\x22;\nct[10] \x3d \x22\x22;\n\nvar fv\x3d\x27\x22clickTag\x3d\x27+url+\x27\x26clickTAG\x3d\x27+url+\x27\x26clicktag\x3d\x27+url+\x27\x26moviePath\x3d\x27+moviePath+\x27/\x27+\x27\x26moviepath\x3d\x27+moviePath+\x27/\x27;\nfor(i\x3d1;i\x3csm.length;i++){if(sm[i]!\x3d\x22\x22){fv+\x3d\x22\x26submovie\x22+i+\x22\x3d\x22+escape(sm[i]);}}\nfor(i\x3d1;i\x3cct.length;i++){if(ct[i]!\x3d\x22\x22){if(ct[i].indexOf(\x22http\x22)\x3d\x3d0){x\x3descape(\x22\x3dL\x26ai\x3dBkkTr1ABuUYnfKOz56AHh_4HQCbOj0YsDAAAAEAEgADgAUIC6g9b______wFYs4bGy0xgyYb2iISk7A-CARdjYS1wdWItNjc2MDQyMjg4NTEzMDEyMrIBGHd3dy5kY2xrLWRlZmF1bHQtcmVmLmNvbboBCWdmcF9pbWFnZcgBCdoBIGh0dHA6Ly93d3cuZGNsay1kZWZhdWx0LXJlZi5jb20vmAKIpAHAAgLgAgDqAi00Nzg4L2huLnVzLmhtbnloLmRpci54LngueC9DZWxlYnJleF9BcnRocml0aXP4AoHSHpAD4AOYA-ADqAMB4AQBoAYe\x26num\x3d0\x26sig\x3dAOD64_2y2kW7wNSq8iMKhxr0rN1gC3lDFA\x26client\x3dca-pub-6760422885130122\x26adurl\\x22+ct[i]);}else{x\x3descape(ct[i]);}fv+\x3d\x22\x26clickTag\x22+i+\x22\x3d\x22+x+\x22\x26clickTAG\x22+i+\x22\x3d\x22+x+\x22\x26clicktag\x22+i+\x22\x3d\x22+x;}}\nfv+\x3d\x27\x22\x27;\nvar bgo\x3d(bg\x3d\x3d\x22same as SWF\x22)?\x22\x22:\x27\x3cparam name\x3d\x22bgcolor\x22 value\x3d\x22#\x27+bg+\x27\x22\x3e\x27;\nvar bge\x3d(bg\x3d\x3d\x22same as SWF\x22)?\x22\x22:\x27 bgcolor\x3d\x22#\x27+bg+\x27\x22\x27;\nfunction FSWin(){if((openWindow\x3d\x3d\x22false\x22)\x26\x26(id\x3d\x3d\x22DCF0\x22))alert(\x27openWindow is wrong.\x27);if((openWindow\x3d\x3d\x22center\x22)\x26\x26window.screen){winL\x3dMath.floor((screen.availWidth-winW)/2);winT\x3dMath.floor((screen.availHeight-winH)/2);},id,\x22width\x3d\x22+winW+\x22,height\x3d\x22+winH+\x22,top\x3d\x22+winT+\x22,left\x3d\x22+winL+\x22,status\x3dno,toolbar\x3dno,menubar\x3dno,location\x3dno\x22);}this.FSWin \x3d FSWin;\nua\x3dnavigator.userAgent;\nif(minV\x3c\x3dpVM\x26\x26(openWindow\x3d\x3d\x22false\x22||(ua.indexOf(\x22Mac\x22)\x3c0\x26\x26ua.indexOf(\x22Opera\x22)\x3c0))){\n\tvar adcode\x3d\x27\x3cobject classid\x3d\x22clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\x22 id\x3d\x22\x27+id+\x27\x22\x27+FWH+\x27\x3e\x27+\n\t\t\x27\x3cparam name\x3d\x22movie\x22 value\x3d\x22\x27+swf+\x27\x22\x3e\x3cparam name\x3d\x22flashvars\x22 value\x3d\x27+fv+\x27\x3e\x3cparam name\x3d\x22quality\x22 value\x3d\x22high\x22\x3e\x3cparam name\x3d\x22wmode\x22 value\x3d\x22\x27+wmode+\x27\x22\x3e\x3cparam name\x3d\x22base\x22 value\x3d\x22\x27+swf.substring(0,swf.lastIndexOf(\x22/\x22))+\x27\x22\x3e\x3cPARAM NAME\x3d\x22AllowScriptAccess\x22 VALUE\x3d\x22\x27+dcallowscriptaccess+\x27\x22\x3e\x27+bgo+\n\t\t\x27\x3cembed src\x3d\x22\x27+swf+\x27\x22 flashvars\x3d\x27+fv+bge+FWH+\x27 type\x3d\x22application/x-shockwave-flash\x22 quality\x3d\x22high\x22 swliveconnect\x3d\x22true\x22 wmode\x3d\x22\x27+wmode+\x27\x22 name\x3d\x22\x27+id+\x27\x22 base\x3d\x22\x27+swf.substring(0,swf.lastIndexOf(\x22/\x22))+\x27\x22 AllowScriptAccess\x3d\x22\x27+dcallowscriptaccess+\x27\x22\x3e\x3c/embed\x3e\x3c/object\x3e\x27;\n if((\x27x\x27!\x3d\x22j\x22)\x26\x26(typeof dclkFlashWrite!\x3d\x22undefined\x22)){dclkFlashWrite(adcode);}else{document.write(adcode);}\n}else{\n\tdocument.write(\x27\x3ca target\x3d\x22_blank\x22 href\x3d\x22\x27+unescape(url)+\x27\x22\x3e\x3cimg src\x3d\x22\x27+gif+\x27\x22\x27+FWH+\x27border\x3d\x220\x22 alt\x3d\x22\x22 galleryimg\x3d\x22no\x22\x3e\x3c/a\x3e\x27);\n}}\nvar pVM\x3d0;var DCid\x3d(isNaN(\x22266113741\x22))?\x22DCF2\x22:\x22DCF266113741\x22;\nif(navigator.plugins \x26\x26 navigator.mimeTypes.length){\n var x\x3dnavigator.plugins[\x22Shockwave Flash\x22];if(x \x26\x26 x.description){var pVF\x3dx.description;var y\x3dpVF.indexOf(\x22Flash \x22)+6;pVM\x3dpVF.substring(y,pVF.indexOf(\x22.\x22,y));}}\nelse if (window.ActiveXObject \x26\x26 window.execScript){\n window.execScript(\x27on error resume next\\npVM\x3d2\\ndo\\npVM\x3dpVM+1\\nset swControl \x3d CreateObject(\x22ShockwaveFlash.ShockwaveFlash.\x22\x26pVM)\\nloop while Err \x3d 0\\nOn Error Resume Next\\npVM\x3dpVM-1\\nSub \x27+DCid+\x27_FSCommand(ByVal command, ByVal args)\\nCall \x27+DCid+\x27_DoFSCommand(command, args)\\nEnd Sub\\n\x27,\x22VBScript\x22);}\neval(\x22function \x22+DCid+\x22_DoFSCommand(c,a){if(c\x3d\x3d\x27openWindow\x27)o\x22+DCid+\x22.FSWin();}o\x22+DCid+\x22\x3dnew DCFlash(\x27\x22+DCid+\x22\x27,pVM);\x22);\n//–\x3e\n\x3c/SCRIPT\x3e\n\x3cnoscript\x3e\x3ca target\x3d\x22_blank\x22 href\x3d\x22\x3dL\x26ai\x3dBkkTr1ABuUYnfKOz56AHh_4HQCbOj0YsDAAAAEAEgADgAUIC6g9b______wFYs4bGy0xgyYb2iISk7A-CARdjYS1wdWItNjc2MDQyMjg4NTEzMDEyMrIBGHd3dy5kY2xrLWRlZmF1bHQtcmVmLmNvbboBCWdmcF9pbWFnZcgBCdoBIGh0dHA6Ly93d3cuZGNsay1kZWZhdWx0LXJlZi5jb20vmAKIpAHAAgLgAgDqAi00Nzg4L2huLnVzLmhtbnloLmRpci54LngueC9DZWxlYnJleF9BcnRocml0aXP4AoHSHpAD4AOYA-ADqAMB4AQBoAYe\x26num\x3d0\x26sig\x3dAOD64_2y2kW7wNSq8iMKhxr0rN1gC3lDFA\x26client\x3dca-pub-6760422885130122\x26adurl\\x3d92295057|266113741|53480227\x22\x3e\x3cimg src\x3d\x22\x22 width\x3d\x22728\x22 height\x3d\x2290\x22 border\x3d\x220\x22 alt\x3d\x22\x22 galleryimg\x3d\x22no\x22\x3e\x3c/a\x3e\x3c/noscript\x3e\n\x3cscript type\x3d\x22text/javascript\x22 src\x3d\x22\x3dENT21188\x26am\x3d1\x26mr\x3d1\x26ty\x3djs\x26ep\x3d1\x26at\x3dview\x26rt\x3dbanner\x26st\x3dimage\x26ca\x3dcmp12600\x26cr\x3d53480227\x26pc\x3d92295057\x26r\x3d1028618\x22\x3e\x3c/script\x3e\n\x3cnoscript\x3e\x3cimg src\x3d\x22\x3dENT21188\x26am\x3d1\x26ep\x3d1\x26at\x3dview\x26rt\x3dbanner\x26st\x3dimage\x26ca\x3dcmp12600\x26cr\x3d53480227\x26pc\x3d92295057\x26r\x3d1028618\x22/\x3e\n\x3cimg src\x3d\x22\x3d5092\x26campid\x3dcmp12600\x26placementid\x3d1_92295057\x26creativeid\x3d53480227\x22/\x3e\x3c/noscript\x3e\n\x3cscript Src\x3d\x22\x3d525748\x26cmp\x3d7160975\x26sid\x3d477325\x26plc\x3d92295057\x26num\x3d\x26adid\x3d\x26advid\x3d877848\x26adsrv\x3d1\x26region\x3d30\x26btreg\x3d266113741\x26btadsrv\x3ddoubleclick\x26crt\x3d\x26crtname\x3d\x26chnl\x3d\x26unit\x3d\x26pid\x3d\x26uid\x3d\x26dvtagver\x3d6.1.src\x22 type\x3d\x22text/javascript\x22\x3e\x3c/script\x3e');

Here is what Google is actually trying to write into the HTML page (with my comments added):

<!– Template Id = 13,901 Template Name = Banner Creative (Flash) – In Page Multiples – [DFA] –>
<!– Copyright 2006 DoubleClick Inc., All rights reserved. –>
<!– Utilities for using Flash –>
<script src="">
<!– Script to active Flash ad unit –>
// DoubleClick Flash ad display utility
function DCFlash(id, pVM) {
// Note: is a DoubleClick domain
// Flash creative for ad
var swf = ";;
// Unbranded (no Celebrex) Pfizer image
var gif = ";;
var minV = 8;
var FWH = ' width="728" height="90" ';
// Target URL for non-Flash mode (with Google click tracking redirection)
// Actual target URL is|266113741|53480227
var url = escape("…cs%3D%3f|266113741|53480227");
var wmode = "opaque";
var bg = "same as SWF";
var dcallowscriptaccess = "never";
var openWindow = "false";
var winW = 600;
var winH = 400;
var winL = 0;
var winT = 0;
var moviePath = swf.substring(0, swf.lastIndexOf("/"));
var sm = new Array();
sm[1] = "";
sm[2] = "";
sm[3] = "";
sm[4] = "";
sm[5] = "";
var ct = new Array();
ct[0] = "";
if (ct[0].substr(0, 4) != "http") {
ct[0] = "";
// Different content targets for users to take action against
ct[1] = "|266113741|53480227";
ct[2] = ";;
ct[3] = ";;
ct[4] = "|266113741|53480227";
ct[5] = "|266113741|53480227";
ct[6] = "";
ct[7] = "";
ct[8] = "";
ct[9] = "";
ct[10] = "";
var fv = '"clickTag=' + url + '&clickTAG=' + url + '&clicktag=' + url + '&moviePath=' + moviePath + '/' + '&moviepath=' + moviePath + '/';
for (i = 1; i < sm.length; i++) {
if (sm[i] != "") {
fv += "&submovie" + i + "=" + escape(sm[i]);
for (i = 1; i < ct.length; i++) {
if (ct[i] != "") {
if (ct[i].indexOf("http") == 0) {
// Click tracking redirect
x = escape("…B3-0%3B0%3B92295057%3B3454-728/90%3B53480227/53398896/1%3B%3B%7Esscs%3D%3f&quot; + ct[i]);
} else {
x = escape(ct[i]);
fv += "&clickTag" + i + "=" + x + "&clickTAG" + i + "=" + x + "&clicktag" + i + "=" + x;
fv += '"';
var bgo = (bg == "same as SWF") ? "" : '<param name="bgcolor" value="#' + bg + '">';
var bge = (bg == "same as SWF") ? "" : ' bgcolor="#' + bg + '"';
function FSWin() {
if ((openWindow == "false") && (id == "DCF0")) alert('openWindow is wrong.');
if ((openWindow == "center") && window.screen) {
winL = Math.floor((screen.availWidth winW) / 2);
winT = Math.floor((screen.availHeight winH) / 2);
}, id, "width=" + winW + ",height=" + winH + ",top=" + winT + ",left=" + winL + ",status=no,toolbar=no,menubar=no,location=no");
this.FSWin = FSWin;
ua = navigator.userAgent;
if (minV <= pVM && (openWindow == "false" || (ua.indexOf("Mac") < 0 && ua.indexOf("Opera") < 0))) {
// Preparing to instantiate Flash player
var adcode = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="' + id + '"' + FWH + '>' +
'<param name="movie" value="' + swf + '"><param name="flashvars" value=' + fv + '><param name="quality" value="high"><param name="wmode" value="' + wmode + '"><param name="base" value="' + swf.substring(0, swf.lastIndexOf("/")) + '"><PARAM NAME="AllowScriptAccess" VALUE="' + dcallowscriptaccess + '">' + bgo +
'<embed src="' + swf + '" flashvars=' + fv + bge + FWH + ' type="application/x-shockwave-flash" quality="high" swliveconnect="true" wmode="' + wmode + '" name="' + id + '" base="' + swf.substring(0, swf.lastIndexOf("/")) + '" AllowScriptAccess="' + dcallowscriptaccess + '"><\/embed><\/object>';
if (('x' != "j") && (typeof dclkFlashWrite != "undefined")) {
// If DoubleClick code is available, activate Flash through it
} else {
// Otherwise, just write out the Flash object
} else {
// Can't use Flash, use an image instead
document.write('<a target="_blank" href="' + unescape(url) + '"><img src="' + gif + '"' + FWH + 'border="0" alt="" galleryimg="no"><\/a>');
var pVM = 0;
var DCid = (isNaN("266113741")) ? "DCF2" : "DCF266113741";
// Kick it all off using a bunch of browser-specific processing
if (navigator.plugins && navigator.mimeTypes.length) {
var x = navigator.plugins["Shockwave Flash"];
if (x && x.description) {
var pVF = x.description;
var y = pVF.indexOf("Flash ") + 6;
pVM = pVF.substring(y, pVF.indexOf(".", y));
} else if (window.ActiveXObject && window.execScript) {
window.execScript('on error resume next\npVM=2\ndo\npVM=pVM+1\nset swControl = CreateObject("ShockwaveFlash.ShockwaveFlash."&pVM)\nloop while Err = 0\nOn Error Resume Next\npVM=pVM-1\nSub ' + DCid + '_FSCommand(ByVal command, ByVal args)\nCall ' + DCid + '_DoFSCommand(command, args)\nEnd Sub\n', "VBScript");
eval("function " + DCid + "_DoFSCommand(c,a){if(c=='openWindow')o" + DCid + ".FSWin();}o" + DCid + "=new DCFlash('" + DCid + "',pVM);");
<!– Can't use Flash ad; use an image instead –>
<a target="_blank" href="…cs%3D%3f|266113741|53480227">
<img src="" width="728" height="90" border="0" alt="" galleryimg="no">
<!– Ad delivery verification & analytics –>
<!– This is Nielsen't NetRatings product –>
<!– The script will load Facebook brand life tracking behind the scenes –>
<!– It will also load AdSafe –>
<script type="text/javascript" src="">
<!– In the noscript case, run NetRatings & AdSafe but no Facebook –>
<img src=""/>
<img src=""/>
<!– DoubleVerify viewability verification–>
<script Src="…1&btadsrv=doubleclick&crt=&crtname=&chnl=&unit=&pid=&uid=&dvtagver=6.1.src" type="text/javascript">

Don’t worry about the volume of code. There are basically two things going on here: delivering a Flash ad and lots of third party ad verification.

Delivering a Flash ad

Flash ads are richer and more interactive but there are browsers where Flash ads don’t do so well. The first part of the Google/DoubleClick ad delivery script is about carefully determining whether a Flash ad unit can be used and falling back to images otherwise. As before, all clicks are tracked via redirects.

Third party  verification

We saw Yahoo! attempting to fire three types of tracking pixels: (a) for impression opportunities, (b) for actual impressions and, in the case of no scripting, (c) for clicks. This is to help optimize the performance of Yahoo!’s ad network. This is first party verification. Google/DoubleClick does the same with its own systems.

Third party verification happens when the advertiser asks the delivery network, in this case Google/DoubleClick, to include additional verification tags (scripts) to prove that the campaign is delivered based on its configured parameters.

In the case of this Celebrex campaign, Pfizer is using four separate verification vendors. At the top level we have only Nielsen NetRatings and DoubleVerify, however NetRatings’s script loads AdSafe as well as Facebook in the pattern we are familiar with: a script that writes out <script> tags to load more scripts.

Putting it all together

Let’s try to piece together the requests that allow this one single ad unit for Celebrex to appear:

  • Yahoo ad unit delivery script
    • Google ad delivery script
      • Flash movie
        • ??? (not easy to track Flash traffic)
      • Nielsen NetRatings tracking script
        • AdSafe pixel
        • Facebook iframe
          • Facebook tracking
            • ??? (did not analyze)
      • DoubleVerify script
        • Tracking script (like a pixel)
    • Yahoo impression tracker
      • Tracking pixel
  • Yahoo impression opportunity tracker
    • Tracking pixel

All in all, 13 separate HTTP requests to 6 separate companies, not counting redirects and cacheable scripts. With this much complexity and independent parties doing their own accounting, it’s no surprise the display advertising value chain is in a bit of a mess right now.

About Simeon Simeonov

Entrepreneur. Investor. Trusted advisor.
This entry was posted in Advertising, Swoop and tagged , , , , , , , , . Bookmark the permalink.

1 Response to Anatomy of an online ad

  1. Pingback: Managing Startups: Best Blog Posts of 2013 |

Leave a Reply