Learn Measure Blog Live About

A more private way to measure ad conversions, the Event Conversion Measurement API

A more private way to measure ad conversions, the Event Conversion Measurement API

A new web API available as an origin trial in Chrome 86 measures when an ad click leads to a conversion, without using cross-site identifiers.

Updated

In order to measure the effectiveness of ad campaigns, advertisers and publishers need to know when an ad click or view leads to a conversion, such as a purchase or sign-up. Historically, this has been done with third-party cookies. Now, the Event Conversion Measurement API enables the correlation of an event on a publisher's website with a subsequent conversion on an advertiser site without involving mechanisms that can be used to recognize a user across sites.

This API is part of the Privacy Sandbox, a series of proposals to satisfy third-party use cases without third-party cookies or other cross-site tracking mechanisms. See Digging into the Privacy Sandbox for an overview of all the proposals.

Glossary

  • Adtech platforms: companies that provide software and tools to enable brands or agencies to target, deliver, and analyze their digital advertising.
  • Advertisers: companies paying for advertising.
  • Publishers: companies that display ads on their websites.
  • Click-through conversion: conversion that is attributed to an ad click.
  • View-through conversion: conversion that is attributed to an ad impression (if the user doesn't interact with the ad, then later converts).

Who needs to know about this API: adtech platforms, advertisers, and publishers

  • Adtech platforms such as demand-side platforms are likely to be interested in using this API to support functionality that currently relies on third-party cookies. If you're working on conversion measurement systems: try out the demo, see if you're eligible to register for an origin trial, and share your feedback.
  • Advertisers and publishers relying on custom code for advertising or conversion measurement may similarly be interested in using this API to replace existing techniques.
  • Advertisers and publishers relying on adtech platforms for advertising or conversion measurement don't need to use the API directly, but the rationale for this API may be of interest, particularly if you are working with adtech platforms that may integrate the API.

API overview

Why is this needed?

Today, ad conversion measurement often relies on third-party cookies. But browsers are restricting access to these.

Chrome plans on phasing out support for third-party cookies and offers ways for users to block them if they choose. Safari blocks third-party cookies, Firefox blocks known third-party tracking cookies, and Edge offers tracking prevention.

Third-party cookies are becoming a legacy solution. New purpose-built APIs are emerging to address in a privacy-preserving way the use cases that third-party cookies solved. To name a few:

Overview of some privacy sandbox APIs: trust tokens and conversion measurement (aggregate and event)

How does the Event Conversion Measurement API compare to third-party cookies?

  • It's purpose-built to measure conversions, unlike cookies. This in turn can enable browsers to apply more enhanced privacy protections.
  • It's more private: it makes it difficult to recognize a user across two different top-level sites, for example to link publisher-side and advertiser-side user profiles. See how in How this API preserves user privacy.

A first iteration

This API is at an early experimental stage. What's available in Chrome 86 as an origin trial is the first iteration of the API. Things may change substantially in future iterations.

Only clicks

This API only supports click-through conversion measurement. View-through conversion measurement isn't supported yet, because view-through conversions are harder to measure in a truly privacy-preserving way. This is an active area of work; you can read more about privacy considerations in the API proposal.

How it works

Diagram: overview of the conversion measurement API steps

This API can be used with two types of links (<a> elements) used for advertising:

  • Links in a first-party context, such as ads on a social network or a search engine results page;
  • Links in a third-party iframe, such as on a publisher site that uses a third-party adtech provider.

With this API, such outbound links can be configured with attributes that are specific to ad conversions:

  • Custom data to attach to an ad click on the publisher's side, for example a click ID or campaign ID.
  • The website for which a conversion is expected for this ad.
  • The reporting endpoint that should be notified of successful conversions.
  • The cut-off date and time for when conversions can no longer be counted for this ad.

When the user clicks an ad, the browser—on the user's local device—records this event, alongside conversion configuration and click data specified by Conversion Measurement attributes on the <a> element.

Later on, the user may visit the advertiser's website and perform an action that the advertiser or their adtech provider categorizes as a conversion. If this happens, the ad click and the conversion event are matched by the user's browser.

The browser finally schedules a conversion report to be sent to the endpoint specified in the <a> element's attributes. This report includes data about the ad click that led to this conversion, as a well as data about the conversion.

If several conversions are registered for a given ad click, as many corresponding reports are scheduled to be sent (up to a maximum of three per ad click).

Reports are sent after a delay: days or sometimes weeks after conversion (see why in Reports timing).

Browser support and similar APIs

Chrome support

This API is supported in Chrome 86 and later:

Standardization

This API is being designed in the open, in the Web Platform Incubator Community Group (WICG). It's available for experimentation in Chrome.

Similar APIs

WebKit, the web browser engine used by Safari, has a proposal with similar goals, the Private Click Measurement. It's being worked on within the Privacy Community Group (PrivacyCG).

How this API preserves user privacy

With this API, conversions can be measured while protecting users' privacy: users can't be recognized across sites. This is made possible by data limits, noising of conversion data, and report timing mechanisms.

Let's take a closer look at how these mechanisms work, and what they mean in practice.

Data limits

In the following, click-time or view-time data is data available to adtech.example when the ad is served to the user and then clicked or viewed. Data from when a conversion happened is conversion-time data.

Let's look at a publisher news.example and an advertiser shoes.example. Third-party scripts from the adtech platform adtech.example are present on the publisher site news.example to include ads for the advertiser shoes.example. shoes.example includes adtech.example scripts as well, to detect conversions.

How much can adtech.example learn about web users?

With third-party cookies

Diagram: how third-party cookies enable cross-site user recognition

adtech.example relies on a a third-party cookie used as a unique cross-site identifier to recognize a user across sites. In addition, adtech.example can access both detailed click- or view-time data and detailed conversion-time data—and link them.

As a result, adtech.example can track the behavior of a single user across sites, between an ad view, click, and conversion.

Because adtech.example is likely present on a large number of publisher and advertiser sites—not just news.example and shoes.example—a user's behavior can be tracked across the web.

With the Event Conversion Measurement API

Diagram: how the API enables conversion measurement without cross-site user recognition
"Ad ID" on the cookies diagram and "Click ID" are both identifiers that enable mapping to detailed data. On this diagram, it's called "Click ID" because only click-through conversion measurement is supported.

adtech.example can't use a cross-site identifier and hence can't recognize a user across sites.

  • A 64 bit-identifier can be attached to an ad click.
  • Only 3 bits of conversion data can be attached to the conversion event. 3 bits can fit an integer value from 0 to 7. This is not much data, but enough that advertisers can learn how to make good decisions about where to spend their advertising budget in the future (for example by training data models).

The click data and conversion data are never exposed to a JavaScript environment in the same context.

Without an alternative to third-party cookies

Without an alternative to third-party cookies such as the Event Conversion Measurement API, conversions can't be attributed: if adtech.example is present on both the publisher's and advertiser's site, it may access click-time or conversion-time data but it can't link them at all.

In this case, user privacy is preserved but advertisers can't optimize their ad spend. This is why an alternative like the Event Conversion Measurement API is needed.

Noising of conversion data

The 3 bits gathered at conversion time are noised.

For example, in Chrome's implementation, data noising works as follows: 5% of the time, the API reports a random 3-bit value instead of the actual conversion data.

This protects users from privacy attacks. An actor trying to misuse the data from several conversions to create an identifier won't have full confidence in the data they receive—making these types of attacks more complicated.

Note that it's possible to recover the true conversion count.

Summing up click data and conversion data:

Data Size Example
Click data (impressiondata attribute) 64 bits An ad ID or click ID
Conversion data 3 bits, noised An integer from 0 to 7 that can map to a conversion type: signup, complete checkout, etc.

Report timing

If several conversions are registered for a given ad click, a corresponding report is sent for each conversion, up to a maximum of three per click.

To prevent conversion time from being used to get more information from the conversion side and hence hinder users' privacy, this API specifies that conversion reports aren't sent immediately after a conversion happens. After the initial ad click, a schedule of reporting windows associated with this click begins. Each reporting window has a deadline, and conversions registered before that deadline will be sent at the end of that window.

Reports may not be exactly sent at these scheduled dates and times: if the browser isn't running when a report is scheduled to be sent, the report is sent at browser startup—which could be days or weeks after the scheduled time.

After expiry (click time + impressionexpiry), no conversion is counted—impressionexpiry is the cut-off date and time for when conversions can no longer be counted for this ad.

In Chrome, report scheduling works as follows:

impressionexpiry Depending on conversion time, a conversion report is sent (if the browser is open)... Number of reporting windows
30 days, the default and maximum value
  • 2 days after the ad was clicked
  • or 7 days after ad click
  • or impressionexpiry = 30 days after ad click.
3
impressionexpiry is between 7 and 30 days
  • 2 days after ad click
  • or 7 days after ad click
  • or impressionexpiry after ad click.
3
impressionexpiry is between 2 and 7 days
  • 2 days after ad click
  • or impressionexpiry after ad click.
2
impressionexpiry is under 2 days 2 days after ad click 1
Chronology of what reports are sent when

See Sending Scheduled Reports for more details on timing.

Example

Here's how the API records and reports a conversion. Note that this is how a click-to-convert flow would work with the current API. Future iterations of this API may be different.

Ad click (steps 1 to 5)

Diagram: ad click and click storage

An <a> ad element is loaded on a publisher site by adtech.example within an iframe.

The adtech platform developers have configured the <a> element with conversion measurement attributes:

<a
id="ad"
impressiondata="776f09351f5809c5"
conversiondestination="https://advertiser.example"
reportingorigin="https://adtech.example"
impressionexpiry="864000000"
href="https://advertiser.example/shoes07"
target="_blank"
>

<img src="/images/shoe.jpg" alt="shoe" />
</a>

This code specifies the following:

Attribute Default value, maximum, minimum Example
impressiondata (required): a 64-bit identifier to attach to an ad click. (no default) A dynamically generated click ID such as a hex-encoded 64-bit integer: 776f09351f5809c5
conversiondestination (required): the origin where a conversion is expected for this ad. (no default) https://advertiser.example
impressionexpiry (optional): in milliseconds, the cutoff time for when conversions can be attributed to this ad. 2592000000 = 30 days (in milliseconds).

Maximum: 30 days (in milliseconds).

Minimum: 2 days (in milliseconds).
Ten days after click: 864000000
reportingorigin (optional): the destination for reporting confirmed conversions. Top-level origin of the page where the link element is added. https://adtech.example
href: the intended destination of the ad click. / https://advertiser.example/shoes07

Some notes about the example:

  • You will find the term "impression" used in the attributes of the API or in the API proposal, even though only clicks are supported for now. Names may be updated in future iterations of the API.
  • The conversion destination is an origin. This may change in the future to specify just an eTLD+1.
  • The ad doesn't have to be in an iframe, but this is what this example is based on.
Gotchas!
  • If this element is within an iframe, the API must be explicitly enabled.
  • Flows based on navigating via window.open or window.location won't be eligible for attribution.

When the user taps or clicks the ad, they navigate to the advertiser's site. Once the navigation is committed, the browser stores an object that includes impressiondata, conversiondestination, reportingorigin, and impressionexpiry:

{
"impression-data": "776f09351f5809c5",
"conversion-destination": "https://advertiser.example",
"reporting-origin": "https://adtech.example",
"impression-expiry": 864000000
}

In the demo and in this example, the 64-bit impression data (click ID) is encoded as a hexadecimal string.

Conversion and report scheduling (steps 6 to 9)

Diagram: conversion and report scheduling

Either directly after clicking the ad, or later on—for example, on the next day—the user visits advertiser.example, browses sports shoes, finds a pair they want to purchase, and proceeds to checkout. advertiser.example has included a pixel on the checkout page:

<img
height="1"
width="1"
src="https://adtech.example/conversion?model=shoe07&type=checkout&…"
/>

adtech.example receives this request, and decides that it qualifies as a conversion. They now need to request the browser to record a conversion. adtech.example compresses all of the conversion data into 3 bits—an integer between 0 and 7, for example they might map a Checkout action to a conversion value of 2.

adtech.example then sends a specific register-conversion redirect to the browser:

const conversionValues = {
signup: 1,
checkout: 2,
};

app.get('/conversion', (req, res) => {
const conversionData = conversionValues[req.query.conversiontype];
res.redirect(
302,
`/.well-known/register-conversion?conversion-data=${conversionData}`,
);
});

.well-known URLs are special URLs. They make it easy for software tools and servers to discover commonly-needed information or resources for a site—for example, on what page a user can change their password. Here, .well-known is only used so that the browser recognizes this as a special conversion request. This request is actually cancelled internally by the browser.

The browser receives this request. Upon detecting .well-known/register-conversion, the browser:

  • Looks up all ad clicks in storage that match this conversiondestination (because it's receiving this conversion on a URL that has been registered as a conversiondestination URL when the user clicked the ad). It finds the ad click that happened on the publisher's site one day before.
  • Registers a conversion for this ad click.

Several ad clicks can match a conversion—the user may have clicked an ad for shoes.example on both news.example and weather.example. In this case, several conversions are registered.

Now, the browser knows that it needs to inform the adtech server of this conversion—more specifically, the browser must inform the reportingorigin that is specified in both the <a> element and in the pixel request (adtech.example).

To do so, the browser schedules to send a conversion report, a blob of data containing the click data (from the publisher's site) and the conversion data (from the advertiser's). For this example, the user converted one day after click. So the report is scheduled to be sent on the next day, at the two-day-after-click mark if the browser is running.

Sending the report (steps 10 and 11)

Diagram: browser sending the report

Once the scheduled time to send the report is reached, the browser sends the conversion report: it sends an HTTP POST to the reporting origin that was specified in the <a> element (adtech.example). For example:

https://adtech.example/.well-known/register-conversion?impression-data=776f09351f5809c5&conversion-data=2&credit=100

Included as parameters are:

  • The data associated with the original ad click (impression-data).
  • The data associated with a conversion, potentially noised.
  • The conversion credit attributed to the click. This API follows a last-click attribution model: the most recent matching ad click is given a credit of 100, all other matching ad clicks are given a credit of 0.

As the adtech server receives this request, it can pull the impression-data and conversion-data from it, i.e. the conversion report:

{"impression-data": "776f09351f5809c5", "conversion-data": 3, "credit": 100}

Subsequent conversions and expiry

Later on, the user may convert again—for example by purchasing a tennis racket on advertiser.example to go alongside their shoes. A similar flow takes place:

  • The adtech server sends a conversion request to the browser.
  • The browser matches this conversion with the ad click, schedules a report, and sends it to the adtech server later on.

After impressionexpiry, conversions for this ad click stop being counted and the ad click is deleted from browser storage.

Use cases

What is currently supported

  • Measure click-through conversions: determine which ad clicks lead to conversions, and access coarse information about the conversion.
  • Gather data to optimize ad selection, for example by training machine learning models.

What is not supported yet

The following features aren't supported yet, but may be in future iterations of this API, or in the Aggregate Conversion Measurement API:

  • View-through conversion measurement.
  • Multiple reporting endpoints.
  • Web conversions that started in an iOS/Android app.
  • Conversion lift measurement / incrementality: measurement of causal differences in conversion behavior, by measuring the difference between a test group that saw an ad and a control group that didn't.
  • Attribution models that are not last-click.
  • Use cases that require larger amounts of information about the conversion event. For example, granular purchase values or product categories.

Before these features and more can be supported, more privacy protections (noise, fewer bits, or other limitations) must be added to the API.

Discussion of additional possible features takes place in the open, in the Issues of the API proposal repository.

Is your use case missing? Do you have feedback on the API? Share it.

What else may change in future iterations

  • This API is at an early, experimental stage. In future iterations, this API may undergo substantial changes including but not limited to the ones listed below. Its goal is to measure conversions while preserving user privacy, and any change that would help better address this use case will be made.
  • API and attribute naming may evolve.
  • Click data and conversion data may not require encoding.
  • The 3-bit limit for conversion data may be increased or decreased.
  • The conversion destination may become an eTLD+1; right now, it's an origin.
  • More features may be added, and more privacy protections (noise / fewer bits / other limitations) if needed to support these new features.

To follow and participate in discussions on new features, watch the proposal's GitHub repository and submit ideas.

Try it out

Demo

Try out the demo. Make sure to follow the "Before you start" instructions.

Tweet @maudnals or @ChromiumDev for any question about the demo!

Register for the origin trial (starting in Chrome 86)

  • If you're planning on using the API as a third-party, you may be eligible to register for a third-party origin trial so you can test at scale across your customer sites.
  • If you're planning on using the API directly on your own origin, you can register your origin for an origin trial.

Share your feedback

Your feedback is crucial, so that new conversion measurement APIs can support your use cases and provide a good developer experience.

Keep an eye out

For API users: must-do and tips

API users are, for example, adtech platforms developers.

Enabling the API

If you create iframes that include ads, you'll need to add a Feature Policy for those ads to support conversion measurement with this API, as follows:

<iframe src="..." allow="conversion-measurement">
<a impressiondata="..."></a>
</iframe>

See the demo for an example.

The API needs to be explicitly enabled as above only for cross-origin child contexts, such as iframes with a cross-origin value in src. It's enabled by default in the top-level context—for example directly on the publisher page—and in same-origin child contexts.

Publishers can choose to use the conversion-measurement feature policy to disable the API.

Checking support

To programmatically check whether the API can be used on a page, use document.featurePolicy.features().includes('conversion-measurement').

(Optional) Recovering the true conversion count

Even though the conversion data is noised, you—as the reporting endpoint— may want to recover the true count of reports with a specific conversion value, despite noising. It's possible to do so when looking at aggregated conversions. This example script provides a technique to do this.

Setting up your browser for local development

  • Use Chrome version 86 or later. You can check what version of Chrome you're using by typing chrome://version in the URL bar.
  • Origin trials activate the feature for end-users. But to activate the feature locally—for example if you're developing on localhost—you'll need to enable flags. Go to flags by typing chrome://flags in Chrome's URL bar. Turn on the two flags #enable-experimental-web-platform-features and #conversion-measurement-api.
  • Disable third-party cookie blocking. In the long term, dedicated browser settings will be available to allow/block the API. Until then, third-party cookie blocking is used as the signal that users don't want to share data about their conversions—and hence that this API should be disabled.

(Optional) Debugging tips:

You can see the conversion reports the browser has scheduled to send at chrome://conversion-internals/ > Pending Reports. Reports are sent at scheduled times. But for debugging purposes, you may not want to wait for these scheduled times. To do so, you can:

  • Click Send All Reports in chrome://conversion-internals/ > Pending Reports.
  • Or activate the flag chrome://flags/#conversion-measurement-debug-mode, so that all reports are always sent immediately.

With many thanks for contributions and feedback to all reviewers—especially Charlie Harrison, John Delaney, Michael Kleber and Kayce Basques.

Hero image by William Warby / @wawarby on Unsplash, edited.

Last updated: Improve article