Header bidding: what a publisher installs
For a publisher whose network sells through Prebid — what the network hands you for each setup (our Prebid.js, your own Prebid.js, a Prebid Server, Prebid Mobile in an app), where each piece goes, and what to check when a slot stays empty.
When your network sells your inventory through header bidding, its demand prices each ad position before your own ad server is asked, through Prebid. You do not build anything for it: the network sets up a header-bidding tag for your site and hands you a few lines to install once. After that, every change is made on the network’s side, with nothing to re-install.
There is no Epom SDK. Epom takes part as an ordinary Prebid bidder called epom_as.
Who this is for
Publishers whose network sells their pages or apps through Prebid. The stock Publisher role has no Header Bidding tab, so the network builds the tag and sends you what to install. If your network adds the tab to your role, you can build the tags for sites you may edit yourself; the full guide is Header bidding.
Prerequisites
- Your site or app set up in the network, with placements for the ad positions you want sold — your network manager creates them or tells you which ones to use.
- Edit access to the page
<head>(or the WordPress theme header), your Prebid.js configuration, or the app code — whichever the integration below needs. - For Google Ad Manager pages: rights in your Ad Manager to create key-values, an order, a line item and a creative.
- For your own Prebid.js or your own Prebid Server: a build that includes the
epom_asbidder adapter, which you get from your network — see Getting the adapter. - For apps: Prebid Mobile in the app, and on Android the
AD_IDpermission.
What you receive
Tell your network manager how ads are served today; that decides what you get.
| How your pages or app serve ads today | What the network sends you | Where it goes |
|---|---|---|
| Google Ad Manager, no Prebid | One script and one container per ad position, plus a line item to set up in your Ad Manager | The script in the page <head>, the containers where the ads go |
Google Ad Manager with your own googletag code you must keep | The same script; the network lists your slot ids or ad unit paths in the tag | The page <head>, above the Google tag |
| Your own Prebid.js | One bids entry per ad unit (and an alias line, if the network bids under its own name) | Your Prebid configuration |
| An app (Prebid Mobile), or a server-side auction | The Prebid Server address, an account id and one slot id per ad unit | Your app code |
| Your own Prebid Server | The address your server reads the slots from, or one document per slot | Your Prebid Server’s configuration |
Getting the adapter
You need the epom_as adapter only when the auction runs in your own Prebid.js or your own
Prebid Server. With the network’s script, or with the Prebid Server address the network sends,
there is nothing to add.
The adapter is Epom’s and is not in the standard Prebid.js download or in a released Prebid Server build. It has been submitted to the Prebid projects and is under review; until it is released there, you get it from your network, which gets it from Epom:
- Prebid.js — the module to add to your own build, or a ready build that carries it.
- Prebid Server — your server has to be built with the adapter. Ask your network; Epom helps with the setup.
The epom_dsp adapter in the standard download is a different Epom product, for buying media,
and cannot take part in these auctions.
Steps: a page with Google Ad Manager
-
Paste the script into the page
<head>, above the Google Publisher Tag, exactly as sent:<script src="https://{serving-domain}/eas/t/{tag-id}.js"></script>Do not add
asyncand do not defer it: it has to run before Google’s tag to hold the ad request until the bids are in. -
Where each ad should appear, place the container the network sent, for example
<div data-eas-ad="leaderboard"></div>. If the network adopted your existing Google slots, skip this step: your owngoogletagslots stay. -
In your Google Ad Manager, create what the network describes: the key-values
hb_pb,hb_adid,hb_size,hb_bidderandhb_deal_epom_as, an order with a line item targeted at your ad units, and the Prebid universal creative. The network’s guide to this is The Google Ad Manager line item. -
Load the page. Positions the network’s campaigns buy show their ads; the rest are filled by Google exactly as before.
On WordPress, put the script in the theme’s header area, not in a post block, so it loads above the Google tag on every page. A later change to the tag reaches pages that already carry the script within about five minutes.
Steps: your own Prebid.js
-
Make sure your Prebid.js build includes the
epom_asbidder adapter — see Getting the adapter. -
Add each
bidsentry to the existing ad unit it names — an extra object in that unit’sbidsarray, next to your other bidders. Keep yourmediaTypes, sizes and other bidders unchanged. With the values the network sent, an ad unit looks like this:pbjs.addAdUnits([{ code: 'article-leaderboard', // your ad unit, unchanged mediaTypes: { banner: { sizes: [[728, 90], [970, 90]] } }, bids: [ { bidder: 'yourOtherBidder', params: { /* unchanged */ } }, { bidder: 'epom_as', params: { networkId: 'n1234', // your network host: 'ads.example.com', // the network's serving domain placementKey: 'a4f21c9e7b' // the placement for this position } } ] }]);Copy the values from what the network sent rather than typing them:
Param Required What it is networkIdYes Your network, as nand a numberhostWhen sent The network’s serving domain, as a bare hostname — no https://, no pathplacementKeyYes The placement that sells this position channelNo A traffic label the network targets and reports on; sent only if the placement has one customParamsNo Key-value pairs the network targets on, for example { section: 'sport' }bidFloor,bidFloorCurNo A floor for this position, in USD — a floor in any other currency is read as USD, not converted; a floor from the Price Floors module wins over it If the network bids under its own name, the entry’s
bidderis that name (for exampleepom_n1234) instead ofepom_as, and the alias line in the next step comes with it. -
If the network sent an alias line (
pbjs.aliasBidder('epom_as', '…')), run it once per page before the auction; renamepbjsif your Prebid uses another global. -
Run your auction as usual. Do not add a second wrapper or the network’s own script beside your Prebid: two auctions on the same ad units overwrite each other’s results.
For video units, your Prebid needs a cache setting or it drops our VAST bids before your
bidsBackHandler runs; see Instream video under
What the publisher does with it.
Steps: an app with Prebid Mobile
-
Point the SDK at the Prebid Server address and account the network sent — a small-volume shared server or a dedicated one, as described under Which Prebid Server to use. For example on Android:
PrebidMobile.setPrebidServerAccountId("<networkId>"); PrebidMobile.setPrebidServerHost(Host.createCustomHost("https://<prebid-server>/openrtb2/auction")); -
Use each slot id (it looks like
<networkId>-26) as theconfigIdof one ad unit. One id serves one kind of creative: a rewarded video and a rewarded playable are two ad units with two ids. -
Start the ad units from the SDK’s initialisation callback, so the first request is not lost.
-
On Android, declare the
AD_IDpermission; without it frequency caps cannot apply to your users.
The example apps for iOS and Android show each format end to end. If the app logs Prebid server does not recognize Config Id, compare the id character by character with the list the network sent, then see When the app gets nothing.
Options you keep
- Floors. A floor you set in Prebid — the Price Floors module,
params.bidFloor, orimp.bidfloorfrom the SDK — is honoured before Epom bids. Floors are in US dollars. - Consent. Your consent manager’s TCF string is passed on with every bid request; nothing to change on your side. A page without a consent manager still bids.
- Your other bidders and Google demand. They compete as before; header bidding adds one bidder, it does not replace your ad server.
Corner cases and gotchas
Corner case: the tag script must load before the Google tag. Loaded after it — moved to the footer, given
async, or delayed by a script-optimisation plugin — it cannot hold Google’s first ad request, so the page’s first impressions go without the bids and header bidding joins only from the first refresh. The browser console says so.
Corner case: in your own Prebid, a creative bids only in a size your ad unit lists. If an ad unit never shows Epom demand, check that its
mediaTypes.banner.sizesinclude the sizes the network sells there.
Corner case: a slot id is fixed once created. If the network removes a slot and adds it again, it has a new id, and the app has to be updated with it.
Per-role notes
- Publisher (stock role): no Header Bidding tab; you install what the network sends and see the results in your usual reports.
- Publisher with the Header Bidding tab: build tags for sites you can edit — see Header bidding.