Privacy Sandbox Protected Audience API Walkthrough (formerly FLEDGE) |
While we have a full glossary for the Privacy Sandbox, the terms below will be directly useful while reading this content.
In the course of this walkthrough, you will accomplish the following:
The first step is to become familiar with Protected Audience API and services.
Weâve created a public Protected Audience demo. Review this demo to ensure that your instance of Google Chrome is ready to use the Protected Audience API and to help learn by showing a working Protected Audience auction:
A successful runthrough of these steps will ensure that your instance of Google Chrome is ready to test the Protected Audience API. Later, youâll validate that your demo was built successfully with Chrome DevTools.
Remember, you can review the Protected Audience Demo at any time to compare your progress with a working example.
Now, youâre ready to develop the infrastructure needed to run a Protected Audience on-device auction. At the end of this guide, you should be able to run an auction with a demo advertiser, publisher, DSP, and SSP. The ad will be rendered in an iframe. To render the ad in a fenced frame, see the explainer.
For the following steps, you need to be able to:
The use of local hostnames is not strictly necessary, but it does help keep this guide and the demo clear. If you donât use the hostnames above, be sure to keep track of what you do use so that you can make the necessary changes to the code samples below.
The publisher page will include the SSP JavaScript tag in a web page they host at https://paapi-demo-publisher.local/index.html. Use the following code.
î°<!DOCTYPEÂ html>
 <head>
  <meta charset=utf-8>
  <meta name=viewport content="width=device-width,initial-scale=1">
  <title>Protected Audience Demo Publisher</title>
  <script src="https://paapi-demo-ssp.local/run-ad-auction.js"></script>
 </head>
 <body>
  <h1>Protected Audience Demo Publisher</h1>
 </body>
</html>
î°
In the following steps you will write code that will run an auction, score an ad, and render the winning ad.
When a user visits the publisher website, the Seller runs an auction and renders the winning ad using an iframe. Put the following code on https://paapi-demo-ssp.local/run-ad-auction.js to start the Protected Audience auction.
î°const auctionConfig = {
 // This should be the same origin as decisionLogicUrl below
 seller: "https://paapi-demo-ssp.local",Â
 decisionLogicUrl: "https://paapi-demo-ssp.local/decision-logic.js",
 // This should be a list of all DSPs that you wish to participate in this auction
 interestGroupBuyers: ['https://paapi-demo-dsp.local'],
 // This object will be available to all auction participants
 auctionSignals: { },
 // This object will only be available to the seller during scoreAd function
 sellerSignals: { },
 // This parameter is optional, and is only available to the Buyer of each object. This is data the seller explicitly provides to individual buyers.
 // Each key in this object should match an entry in the interestGroupBuyers array above
 perBuyerSignals: {
  "https://paapi-demo-dsp.local": { },
 },
};
async function runAuction(){
 // Run ad auction
 const opaqueUrl = await navigator.runAdAuction(auctionConfig);
 // Render ad
 const iframeEl = document.createElement('iframe');
 iframeEl.src = opaqueUrl;
 document.body.appendChild(iframeEl);
}
runAuction();
î°
Create a file at https://paapi-demo-ssp.local/decision-logic.js file with the following contents. Â The script needs to define a scoreAd(...)Â function and a reportResult(...)Â function.
î°function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals, browserSignals) {
  // You can use any parameters provided to this function to define a desirability score.
  // For this example the original bid value of each bid becomes the desirability score. The score of each ad is compared automatically and the ad with the highest score is returned by the Protected Audience auction.
  return bid;
}
function reportResult(auctionConfig, browserSignals) {
  // this can be any information you wish to pass to the winning bidderâs reportWin function
  return {};
}
î°
In the following steps, youâll create two sets of code that are needed from the DSP
Use the following example code to add a user to an interest group when they visit an advertiser page. Create a file and make it available at https://paapi-demo-dsp.local/join-interest-group.js.
î°const interestGroup = {
  name: "test",
  // This should be the origin where this file will be hosted
  // This should be the same origin as biddingLogicUrl below
  owner: "https://paapi-demo-dsp.local",
  // This script must have the same origin as the owner directly above
  // An example of bidding logic is provided in the next section.
  biddingLogicUrl: "https://paapi-demo-dsp.local/bidding-logic.js",
  // Protected Audience API requires that any ad that could be returned by bidding logic is listed here.
  // For this example there is only one ad which you will set up in Step 4.2
  ads: [{
    renderUrl: "https://paapi-demo-advertiser.local/ad.html",
  }],
};
document.addEventListener("DOMContentLoaded", (e) => {
  // An interest group expires in 30 days unless it is rejoined.
  // You can set a shorter expiration depending on your use case
  const kSecsPerDay = 3600;
  navigator.joinAdInterestGroup(interestGroup, kSecsPerDay * 24 * 30);
});
î°
Every interest group has bidding logic associated with it. This logic may be provided as a JavaScript resource. The script needs to define a generateBid(...)Â function and a reportWin(...)Â function.
Create a file accessible as https://paapi-demo-dsp.local/bidding-logic.js and store the following contents.
î°function generateBid(interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, browserSignals) {
  return {
    // Free form object provided to Seller's scoreAd(...) function
    // alongside the bid that can be used to inform the
    // desirability score
    ad: {},
    // bid amount
    bid: 1,
    // This URL needs to match one of the URLs in the ads object provided to the interestGroup object during the call to joinAdInterestGroup.
    render: interestGroup.ads[0].renderUrl,
  };
}
// While this walkthrough wonât cover reporting, the current implementation of Protected Audience in Chrome will warn if reportWin() is not defined.
function reportWin(auctionSignals, perBuyerSignals, sellerSignals, browserSignals) {
  // UNIMPLEMENTED
}
Generally, a DSP will manage interest groups. Create an advertiser page where the user will be added to an interest group by a DSP using a DSPâs JavaScript (Section 3.1).
Create an HTML file that is accessible at https://paapi-demo-advertiser.local/index.html. Use the following content in the html page.
î°<!DOCTYPEÂ html>
 <head>
  <meta charset=utf-8>
  <meta name=viewport content="width=device-width,initial-scale=1">
  <title>Protected Audience Demo Advertiser</title>
 </head>
 <body>
  <h1>Advertiser Product Page</h1>
  <script src="https://paapi-demo-dsp.local/join-interest-group.js"></script>
 </body>
</html>
î°
When a Protected Audience auction concludes, an ad creative associated with a winning interest group (IG) is returned as an opaque URN. This can then be set to an iframeâs src attribute. In this demo, the creative is an SVG, rendered in an HTML document. The creative can come from anywhere. Â It may come from the advertiser, the DSP, or an ad server. For this example the advertisement is hosted on an Advertiserâs domain.
Create an HTML file available at https://paapi-demo-dsp.local/ad.html with the following contents.
î°<!DOCTYPEÂ html>
 <body>
  <meta charset=utf-8>
  <meta name=viewport content="width=device-width,initial-scale=1">
  <title>Protected Audience Demo Ad</title>
 </head>
 <body>
  <svg id="circle" viewBox="0 0 100 100" height="100" width="100">
   <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
  </svg>
 </body>
</html>
î°
Visit https://paapi-demo-advertiser.local/index.html where youâll be added to an interest group by the JavaScript managed by the demo DSP. You can verify this by visiting the Interest Group section of Chrome DevTools. Open Chrome DevTools > Application. Under Storage, you should see that your browser was added to the Interest Group âtestâ.
Next, visit the Publisher page at https://paapi-demo-publisher.local/index.html. This will render the Demo Publisher page and an iframe that will render the ad. You should be able to observe the bid in the auction by reviewing the Interest Groups section where you saw the âtestâ Interest Group. You should also see the ad created in Section 4.2.
Congratulations, you have successfully run a Protected Audience auction and rendered the ad of the winning bid!
In this demo, we are using an iframe to render the content, but you may also choose to use a fenced frame if you wish. To use a fenced frame, pass in the resolveToConfig property to the runAdAuction() call.  The auction promise will resolve to a fenced frame config object, that can be set as the config attribute of the fenced frame element.
î°const frameConfig = await navigator.runAdAuction({
 // ...auction configuration
 resolveToConfig: true
});
if (window.FencedFrameConfig && frameConfig instanceof FencedFrameConfig) {
 const frame = document.createElement('fencedframe');
 frame.config = frameConfig;
}
î°
See the fenced frames article to learn how to render a Protected Audience auction content into a fenced frame.
To ask a question about your implementation, about the demo, or about the documentation:
For bugs and issues with the implementation of the Protected Audience API in Chrome: