Many bidders track their bidder-specific user IDs through cookies. Since bidders will generally serve ads from a different domain than where Prebid Server is hosted, those cookies must be consolidated under the Prebid Server domain so that they can be sent to each demand source as part of auction calls.
Prebid Server stores bidder IDs in the uids
cookie in the host domain. For example:
{"uids":{},"tempUIDs":{"adnxs":{"uid":"4722255122219375043","expires":"2020-07-30T22:10:28.961Z"},"triplelift":{"uid":"9328941297032053459","expires":"2020-07-30T22:10:33.496Z"},"yieldone":{"uid":"8c41c3b1-ce22-44fd-9bd7-454cd79e3c91","expires":"2020-07-30T22:10:33.229Z"},"ix":{"uid":"XlV6w9HM6LYAAHx2YJ4AAACZ&476","expires":"2020-07-30T22:10:31.916Z"},"yieldmo":{"uid":"ge515bd6c7da71cdc98a","expires":"2020-07-30T22:10:32.569Z"},"adform":{"uid":"1707054018971720697","expires":"2020-07-30T22:10:30.453Z"},"brightroll":{"uid":"y-S8Fq5QZ1lwWKPeXdoZ9vSeZx47maINFrJeY53pDtokA2FlaPmwvrJg--","expires":"2020-07-30T22:10:29.867Z"},"consumable":{"uid":"ue1-sb1-aa634f4b-d618-4378-b8c3-9baa56dcb91a","expires":"2020-07-30T22:10:28.07Z"},"pubmatic":{"uid":"2ECE1904-7EB2-4C38-98A4-38E97535AA9C","expires":"2020-07-30T22:10:27.559Z"},"rubicon":{"uid":"KACWYIER-P-59CH","expires":"2020-07-30T22:22:42.432Z"},"pulsepoint":{"uid":"dcxvyKqDV5VV","expires":"2020-07-30T22:10:26.915Z"},"sovrn":{"uid":"bad97f98b08c9204fe6b9826","expires":"2020-07-30T22:10:25.588Z"},"openx":{"uid":"f1f4ac13-99f8-46da-82f8-b52c29b378e0","expires":"2020-07-30T22:10:25.93Z"}},"bday":"2020-05-18T20:01:18.934Z"}
Here’s how these IDs get placed in the cookie from Prebid.js:
1) Prebid.js starts by calling the Prebid Server /cookie_sync
, letting it know which server-side bidders will be participating in the header bidding auction.
POST https://prebid-server.example.com/cookie_sync
{"bidders":["bidderA","bidderB"], "gdpr":1, "gdpr_consent":"...", "us_privacy": "..."}
2) If privacy regulations allow, Prebid Server will look at the uids
cookie in the host domain and determine whether any bidders are missing or need to be refreshed. It responds with an array of pixel syncs. e.g.
{"status":"ok","bidder_status":[{"bidder":"bidderA","no_cookie":true,"usersync":{"url":"//biddera.com/getuid?https%3A%2F%2Fprebid-server.example.com%2Fsetuid%3Fbidder%3DbidderA%26gdpr%3D%26gdpr_consent%3D%26us_privacy%3D%26uid%3D%24UID","type":"redirect","supportCORS":false}},{"bidder":"bidderB","no_cookie":true,"usersync":{"url":"https://bidderB.com/u/match?gdpr=&euconsent=&us_privacy=&redir=https%3A%2F%2Fprebid-server.example.com%2Fsetuid%3Fbidder%3DbidderB%26gdpr%3D%26gdpr_consent%3D%26us_privacy%3D%26uid%3D","type":"redirect","supportCORS":false}}]}
3) When it receives the response, Prebid.js loops through each element of bidder_status[]
, dropping a pixel for each bidder_status[].usersync.url
.
4) The bidder-specific endpoints read the users’ cookie for the bidder’s domain and respond with a redirect back to Prebid Server’s /setuid
endpoint
5) When the browser receives this redirect, it contacts Prebid Server, which will once again check the privacy settings and if allowed, update the uids
cookie.
Cookie sync for AMP works in a way quite similar to Prebid.js.
1) The Prebid Server hosting company places a modified version of the load-cookie
script onto a CDN. This script is part of the Prebid Universal Creative repo.
The only two values currently valid for ‘endpoint’ are ‘appnexus’ and ‘rubicon’ – other host companies should update their copy to include their endpoint.
See the AMP implementation guide for more information.
2) The publisher places the ‘load-cookie’ script into the page:
<amp-iframe width="1" title="User Sync"
height="1"
sandbox="allow-scripts allow-same-origin"
frameborder="0"
src="https://PROVIDED_BY_HOSTCOMPANY/load-cookie.html?endpoint=HOSTCOMPANY&max_sync_count=5">
<amp-img layout="fill" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" placeholder></amp-img>
</amp-iframe>
If the publisher has an AMP Consent Management Platform, they should use load-cookie-with-consent.html
.
3) At runtime, the load-cookie
script just calls the Prebid Server /cookie_sync endpoint. The rest works the same as described for Prebid.js above.
Building a sync endpoint is optional – there is no benefit from ID syncing for mobile-only bidders. For browser-based bidding, ID syncing can help improve buyer bid rate. There are two main options a bidder can choose to support:
Bidders must implement an endpoint under their domain which accepts an encoded URI for redirects. This URL should be able to accept privacy parameters:
The specific attributes can differ for your endpoint. For instance, you could choose to receive gdprConsent rather than gdpr_consent.
Here’s an example that shows the privacy macros as configured in PBS-Go:
userSync:
redirect:
url: https://some-bidder-domain.com/usersync-url?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}
userMacro: YOURMACRO
PBS-Java uses slightly different macros in the bidder config:
usersync:
url: https://some-bidder-domain.com/usersync-url?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redirectUri=
redirect-url: /setuid?bidder=acuityads&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&uid=YOURMACRO
In either case, the {{…}} macros are resolved by PBS.
The “YOURMACRO” string here needs to be whatever your sync endpoint will recognize and resolve to the user’s ID from your domain. Some examples of macros that bidders use: $UID, ${UID}, \(visitor_cookie\), ${DI_USER_ID}, etc. Every bidder has their own value here.
Here’s how this all comes together:
mybidder: 132
under the cookie at prebid-domain.com
.Then the next time the client then calls www.prebid-domain.com/openrtb2/auction
, the ID for mybidder
will be available in the Cookie. Prebid Server will then stick this value into request.user.buyeruid
in the OpenRTB request it sends to mybidder
’s bid adapter.