loading
Warning:
Volatile, and none of it works from a call alone Chromium-only, and genuinely unstable: shapes have changed between releases and parts have been deprecated outright. Each API also needs more than a call - a permissions policy on the document, response headers from the server, and for attribution and tokens an origin enrolled with the browser vendor. What is here is the client-side half; the rest is configuration you arrange elsewhere. Expect empty results on this page.

Topics

IsTopicsSupported / GetTopics

A topic is an id in a public taxonomy - never a profile, an identifier or a history. At most three come back, and only ones the browser has already observed this caller present for, so an empty array is the ordinary answer. Reading with skipObservation records nothing; observing should follow from a real ad request rather than from a debug read.

C#
@inject Bit.Butil.PrivacySandbox privacySandbox

var topics = await privacySandbox.GetTopics(skipObservation: true);

foreach (var topic in topics)
{
    // topic.Topic indexes into topic.TaxonomyVersion's taxonomy
}
Live sample
topics output
Results will appear here when you interact with the samples.

Attribution Reporting

IsAttributionReportingSupported / RegisterAttribution / RegisterAttributionImage

The registration lives in the response headers of a URL you fetch, not in its body - the browser reads them and stores what it read, and nothing comes back to your code. Which is the design: measurement without the site learning who converted. The image form is what an ad creative uses; the fetch form suits an app that is already making the request.

C#
// what an ad creative does - the image itself is never displayed:
await privacySandbox.RegisterAttributionImage("https://reporter.example/pixel.png");

// a source - an impression or a click that may later convert:
await privacySandbox.RegisterAttribution("https://reporter.example/source",
                                         eventSourceEligible: true);

// the conversion itself:
await privacySandbox.RegisterAttribution("https://reporter.example/trigger",
                                         eventSourceEligible: false, triggerEligible: true);
Live sample
attribution output
Results will appear here when you interact with the samples.

Private State Tokens

IsPrivateStateTokensSupported / HasPrivateToken / HasRedemptionRecord / RequestToken

An anti-fraud signal that carries nothing else: a site the user has already proved themselves on issues tokens, and another site spends one to learn 'trusted' and no more. The two Has… calls are the cheap checks - they answer whether the challenge needs running again at all.

C#
if (await privacySandbox.HasRedemptionRecord(issuer) is false)
{
    await privacySandbox.RequestToken(issuerUrl, PrivateStateTokenOperation.TokenRedemption);
}

// Attaching the record needs the issuers it may come from - nothing else says whose:
await privacySandbox.RequestToken(apiUrl, PrivateStateTokenOperation.SendRedemptionRecord,
                                  issuers: [issuer]);
Live sample
tokens output
Results will appear here when you interact with the samples.

Fenced frames

IsFencedFrameSupported / IsInFencedFrame

Worth knowing rather than assuming: inside a fenced frame storage is partitioned differently, there is no access to the embedder, navigation is restricted and the referrer is gone - so code that takes any of those for granted has to behave differently there.

C#
if (await privacySandbox.IsInFencedFrame())
{
    // no embedder, partitioned storage, no referrer
}
Live sample
fenced frame output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsTopicsSupported
ValueTask<bool> IsTopicsSupported()
True when the runtime exposes document.browsingTopics. Returns default (false) during prerender/SSR instead of throwing.
GetTopics
ValueTask<BrowsingTopic[]> GetTopics(bool skipObservation = false)
At most three coarse interests, and only ones already observed for this caller. Empty is the normal answer.
IsAttributionReportingSupported
ValueTask<bool> IsAttributionReportingSupported()
True when the runtime supports Attribution Reporting registrations.
RegisterAttribution
ValueTask<bool> RegisterAttribution(string url, bool eventSourceEligible = true, bool triggerEligible = false)
Registers a source or a trigger by fetching a URL whose response carries the registration headers.
RegisterAttributionImage
ValueTask<bool> RegisterAttributionImage(string url)
The same registration through an image, the way an ad creative does it. The image is never displayed.
IsPrivateStateTokensSupported
ValueTask<bool> IsPrivateStateTokensSupported()
True when the runtime exposes document.hasPrivateToken.
HasPrivateToken
ValueTask<bool> HasPrivateToken(string issuer)
Whether this browser holds any unspent token from an issuer.
HasRedemptionRecord
ValueTask<bool> HasRedemptionRecord(string issuer)
Whether this browser already holds a redemption record from an issuer for this site.
RequestToken
ValueTask<bool> RequestToken(string url, PrivateStateTokenOperation operation, int version = 1, string[]? issuers = null)
Runs one token operation as a fetch: requesting, redeeming, or attaching the record. SendRedemptionRecord needs issuers; the other two ignore it.
IsFencedFrameSupported
ValueTask<bool> IsFencedFrameSupported()
True when the runtime supports <fencedframe>.
IsInFencedFrame
ValueTask<bool> IsInFencedFrame()
Whether this document is itself running inside a fenced frame.
An unhandled error has occurred. Reload 🗙