The Hivestack Developer Hub

Welcome to the Hivestack developer hub. You'll find comprehensive guides and documentation to help you start working with Hivestack as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    Documentation and Guides

1 Terminology

Term Description:

  • Media owner - The owner of the player which ultimately plays the ad.
  • Player - A unit, with one or multiple screens, which plays digital ads.
  • Product - A media owner may classify their players into “products”. For example all players in malls may be part of a “Mall” product.

2 Goals

The goal of this document is to identify challenges through which a buyer (an advertiser or agency) may use a DSP in order to target and buy ads to be played on a digital signboard and to flesh out the solutions and processes needed to overcome these challenges.

The process tries to leverage as much of the existing OpenRTB 2.5 specification, with as little extensions or modifications as possible.

3 Additional reading

OpenRTB API Specification Version 2.5 Terminology from the OpenRTB Api documentation is used extensively in this document. It can be found at

4 Scenarios

Two scenarios are considered in this document: open bidding and pre-approved campaigns.

Open bidding
“Open bidding” is the process in which a media owner can send a bid request in order to fill in an open spot in a player’s schedule (or perhaps even all spots) and all (or selected) buyers can bid for the spot through a DSP and provide the content of the ad.

Pre-approved campaigns
“Pre-approved campaigns” is the process where advertiser or agency and a media owner have an agreement to play an ad in a predetermined schedule. The media owner can then use the advertiser or agency’s DSP to retrieve the creative and report impressions, with the link being made through a Deal ID.

5 Challenges

5.1 Audience targeting

The OpenRTB standard was created for a process in which an ad would be served to an audience consisting of a single person. This meant that the focus of targeting information was placed on the device, the app or site displaying the ad and the single person viewing the ad. But our case results in many people viewing the ad.


  • The current OpenRTB standards provide targeting information for a single person.
  • We need a demographic breakdown of the audience viewing the ad.

The Imp object has been given an extension (called ImpExt ) which contains extra information about the audience of the player, including the total number of viewers and a demographic breakdown.

In order to correctly target ads and ensure correct billing, support for this extension is required.

Additionally, the Bid object now has a BidExt extension which adds the “targetdemo” field where the bidder can specify the targeted demographics in order to receive a count of the targeted audience for reporting purposes.

5.2 Impression reporting/billing notification delays

One of the challenges of serving ads on a digital billboard is the distribution of the creative to the player. Players may have slow, unreliable, restricted or even no direct access to the Internet and cannot tolerate awkward pauses or stutter. This means that creatives often have to be pre-loaded by the players, sometimes quite in advance. This can cause a substantial delay between accepting a bid and actually playing the creative. This, in turn, delays the reporting of the impression for billing purposes.

Additionally, these restrictions may prevent a player from directly reporting an impression, which can cause further delays as other processes channel the impression report to it’s final destination.


  • Smooth Internet connectivity, or any connectivity, cannot be guaranteed.
  • The creative must often be retrieved in advance, which means the bid request must be done in advance.
  • There may be further delays in reporting impressions if the player cannot do so directly.

The solution to this problem is twofold: The ImpExt extension of the Imp object contains the “playwindow” and “impconfirmdelay” fields that provide the time window in which the creative
of the winning bid is expected to play and the maximum delay between the creative being played and the impression being reported.

Additionally, the “exp” field of the Imp object (added in OpenRTB 2.4) will contain the combined time of both fields and can be used in a more standard (if less informative) manner.

5.3 Restrictions on impression reporting methods

The OpenRTB standard itself does not specify exactly how a successful impression should be reported. While the VAST protocol, which features an impression reporting URL, is widely used in video, there is no such simple solution for still images. The most popular methods for impression reporting of still images is to send a creative consisting of markup language with either embedded JavaScript which makes the impression call or an invisible image whose loading signals the successful impression. The main problem with this method is not only the previously possible lack of Internet connectivity, but communication restrictions that could be placed on a player for security purposes.


  • The internet connectivity of a player may be lacking, restricted or simply non-existent
  • The most popular method if reporting impressions for a still image is to embed the image in some HTML markup with some JavaScript code tasked with calling an impression reporting URL or with an invisible tracking pixel.
  • How can we report an impression if the JavaScript cannot call an external URL or the invisible tracking pixel cannot be loaded?

The Bid object has received an extension called BidExt which contains the “impurls” field. If specified, the URL will be called by the media owner once the creative has played. This also frees up the win notice URL to directly serve an image or video rather than going through HTML markup.

If a creative is served through a VAST document, the impression URL found there will also be used. But the actuals audience numbers cannot be sent to this URL as applying substitution macros to VAST reporting URLs is not standard behavior. So it is recommended to always use the “impurls” field.

5.4 Retrieving external resources

An ad may consist of HTML markup to be displayed. This HTML markup will usually use external resources, such as images. Once again, the possibly limited or non-existent Internet connectivity of a player may preclude the fetching of such resources.

Also, the delay in loading these resources may be unacceptable once comes the time to display the ad. For example, we would not want to display a progressively loading image on the screen because the player could only know it has to load it once it tried displaying the markup!


  • HTML markup will normally reference external sources.
  • Such external resources may be unavailable due to restricted Internet access.
  • It is mostly impossible to guarantee that a player can figure out all the resources needed a piece of HTML markup, in order to pre-load them, before it tries to render the markup.

There is unfortunately no satisfactory solution to this problem. The most obvious solution is to use an image or video directly as the creative rather than using HTML markup. Most reasons why HTML markup is often used (such as impression reporting) are handled by other solutions found in this section.

Note that these problems may not apply to all players, so it is possible to ignore this problem if a buyer is targeting a media owner that it knows can successfully handle their HTML markup content.

5.5 Reporting audience numbers when reporting impressions

Normally, calling an impression/billing reporting URL indicates that a single person has viewed the ad. But an ad playing on a digital billboard can be viewed by multiple people and this number must somehow be reported.


  • Calling an impression/billing reporting URL normally signals a single view.
  • When a creative is played by a digital billboard, it will be seen by multiple people.
  • We must somehow report that number to the DSP for correct impression counting and billing.

Three substitution macros will be added to help in reporting these numbers. The following macros can be applied to the URL of the “impurls” field of the ImpExt object. Also these macros can be applied to the HTML markup, but not to the win notice URL (as these numbers are not yet known when the URL is called).

Macro Value:

  • ${TOTAL_IMP} - The total audience count when the ad was played.
  • ${TARGET_IMP} - The total targeted audience count when the ad was played.
  • ${TOTAL_PRICE} - The total price to bill. This is calculated according to the winning price and the total audience number.

6 Use of the OpenRTB API

This section of the document describes how the OpenRTB standard is used and extended in order to successfully go through the process of allowing buyers to target players to play their ads.

The workflow itself has not changed: when an ad is needed, a request is made, the bids are tallied, the winner is immediately notified using the win notice URL and the creative is retrieved to be played.

In addition to the extensions mentioned in the “Challenges” section, a few useful fields have been added in order to help with targeting by exposing new information such as the audio capabilities of a player or the kind of location it is in.


\*No specific value, the “Notes” column contains more information.
[...]An array of values or objects.
{...}A sub-object.
_Empty_Omitted or empty value.

6.1 Request format

The requests sent by Hivestack simulates a fullscreen ad. Each call is made for a single campaign each time it needs content to play. Support for multiple campaigns in a single request may be considered in the future in order to minimize the number of requests.

The request will typically be made in advance so that the content of the ad can be fully retrieved before the ad is planned to play.

Fields that are not specified here will be omitted in the actual request.

6.1.1 BidRequest

id\*A unique ID in the form of a GUID.
imp[...]An array containing a single Imp object.

Multiple **Imp** objects may be supported in the future.
app{...}An **App** object.
device{...}A **Device** object.
test0 / 10 – Normal billable campaign
1 – Non-billable test campaign
at1 / 2 / 38525121 – First Price
2 – Second Price
3852512 – Pre-approved campaigns only
wseat[...] / empty
cur[...] / emptyMay be empty if the request is for a pre-approved deal.
wlang[...] / empty
bcat[...] / empty
badv[...] / empty

6.1.2 Imp

id\*A unique(within the request) sequential number.
banner{...} / emptyA Banner instance offering information for still image content.

If the media owner/player does not support still images, this attribute will be omitted.
video{...} / emptyA Video instance offering information for video, flash or HTML content.

If the media owner/player does not support video content, this attribute will be omitted.
displaymanager\*A unique identifier for the media owner. Can be used by the DSP to customize the response.
displaymanagerver\* / emptyA version number provided by the media owner. This field may be empty. Can be used to customize the response.
tagid\* / emptyMay contain a debugging value.
pmp{...} / emptyA Pmp instance describing any marketplaces deals in effect.
exp\*The total, converted to seconds, of the “playwindow” and “impconfirmdelay” fields of the ImpExt object. (Included for compatibility with OpenRTB 2.4+)
ext{...}An ImpExt instance

6.1.3 ImpExt (Extension)

playwindow\*integerThe time window in which the ad is supposed to play following a winning bid. If the media owner cannot play the ad within this time window, the ad will not play and no impression/billing confirmation will be sent.
impconfirmdelay\*integerThe maximum time, in minutes it may take to call the impression/billing confirmation URL once the creative has played.
totalaud\*floatThe total number of viewers in the audience.
audbreakdown[...]arrayAn array of Audience objects. This is the breakdown of the audience into different demographic groups.
dataprovider* / emptyintegerAn optional code indicating the source of the audience information.

0 – Other or not specified
1 – Publisher’s own research
10 – GeoPath
11 – Nielsen
12 – Quividi

6.1.4 Audience (Extension)

demo[...]array of stringsList of demographic categories of this slice of the audience. Each entry contains a string code describing the demographic. If the array contains multiple entries, they all apply (ex: Male and aged 16-21)

See Appendix B for a description of these codes.
aud\*floatA value between 0.0 and 1.0 representing the fraction of the total audience that correspond to all the demographic categories in the “demographics” field.

6.1.5 Banner

w\*Width, in pixels, of the player’s screen.
h\*Height, in pixels, of the player’s screen.
id\*Identical to the id attribute of the parent Imp object.
mimes[...]List of formats supported by the media owner.

6.1.6 Video

mimes[...]List of formats supported by the media owner.
protocols[...] / empty This value depends on the support offered by the media owner. If empty, the video should be served directly through the response of the win notice URL.
w\*Width, in pixels, of the player’s screen.
h\*Height, in pixels, of the player’s screen.
start delay0Not applicable in this case
sequence\*Identical to the id attribute of the parent Imp object.
minbitrate\* / empty
maxbitrate\* / empty
ext{...} A VideoExt instance

6.1.7 VideoExt (Extension)

audio\*0 – No sound
1 – Sound available
2 – Sound required

6.1.8 Pmp

private_auction0 / 1Always “1” for pre-approved campaigns.
deals[...]An array containing a one or more Deal instances.

6.1.9 Deal

id\*A friendly string identifying the deal.
bidfloor\*Minimum bid for the play, expressed in CPM. In the case of pre-approved campaigns, this amount will always be 0.
bidfloorcur\*Currency used for the minimum bid amount. Typically, “USD”.
at1 / 2 / 3852512The auction type, as described in the OpenRTB standard. For pre-approved campaigns, the value will be “3852512”.

This field is unlikely to be used.
wseat[...] / emptyWhitelist of seats allowed to bid for this deal.
wadomain[...] / emptyWhitelist of advertiser domains that are allowed to bid for this deal.

6.1.10 App

id \* / emptyAn optional unique ID representing the media owner’s product.
name\* / emptyAn optional name for the media owner’s product.
domain\* / emptyAn optional domain for the media owner’s product.
publisher{...}A Publisher object.

6.1.11 Publisher

id\*A unique ID representing the media owner.
name\*Name of the media owner.
domain\*Domain of the media owner.

6.1.12 Device

ua\* / emptyIf the media owner/player supports HTML ads, it may report the user agent string of the internal engine it uses.
geo{...} / emptyA Geo instance. May be omitted if the location is unknown.
h\* / emptyPhysical height of the screen in pixels. Omitted if unknown.
w\* / emptyPhysical width of the screen in pixels. Omitted if unknown.
ppi\* / emptyScreen size as pixels per linear inch. Omitted if unknown.
pxratio1Very unlikely to be any other number.
js0 / 1Support for JavaScript.

Use of JavaScript is not recommended.
flashverVersion of Flash supported by the media owner/player.

Omitted if Flash is either not supported or the media owner cannot guarantee the support of a specific version.
ext{...}A DeviceExt instance.

6.1.13 DeviceExt (Extension)

mediatype\* / emptyintegerA numeric code describing the general type of location the ad would play. Omitted if unknown or no code applies.

See appendix A for accepted values.

6.1.14 Geo

type3Provided by the media owner.
metro\* / empty

6.2 Expected bid response

The bid response from the DSP.

If the response does not include any bids, an error code is included in the response or the server returns a 40x/50x response, the Hivestack system will try again up to five times. If it does not receive a successful bid by then, it will assume that there is no content to play (if there are no bids) or there is a problem with the DSP (in case of an error).

Values that are not needed by Hivestack will be ignored. The “expected value” column simply represents what would normally be expected in this scenario. Omitting a field or sending a value different from the “expected value” will not trigger an error or rejection of the response unless marked as mandatory in the OpenRTB specification or if specified otherwise in the “notes” column.

6.2.1 BidResponse

AttributeExpected ValueNotes
id\*ID of the bid request (as normal)
bidid\*Any string. Will be saved for logging/tracking purposes.
customdataemptyNot currently supported.
extemptyNo extensions have currently been agreed upon. Any value will be ignored.

6.2.2 BidSeat

AttributeExpected ValueNotes
bid[...]As in the OpenRTB standard, the bid is in CPM. With the final price being determined by the total number of impressions (not targeted impressions) when the ad is played.
extemptyNo extensions have currently been agreed upon. Any value will be ignored.

6.2.3 Bid

AttributeExpected ValueNotes
adidemptyPreloaded ads are not supported. This field can be used as a fallback for creative approval and caching if crid is not available, but use of the crid field is preferred.
nurl\*The “${TOTAL_IMP}”, “${TARGET_IMP}” and “${TOTAL_PRICE}” substitutions macros cannot be used in this URL as the actual impression audience numbers are not known yet.
iurlemptyAny value in this field will be ignored.
cidemptyAny value in this field will be ignored.
crid*A unique identifier for the creative. Used for creative approval and caching. If this field is not specified, the adid will be used as a fallback, but use of this field is preffered.
attr[...] / emptyAny values will be ignored.
ext{...}A BidExt object. This is optional and can be omitted, but it’s use is highly recommended.

6.2.4 BidExt (Extension)

AttributeExpected ValueTypeNotes
impurl\* string (URL) This field has been deprecated in favour of the "impurls" field.
impurls\* array of strings (URLs) A list of URLs to call to submit an impression when the creative is played, thus confirming the billing of the play.

Can be used as an alternative in cases where there is no other way to submit such a URL. For example, in cases where the win notice URL directly returns the creative.

Substitution macros can be used in the URL. Including the “${TOTAL_IMP}”, “${TARGET_IMP}” and “${TOTAL_PRICE}” macros.

This parameter is optional.
targetdemo[...]array of stringsThe list of targeted demographics. This list will be used to calculate the number of targeted impressions (for the “${TARGET_IMP}” substitution macro).

Each entry in the array is a string with the code of the targeted demographic. As long as person is included in at least one of the values for each demographic type specified, then they are considered part of the target.

For example, the ["GNDR-M", "AGE-15-17", "AGE-18-24"] array will target males which are also in either the 15-17 or 18-24 age ranges.

Use of a code not present in the “audbreakdown” field of the ImpExt object will cause the bid to be rejected.

If this field is omitted, or the whole BidExt object is omitted, the Hivestack will assume that no demographic is specifically targeted.

Appendix A. Media Type


Appendix B. Demographic codes

Because media owners may organise their demographic categories differently, the demographic code system was designed to be as flexible as possible. The codes are designed such that they completely describe the demographic without referring to a common table, being overly long or hard to parse.

There two kinds of demographics: value ranges and discrete values.

Values ranges represent demographics that cover a part of a spectrum of values, such as age and household income. Values ranges use the following format: “[type]-[min]-[max]”. Either or both the “min” or “max” parts can be replaced with “*” in order to signify that there is no minimum or maximum. Also, in order to shorten the numbers, the “K”, “M” and “B” suffixes can be used for thousands, millions and billions. See below for a list of types and examples.

Discrete values represent demographics that have discrete possible values, such as gender. Each value can be a number or a code. The following format is used: “[type]-[value]”. If the value is numeric, the “<” (ex: “ABC-<10”) or “+” (ex: “ABC-10+”) characters to indicates that lower or higher values are also included. The “*” character can also be used as placeholder for all possible values. See below for a list of types and examples.

Currently supported demographic types

Note: The demographic codes presented here are the recommended defaults. A supplier may use custom codes to better fit their demographic data. If you are receiving unexpected codes, please contact Hivestack support.


The age demographic uses the “AGE” type code and are made of ranges in which both the
minimum and maximum are included.


All agesAGE-\*-\*
18 to 24 years oldAGE-18-24
65 or olderAGE-65-\*

Household income

The household income demographic uses the “HHI” type code and are made of ranges in which the minimum is included and maximum is excluded. The currency should be inferred as the one in circulation in the country of the player.


$0 - $24,999HHI-0-25K
$40,000 - $59,999HHI-40K-60K
$100,000 or moreHHI-100K-\*
$500,000 - $999,999HHI-500K-1M


The gender uses the “GNDR” type code and corresponds to one of the following codes:

Any genderGNDR-\*

Updated about a year ago


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.