Topics API integration guide

Learn how to use the Topics API to meet specific ad tech use cases.

How the API returns topics

If Chrome lacks a sufficient number of observed topics to create the top five topics for an epoch (one week), then the Topics API will add random topics to complete the top five. The Topics Internals column headed Real or Random indicates whether that particular topic was based on a real observation or additional random "padding" to complete the top five. Read more about this mechanism in the explainer.

The topic selected for each epoch is randomly selected from the user's top five topics for that time period. If not enough topics have been observed during the epoch, then additional topics will be chosen at random to make up the total of five. These randomly selected topics are subject to filtering.

To further enhance privacy and ensure that all topics may be represented, there is a 5% chance that the topic selected for an epoch is randomly selected from all topics, instead of being chosen from observed topics. As in the case above where too few topics had been observed, these randomly selected topics are not subject to filtering.

More on how topics are selected is available in Topics classification.

Plan your MVP deployment

The Topics API gives access to topics of interest observed for a user, without having to resort to tracking the sites a user visits, or exposing their navigation history.

The Topics API caller is the entity that calls the document.browsingTopics() JavaScript method, or observes and accesses topics using HTTP request headers. Your code, and the eTLD+1 it's called from, in this instance, is the caller. When you call the Topics API, you're instructing the user's browser to observe the topics of interest when the user visits a website. This visit is then considered in the topics calculation for the next epoch.

The Topics API is designed to filter results per-caller or per-eTLD+1 of the calling context. In other words, the origin of the iframe (when using the JavaScript API) or the URL of the fetch request (when using headers) is considered the caller, and topics are calculated according to that caller.

The following diagram illustrates this approach:

The steps the Topics API takes as users visit sites that use the API.
How the API observes and accesses topics.

In this diagram:

  1. A user opens Chrome and visits multiple websites (customerA.example, customerB.example.br, etc.) which include your ad tech's iframe (source: iframe.adtech.example) or the fetch call passing headers.
    • Chrome will record topics of interest of this user.
  2. After seven days navigating, with topics of interest being observed by the Topics API, the same user on the same device visits a target website (publisher-e.example). The Topics API returns a list of topics and in this specific example, one topic calculated from the previous week of observations of this user will be returned.
    • Only browsers of users who visited sites that adtech.example has observed in Step 1 will be returning topics results in Step 2 (we call this observation filtering—you can't see topics of users you never saw before).
  3. With this list (of one topic for now) you can call your back-end API (ads.adtech.example/topics-backend) to use topics data as part of your contextual dataset.
  4. Now, depending on your use case, you can create a more personalized experience for this user by accessing the topics of interest you have observed for them during the last weeks.

Call the Topics API

There are two ways to observe and access the topics for a user. You can use

  • The JavaScript API from within an iframe:
    • Adding an iframe on target websites (publisher's websites) that contains JavaScript code calling the Topics API using document.browsingTopics().
  • Headers option:
    • Fetch (which is recommended) or XHR (not recommended and was only available during the completed origin trial):
      • You can access topics from the Sec-Browsing-Topics header in requests to the ad tech back end. This is the most performant option (low latency to observe topics of one specific user).
    • Using an iframe tag with the browsingtopics attribute:
      • You can add an iframe with a browsingtopics attribute and Chrome will include topics (observed for the eTLD+1 of the iframe) in the Sec-Browsing-Topics header on the request for the iframe.

Implement with JavaScript and iframes

We recommend you fork either the Topics JavaScript API demo or the header demo and use one of these as a starting point for your code.

You can include an <iframe> element in HTML or add an iframe dynamically with JavaScript. One way to dynamically create an iframe is with the following JavaScript:

const iframe = document.createElement('iframe');
iframe.setAttribute('src', 'https://...');
document.body.appendChild(iframe);

Check if the Topics API is supported and available on this device through feature detection:

'browsingTopics' in document && document.featurePolicy.allowsFeature('browsing-topics') ?
  console.log('document.browsingTopics() is supported on this page') :
  console.log('document.browsingTopics() is not supported on this page');

Call the Topics API from within that iframe:

const topics = await document.browsingTopics();

You should receive a list of topics observed for this user from the last three weeks. Remember, this list can be empty or may include 1, 2, or 3 topics, from up to the last three weeks.

Here's an example of what the API returns:

[{'configVersion': String, 
  'modelVersion': String, 
  'taxonomyVersion': String, 
  'topic': Number, 
  'version': String}]
  • configVersion: a string identifying the current configuration.
  • modelVersion: a string identifying the machine-learning classifier used to infer topics.
  • taxonomyVersion: a string identifying the set of topics currently in use by the browser.
  • topic: a number identifying the topic in the taxonomy.
  • version: a string combining the configVersion and the modelVersion.

Read more about this implementation.

Implement with HTTP headers

Topics can be accessed from the Sec-Browsing-Topics header of a fetch()/XHR request, or of an iframe request.

Request and Response headers for setting and retrieving topics.
Headers for iframe and fetch().

You can mark topics provided by request headers as observed by setting an Observe-Browsing-Topics: ?1 header on the response to the request. The browser will then use those topics to calculate topics of interest for a user.

If the API returns one or more topics, a fetch request to the eTLD+1 from which the topics were observed will include a Sec-Browsing-Topics header like this:

(325);v=chrome.1:1:1, ();p=P000000000

If no topics are returned by the API, the header looks like this:

();p=P0000000000000000000000000000000

Sec-Browsing-Topics header values are padded, to mitigate the risk of an attacker learning the number of topics scoped to a caller based on the header length.

Implement with fetch()

On the publisher page, add your code for the fetch request, making sure to include {browsingTopics: true}.

fetch('<topics_caller_eTLD+1>', {browsingTopics: true})
    .then((response) => {
        // Process the response
 })

In browsers that support the API, the fetch() request will include a Sec-Browsing-Topics header that lists topics observed for the request URL hostname.

Implement with an iframe

Similarly to a fetch() request, the Sec-Browsing-Topics header will be sent when using the browsingtopics attribute on an iframe.

<iframe src="<topics_caller_eTLD+1>" browsingtopics></iframe>

In this case, the will be the caller, similar to the fetch call.

Server side—identical for all cases

To have the topics in the Sec-Browsing-Topics request header marked by the browser as observed, but also to include the current page visit in the user's next epoch top topic calculation, the server's response has to include Observe-Browsing-Topics: ?1.

Here's a JavaScript example using setHeader():

res.setHeader('Observe-Browsing-Topics', '?1');

Topics back-end implementation

Adding a back end for Topics is optional. Your choice depends on how and where you want to use the topics calculated on-device (in the browser).

// Use the language/framework/stack of your preference
function processTopicsBackendAPI(topics, user, domain, caller) {
  // Validate inputs
  // If the list is not empty, continue
  // Use topics as an additional contextual signal
}

Use topics as contextual data

Topics data can be considered alongside other signals such as URLs, keywords, and even tags, as an additional signal about your audience.

As explained in Maximize ad relevance after third-party cookies, there are multiple approaches to leveraging Topics to serve relevant ads. Some of these involve using topics to build audiences, and others suggest using Topics as one signal among others to train machine learning models that will be used to infer additional interests of the audience or even to optimize bidding logic.

Build and deploy

  1. Collect topics by observing users in production—not scaled yet (Estimated time: approximately 1 week)
    1. Understand your options: iframe and JavaScript or HTTP headers
    2. Define the domain of the iframe.
    3. Build the JavaScript code, using the demo app as a code reference — or implement the headers option.
    4. Deploy Topics to your controlled environment (some production sites).
    5. Add the Topics implementation to some target sites (no more than five sites at this time).
    6. Functional testing and validation.
  2. [Optional] Use Topics data as a contextual signal (with URLs, tags, etc.) (Estimated time: around 3 days).
    1. After receiving the list of topics, you can send it to your back end with other contextual signals.

Deploy to some target sites

Now that you have the code, let's add it to some target sites for a first test and to make sure the API is stable and working in this controlled environment.

We recommend that you pick target websites that:

  • Get a small number of monthly visits (less than about 1 million visits/month): You should begin by deploying the API to a small audience first.
  • You own and control: If necessary you can quickly disable the implementation without complex approvals.
  • Are not business critical: Since this implementation can disrupt your user's experience, start with low risk target sites.
  • Total no more than five sites: You won't need that much traffic or exposure for now.
  • Represent different themes: Choose websites that represent different categories (for example, one about sports, another about news, one more from food and drink, etc.). You can use the internal topics tool in Chrome to validate domains and how they are classified by the Topics machine-learning classifier. Learn more about debugging in the Topics API developer guide.

Functional testing and validation

When calling the Topics API in this limited environment you can expect:

  • An empty array of topics [] if this is the first call of this device, for this site and caller in the last seven days.
  • A list of zero to three topics, representing the interests of this user.
  • After seven days of observation you should receive:
    • One topic representing the interest of that user calculated from the navigation history of that week.
      • One important detail: if not enough topics have been observed by you for a user for the Topics API to calculate the top five topics of that week, then Topics will add as many random topics as necessary to arrive at the total number of five. Find more details about the API.
  • A new topic entry replacing one of the three if you are calling it after four weeks of observation.
    • This happens because the Topics API will be stable for the following weeks, not exposing too many of the user's interests. Find more details on GitHub.
  • If you have not observed topics for the user for more than three weeks, then the Topics API will return an empty array [] again.

Measure the performance and metrics of your user experience.

  • The run time of the JavaScript calls to the Topics API inside a cross-origin iframe should be measured to be used in future performance analysis—make sure to collect and store telemetry data properly in your back end.
    • The time taken to create an iframe and postMessage() topics, after topics are received, is also another possible metric to be calculated.

Troubleshooting

I'm calling the Topics API but I'm receiving null as the result. What can I do?
If you are calling the Topics API within the first week of observing a user, then this is expected.

Key recommendations

  1. Test your front-end code to make sure your JavaScript is working as expected.

  2. Test your back end to receive the topics results.

    1. Remember to make sure data types and back-end API parameters are configured correctly.
    2. Make sure your back end is configured to scale appropriately.
  3. From our experience, it is necessary to allow at least three weeks before starting to get more relevant topics results.

  4. Not all users will have Topics enabled:

    1. Users can explicitly disable the Topics API.
    2. Publisher's pages can control permissions policy. Refer to (opt-out) in the Topics API developer guide.
    3. Check chromestatus.com for more details.
  5. Add metrics and observability to this environment: you'll need them to analyze the first results. Example metrics include:

    1. Latency of calls;
    2. HTTP errors on topics calls;
  6. Try to limit changes to your implementation during the initial three weeks.

Scale to production

Here's a step-by-step summary of how you can scale to production. The steps are explained below.

  1. Scale the implementation (production) This is described below.
    1. Add the iframe to multiple publisher's websites.
  2. Process and use topics data (Estimated time: around 4 weeks).
    1. Incorporate topics data as an additive signal alongside other data.
    2. Source real-time-bidding testing partners.
    3. Run utility testing with topics as an additive signal to your other data.

Scale your implementation

At this point you should have topics data being collected from some sites in a controlled environment, with a higher level of confidence about the whole solution.

Now it's time to scale this implementation by deploying the same code to more target websites. This will enable you to observe more users, collect more topics data, and deepen your understanding of your audiences.

We recommend the following:

  1. Deploy gradually across your sites, especially if you have a large volume of traffic.
  2. Perform load testing for your topics data, according to your expected traffic.
    1. Confirm that your back end can handle a large volume of calls.
    2. Set up metric collection and logs for analysis.
  3. Immediately after deploying the Topics API, check your metrics to detect any severe end-user issues. Keep checking your metrics regularly.
  4. In case of disruption or unexpected behavior, roll back the deployment and analyze your logs to understand and fix the issue.

See also

Check out our resources to better understand the Topics API on the Web.