Privacy Sandbox

Protected Audience API Walkthrough (formerly FLEDGE)

Key terms and concepts

While we have a full glossary for the Privacy Sandbox, the terms below will be directly useful while reading this content.

  1. Advertiser: A company that pays to advertise their products.
  2. Buyer: A buyer is a party bidding for ad space in an ad auction, likely to be a Demand Side Platform (DSP), or maybe the advertiser itself. Ad space buyers own and manage interest groups. Learn about ad space buyers in FLEDGE.
  3. Device: A unique Google Chrome instance where Protected Audience on-device auctions will be running.
  4. DSP (Demand-side platform): An ad tech service used to automate ad purchasing. Advertisers use DSPs to buy ad impressions across a range of publisher sites. Publishers make ad inventory available through marketplaces called ad exchanges, and buyers compete in real-time through a DSP for the opportunity to place their advertisement.
  5. Interest Group: The Protected Audience API equivalent to an audience / segment. They are created by Buyers, and may represent any custom audience logic, such as a remarketing list. They are maintained on-device in a protected environment. Every Protected Audience interest group has an owner (owners are buyers).
  6. Origin: A source site identified by the scheme (protocol), hostname (domain), and port of the URL used to access it. E.g., https://developer.chrome.com
  7. Origin trial: A Google Chrome capability that enables developers to enable a new or experimental feature on real user traffic, before it is launched in the web platform
  8. Publisher: A site with ad inventory offered to advertisers for commercial ad placement.
  9. Seller: A seller is the party invoking the Protected Audience ad auction, likely to be a Sell Side Platform (SSP) or maybe the publisher itself.
  10. Supply-side Platform (SSP): An ad tech service used to enable programmatic monetization of ad inventory. SSPs allow publishers to offer their inventory to multiple ad exchanges, DSPs, and networks. This enables a wide range of potential buyers to bid for ad space.
  11. Uniform Resource Name (URN): A URL essentially made up of random numbers that offers an opaque handle to an underlying resource, e.g. URL. The underlying resources isn't visible except in certain circumstances, e.g. when the URN is rendered in a Fenced Frame or Iframe. globally unique persistent identifiers assigned within defined namespaces

Your goals

In the course of this walkthrough, you will accomplish the following:

  1. Get to know the Protected Audience API.
  2. Set up your device to run an end-to-end Protected Audience on-device auction.
  3. Create a test setup of each auction participant.
  4. Run a Protected Audience on-device auction and render the winning ad.

Getting to know the Protected Audience API

The first step is to become familiar with Protected Audience API and services.

Test the API with the demo

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:

  1. Watch this video (6m) walking through the demo.
  2. Go to fledge-demo.glitch.me and follow the instructions to start your Chrome browser with the required sets of command line flags.
  3. Open the “travel” advertiser example
  4. Open Chrome DevTools > Application. Under Storage, you should see that your browser was added to the Interest Group “travel”.
  5. Go to the auction demo. You should see three new events in Chrome DevTools. There will be an event with Access Type = "loaded", another with Access Type = "bid", and a final event with Access Type = "win". You should also see the winning ad being shown on the demo page in the “ADS BY FLEDGE” section.


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.

Set up your local environment

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:

  • Serve HTML and JS files from multiple origins (For testing purposes, you do not have to deploy the setup on the web, and you can test on your local machine).
  • Serve the HTML and JS content through an HTTPS connection.
  • Map each web server to the following hostnames. Note that you may change any of these names, but be sure to update the example code provided below with the hostnames you do use.
  • https://paapi-demo-advertiser.local
  • https://paapi-demo-publisher.local
  • https://paapi-demo-ssp.local
  • https://paapi-demo-dsp.local

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.

1: Create the Publisher web page and logic

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>

î°‚

2: Create the SSP logic

In the following steps you will write code that will run an auction, score an ad, and render the winning ad.

2.1: Create the auction and ad rendering logic

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();

î°‚

2.2: Create scoring logic

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 {};

}

î°‚

3: Create the DSP web page and logic

In the following steps, you’ll create two sets of code that are needed from the DSP

  • Code to add a user to an interest group on the advertiser prior to the auction.
  • Code to provide bidding logic and reporting logic to the auction

3.1 Add user to an interest group

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);

});

î°‚

3.2 Provide bidding and reporting logic

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

}

î°‚4: Create the Advertiser web page

4.1: Create the advertiser’s product page

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>

î°‚

4.2: Create an advertisement

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>

î°‚

5: Putting it all together (join an IG, run the auction, render an ad)

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!

Using fenced frames

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.

Engage and share feedback

Get support

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:

Get updates

Find out more