OpenAds wrapper synchronization
When multiple ad wrappers run on the same page, each wrapper can generate a unique transaction ID (TID), making it hard to track impressions and reconcile bids. OpenAds follows IAB Tech Lab guidelines, which recommend assigning a single, shared TID per impression so all wrappers reference the same ID. This ensures consistent reporting, simplifies auditing, and keeps setups compliant across multiple libraries. The process of synchronization attributes all bids for an impression to a single ID instead of one per wrapper.
IMPORTANT: Improper wrapper configuration can result in lower win rates, or missing signals in the auction.
What you need to know
Here's what you need to know about wrapper synchronization:
- Wrapper synchronization is a one-time configuration that ensures compliance with IAB Tech Lab guidelines for TIDs.
- OpenAds ignores any
ortb2Imp.ext.tidvalues not generated by theoajs.generateTID()function. For such impressions, it generates a new TID and logs a warning in the browser console with details of the offending impression. - Implementations outside of OpenPath (the default ad-serving path for OpenAds) that use a TDID require additional cookie syncing.
- Your consent configuration must align across all wrappers. For details, see Consent Management.
- OpenAds must match CPM rounding in all other wrappers.
For a code sample that illustrates how you can sync an impression TID across multiple libraries, see Run Prebid.js and OpenAds.js concurrently.
Prebid
To use OpenAds alongside Prebid, configure the following Prebid settings to mirror OpenAds:
Add ad units that point to the OpenAds thetradedesk bidder and the Prebid thetradedesk bidder.
Remove Prebid namespaces—no foreign bidder is firing inside the OpenAds auction.
Set the Prebid configuration to match the CPM rounding used in OpenAds.
Update consent management in pbjs to match oajs based on location settings.
Set price granularity to the custom value in both Prebid and OpenAds.
Remove parallel OpenPath and pbjs requests with same slot conflicts.
Run Prebid.js and OpenAds.js concurrently
The following sample JavaScript code shows the pb.js and oa.js scripts running concurrently on a webpage that runs Google Publisher Tag (GPT).
TIP: If your page runs both wrappers inside the script, wait for bids from each wrapper before sending the ad server request. For details, see the
trySendAdserverRequest()function.
<script>
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
var oajs = oajs || {};
oajs.que = oajs.que || [];
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
var TIMEOUT = 700;
var adServerRequestSent = false;
var pbjsBidsBack = false;
var oajsBidsBack = false;
googletag.cmd.push(function() {
googletag.pubads().disableInitialLoad();
});
// Helper to ensure we call GPT exactly one time.
function sendAdserverRequest() {
if (adServerRequestSent) return;
adServerRequestSent = true;
googletag.cmd.push(function() {
// Apply targeting from both Prebid instances.
oajs.setTargetingForGPTAsync();
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
}
function trySendAdserverRequest() {
if (pbjsBidsBack && oajsBidsBack) {
sendAdserverRequest();
}
}
// Generate a TID to be synced across OpenAds and Prebid.
const slots = [
{
id: 'TID_PLACEHOLDER',
tid: oajs.generateTID(),
sizes: [
[300, 250]
]
}
]
oajs.que.push(function() {
oajs.requestBids({
adUnits: slots.map((slot) => ({
code: slot.id,
mediaTypes: {
banner: {
sizes: slot.sizes,
},
},
ortb2Imp: {
ext: {
// Sync TID to OpenAds.
tid: slot.tid
}
}
})),
bidsBackHandler: function() {
oajsBidsBack = true;
trySendAdserverRequest();
},
timeout: TIMEOUT
});
});
pbjs.que.push(function() {
pbjs.requestBids({
adUnits: slots.map((slot) => ({
code: slot.id,
mediaTypes: {
banner: {
sizes: slot.sizes,
},
},
ortb2Imp: {
ext: {
// Sync TID to Prebid.
tid: slot.tid
}
}
})),
bidsBackHandler: function() {
pbjsBidsBack = true;
trySendAdserverRequest();
},
timeout: TIMEOUT
});
});
// Timeout safeguard
setTimeout(function() {
sendAdserverRequest();
}, TIMEOUT);
googletag.cmd.push(function() {
googletag.defineSlot('/1234567/homepage', [300, 250], 'TID_PLACEHOLDER')
.addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>