Aug 7, 2019 8 min read

OpenRTB (ORTB) Explained

OpenRTB (ORTB) Explained

Did you know that every time you load a web page, you are initiating dozens of auctions, for actual real-life money? Yes, that’s right — you are the impetus of a beautifully choreographed dance of technology and auction dynamics.

Many of the display and video ads you see online are the result of many different companies bidding for the right to display their ad to you. The framework in place to facilitate the auction is called OpenRTB or ORTB, which are both short for Open Real Time Bidding.  

ORTB, like VAST, is a standard that was created by the IAB for the purpose of creating a universal language that all entities participating in an auction can speak in order to conduct business. Auctions are the backbone of programmatic advertising and ensure that publishers are earning the highest possible price for their ad space.

Entire books have been written on the subject of auction dynamics, so if you are interested in that, go read one of those. The purpose of this article is to break down ORTB technically and explain how it is used to actually conduct an auction in programmatic advertising.

In order to understand ORTB, you will first have to understand the different ad tech entities involved in the auction process. In its most simple form, an auction involves two sides - the supply side and the demand side. On the supply side you have the SSP and on the demand side the DSP. I’m going to explain each in the most basic way possible below:

Supply side platform or SSP

Used by publishers in order to manage their programmatic inventory.  They use the platform to package and sell their inventory to advertisers.

Demand Side Platform or DSP

Used by advertisers to buy programmatic inventory. They use the platform to manage creatives, target ads and report on delivery.

Even though both of the descriptions above are gross oversimplifications, they give you enough context to explain ORTB.  

Like the two entities (SSP & DSP) communicating via ORTB, the specification details both sides in the form of a “bid request” and “bid response”. Notice the word “bid”? Remember, this is an auction after all.

The SSP is asking for a bid (bid request) and the DSP will hopefully respond with a bid (bid response). Both bid request and bid response are formatted in JSON (Javascript Object Notation) which is a lightweight format used to transport data. JSON is to ORTB as XML is to VAST.  

Do not be intimated by JSON, it can look intimidating, but just like XML it can be easily decoded with the human eye. Both bid request and response consist of “objects”, “attributes” and values of those two items. Let’s take a quick look at a sample bid request:

{ 
"id":"1234567893",
   "at":2,
   "tmax":120,
   "imp":[
      {
         "id":"1",
         "bidfloor":5,
         "video":{
            "w":640,
            "h":480,
            "pos":1,
            "startdelay":0,
            "minduration":5,
            "maxduration":30,
            "maxextended":30,
            "minbitrate":300,
            "maxbitrate":1500,
            "api":[
               1,
               2
            ],
            "protocols":[
               2,
               3
            ],
            "mimes":[
               "video/x-flv",
               "video/mp4",
               "application/x-shockwave-flash",
               "application/javascript"
            ],
            "linearity":1,
            "boxingallowed":1,
            "playbackmethod":[
               1,
               3
            ],
            "delivery":[
               2
            ],
            "battr":[
               13,
               14
            ],
            "companionad":[
               {
                  "id":"1234567893-1",
                  "w":300,
                  "h":250,
                  "pos":1,
                  "battr":[
                     13,
                     14
                  ],
                  "expdir":[
                     2,
                     4
                  ]
               },
               {

               }
            ],
            "companiontype":[
               1,
               2
            ]
         }
      }
   ],
   "site":{
      "id":"1345135123",
      "name":"Site ABCD",
      "domain":"siteabcd.com",
      "cat":[
         "IAB2-1",
         "IAB2-2"
      ],
      "page":"http://siteabcd.com/page.htm",
      "ref":"http://referringsite.com/referringpage.htm",
      "privacypolicy":1,
      "publisher":{
         "id":"pub12345",
         "name":"Publisher A"
      },
      "content":{
         "id":"1234567",
         "id":"1234567893-2",
         "w":728,
         "h":90,
         "pos":1,
         "battr":[
            13,
            14
         ],
         "series":"All About Cars",
         "season":"2",
         "episode":23,
         "title":"Car Show",
         "cat":[
            "IAB2-2"
         ],
         "keywords":"keyword-a,keyword-b,keyword-c"
      }
   },
   "device":{
      "ip":"64.124.253.1",
      "ua":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16",
      "os":"OS X",
      "flashver":"10.1",
      "js":1
   },
   "user":{
      "id":"456789876567897654678987656789",
      "buyeruid":"545678765467876567898765678987654",
      "data":[
         {
            "id":"6",
            "name":"Data Provider 1",
            "segment":[
               {
                  "id":"12341318394918",
                  "name":"auto intenders"
               },
               {
                  "id":"1234131839491234",
                  "name":"auto enthusiasts"
               }
            ]
         }
      ]
   }
}


Woah! There’s a lot going on here and I know what you are probably thinking — this looks like code and I am frightened! Fear not, Ad Tech pupil, because If we start to break down this bid request into its atomic parts, it makes much more sense.

Let’s first talk about how the bid request is organized. Everything is hierarchical, meaning there are objects within objects. An example of this would be how the “publisher” and :”content” objects are nested within the “site” object. You can tell it’s nested because both the “publisher” and “content” object are within the “site” object’s curly brackets “{“,”}”. The curly bracket for “site” does not close until after both the “publisher” and “content” brackets. You can also see that both “publisher” and “content” have their own curly brackets but there are no curly brackets within each — meaning there are no nested objects within these sub-objects.  

You might notice that there are square brackets “[“, “]” within the “publisher” and “site” sub-objects. These characters are used to signify what’s called an “array”. An array is simply a list of items. This list can contain integers, strings (words) or a boolean (true / false or 1/0). To make things more confusing, you can also have an array that contains multiple objects.  

You can see the “imp” (impression) object near the top is started off with an opening square bracket “[“ which signifies that this is the first impression object (since ORTB allows you to offer up multiple impression objects in a bid request). This is called a consolidated bid request and you can follow the link to learn more about that.

Luckily, our example only contains one impression object so no need to dive into that right now.  

The impression object is used to offer a potential impression to all competing DSPs. SSPs send out the same bid request to all DSPs participating in the auction. The impression object contains all the information that a DSP needs in order to decide if it’s going to bid on the opportunity. You can see that our example impression is for video since there is a nested “video” object.

If we look through the attributes within the video object you can ascertain that this particular video impression will render in a 640 x 480 pixel player since the “w” (width) attribute is 640 and the “h” (height) attribute is 480. You can also see that the publisher will not accept any ads shorter than five seconds ("minduration": 5) or longer than thirty seconds "maxduration": 30.

The video attributes describe information about the video environment, but DSPs can also learn other information about the publisher, site, device and user making the ad request by parsing through those eponymously named objects.  

I will not go through each field in this bid request, but you can see that it is very easy to glean all the information the SSP is sharing about the opportunity by simply looking at the attribute and its associated value. If you are interested in learning the meaning of each object and attribute, check out the OpenRTB 2.5 spec.  

One of the most important fields within the entire bid request is “bidfloor”.The bid floor is the lowest amount that a publisher will accept for this particular opportunity. In our example, you can see that it is $5 CPM. This means that the bid price returned in any bid response must be $5 or above or the SSP will toss out the bid.  

Once a DSP decides that they would like to bid on an opportunity, they will respond back to the SSP with a “bid response” which is very similar to the bid request except that it contains all the information that a DSP needs to provide in order to compete in the auction.

Check out the example below:

{
   "id":"123",
   "seatbid":[
      {
         "bid":[
            {
               "id":"12345",
               "impid":"2",
               "price":5.00,
               "nurl":"http://example.com/winnoticeurl",
               "adm":"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<VAST version=\"2.0\">\n<Ad id=\"12345\">\n<InLine>\n<AdSystem version=\"1.0\">SpotXchange</AdSystem>\n<AdTitle>\n <![CDATA[Sample VAST]]>\n</AdTitle>\n<Impression>http://sample.com</Impression>\n<Description>\n<![C DATA[A sample VAST feed]]>\n</Description>\n <Creatives>\n<Creative sequence=\"1\" id=\"1\">\n<Linear>\n<Duration>00:00:30</Duration>\n  <TrackingEvents> </TrackingEvents>\n<VideoClicks>\n<ClickThrough>\n<![CDATA[http://sample.com/openrtb test]]>\n</ClickThrough>\n</VideoClicks>\n<MediaFiles>\n<MediaFile delivery=\"progressive\" bitrate=\"256\" width=\"640\" height=\"480\" type=\"video/mp4\">\n<![CDATA[http://sample.com/video.mp4]]>\n </MediaFile>\n</MediaFiles>\n</Linear>\n </Creative>\n</Creatives>\n</InLine>\n</Ad>\n</VAST>"
            }
         ]
      }
   ]
}


Metadata within the bid response is used to conduct the auction and also honor any rules the publisher may have in place to control which ads and buyers can participate. For example, a publisher may want to block all automotive ads or just ads from Toyota. The publisher’s SSP can honor these blocks by parsing the “adomain” and “cat” fields.

“Adomain” stands for “advertiser domain” and should point to the advertiser’s corporate site, which would be “toyota.com” if it was a Toyota ad. The “cat” field will contain an IAB category code that most closely describes the ad’s content. For our theoretical example, the IAB category code would be "IAB2-1" and "IAB2-2" which are the category codes for "Auto Parts" and "Auto Repair".  

Once again, I will not describe all the fields in the bid response, these too can be found in the ORTB spec. However, the most important field here is bid price. This is the CPM dollar amount the advertiser is willing to pay for this opportunity and is the rate at which a bid will be competed with other bids.  

There are two main types of ORTB auctions, first-price and second-price auctions.

First-price auction

Will take the highest bid and that is the price that the advertiser pays.

Second-price auction

Will take the highest bid, then lower it to either at the second highest bid’s rate or a penny above it (this varies by SSP) and that is the price the advertiser will pay.

So for a second price auction where there are two bids — one at $5 and another at $6, the $6 bid will win but the advertiser will only pay $5.01.  

So let’s assume our example bid above won the SSP’s auction. What happen’s next? How does the ad get delivered and actually played back? That’s where the “adm” field comes into play. This field stands for “ad markup”, and typically contains VAST XML for video impressions.  

I wrote an entire post on VAST that explains this IAB standard in detail, which you should definitely read if you do not know what VAST is. If you are too lazy to read that, then understand that VAST contains all the information required by a video player to playback an ad and also notify all interested parties about various metrics and events that occurred (impression, complete, etc).  

If a bid wins, the SSP will take the VAST in the "adm" field and deliver it to the publisher for playback (typically adding in extra tracking beacons in order to inform the SSP about various events occurring so they can track independently. Once again, if this doesn’t make sense to you then read my VAST post.

There are variations of delivering ad markup that includes returning markup in a separate response only after an SSP notifies a DSP that they won, but using the “adm” field is the most typical.  

The entire transaction is “complete” after the ad is played back on the publisher’s property and the various tracking beacons are called to inform all parties that the ad impressed. The transaction is recorded along with pricing information by the SSP and DSP so each entity knows what it is owed and how much it owes respectively.  

The basics of ORTB are simple to understand and what was described above is enough for most people to get by in the ad tech world. There are of course many more details and tangents one could explore but going into that level of fine-grain detail usually is only necessary for the product managers, engineers and integration teams. If there are certain aspects of ORTB you want to know more about, drop me a line and we can talk about it or you can inspire a future post exploring the subject!

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ad Tech Explained.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.