How Topics API Provides Interest-Based Ad Signals

The Topics API provides privacy-preserving, interest-based advertising signals directly to client-side JavaScript by determining high-level user interests on-device rather than relying on cross-site tracking cookies. This article explains how the browser calculates these topics from browsing behavior, filters them according to caller visibility, and exposes them to client-side scripts via standardized JavaScript APIs and HTTP headers to enable relevant ad targeting.

On-Device Topic Classification and Epochs

The process begins inside the user’s browser, which maintains a public, standardized taxonomy of coarse interest categories (such as “Sports,” “Consumer Electronics,” or “Rock Music”). As a user navigates the web, the browser maps the hostnames of visited sites to these categories using a local machine learning model or a curated list.

The browser calculates topics over a set timeframe known as an epoch (typically one week): 1. Top Topic Selection: At the end of each epoch, the browser identifies the user’s top five topics based on their site visit frequency. 2. Noise Injection: A sixth topic is chosen at random from the entire taxonomy to introduce differential privacy and prevent fingerprinting. 3. Retention: The browser retains topics from the last three epochs, meaning up to three historical topics can be available at any given time.

Caller Observation Requirement

To prevent third-party actors from learning about browsing history on sites where they have no presence, the Topics API enforces an observation rule. A caller (such as an ad-tech provider or analytics script) will only receive a specific topic for a user if that caller’s script was present on a website associated with that topic during the epoch in which it was calculated. If a caller never observed the user on any “Sports” sites, they cannot receive the “Sports” topic for that user.

Accessing Signals via Client-Side JavaScript

Ad-tech scripts running on the page can retrieve available topics using the JavaScript method document.browsingTopics().

When invoked, this method returns a Promise that resolves to an array of topic objects. A standard execution looks like this:

try {
  const topics = await document.browsingTopics();
  console.log(topics);
} catch (error) {
  console.error("Topics API failed to load:", error);
}

Each returned topic object contains specific metadata: * topic: A numeric ID corresponding to a category in the standard taxonomy. * taxonomyVersion: The version of the taxonomy used by the browser. * modelVersion: The version of the on-device classifier used to categorize visited sites. * configVersion: Configuration parameters used by the browser implementation.

Alternative Retrieval via HTTP Fetch

Topics can also be requested declaratively through network requests without explicitly calling document.browsingTopics(). When initiating a fetch() request or requesting an <iframe>, developers can set the browsingTopics: true option:

fetch('https://ad-server.example/bids', {
  browsingTopics: true
});

The browser automatically adds a Sec-Browsing-Topics request header containing the available topic IDs to the outgoing request. The server can then evaluate the topics, select an appropriate ad, and send back a Observe-Browsing-Topics: ?1 response header to record that it observed the current site visit for future epoch calculations.

Utilizing Signals in Ad Auctions

Once retrieved in client-side JavaScript, the topic IDs are passed as contextual parameters to downstream ad systems, header bidding wrappers (such as Prebid.js), or Real-Time Bidding (RTB) auctions. These signals allow buyers to bid on relevant audience interests while ensuring the user’s granular browsing history never leaves the local device.