Attribution Reporting

Draft Community Group Report,

This version:
https://wicg.github.io/conversion-measurement-api
Issue Tracking:
GitHub
Inline In Spec
Editor:
(Google Inc.)

Abstract

An API to report that an event may have been caused by another cross-site event. These reports are designed to transfer little enough data between sites that the sites can’t use them to track individual users.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

This section is non-normative

This specification describes how web browsers can provide a mechanism to the web that supports measuring and attributing conversions (e.g. purchases) to ads a user interacted with on another site. This mechanism should remove one need for cross-site identifiers like third-party cookies.

1.1. Overview

A page can register an attribution source on a site by providing attributionsourceeventid and attributiondestination attributes on an a element. When such an a element is clicked, and the resulting navigation commits in a document within the same site as the attributiondestination, the attribution source is stored in UA storage.

Alternatively, a page can register an attribution source on a site by providing a registerattributionsource attribute on an a element. When such an a element is added to the page, the attribution source is stored in UA storage.

At a later point, the attributiondestination site may fire an HTTP request to trigger attribution, which matches an attribution trigger with any previously stored sources. If a matching source exists, it is scheduled to be reported at a later time, possibly multiple days in the future.

Reports are sent to reporting endpoints that are configured in the attribution source and attribution trigger.

2. HTML monkeypatches

2.1. long long reflection

Add the following rules for reflecting content attributes:

If a reflecting IDL attribute has a signed integer type (long long) then, on getting, the content attribute must be parsed according to the rules for parsing integers, and if that is successful, and the value is in the range of the IDL attribute’s type, the resulting value must be returned. If, on the other hand, it fails or returns an out of range value, or if the attribute is absent, then the default value must be returned instead, or 0 if there is no default value. On setting, the given value must be converted to the shortest possible string representing the number as a valid integer and then that string must be used as the new content attribute value.

If a reflecting IDL attribute has a signed integer type (long long) that is limited to only non-negative numbers then, on getting, the content attribute must be parsed according to the rules for parsing non-negative integers, and if that is successful, and the value is in the range of the IDL attribute’s type, the resulting value must be returned. If, on the other hand, it fails or returns an out of range value, or if the attribute is absent, the default value must be returned instead, or −1 if there is no default value. On setting, if the value is negative, the user agent must throw an "IndexSizeError" DOMException. Otherwise, the given value must be converted to the shortest possible string representing the number as a valid non-negative integer and then that string must be used as the new content attribute value.

2.2. <a> element

Add the following content attributes to the a element:

attributionsourceeventid

Identifies the declared attribution source

attributiondestination

Site which can attribute an event to the declared attribution source

attributionreportto

origin to receive attribution reports

attributionexpiry

Length of time the attribution souce is valid

attributionsourcepriority

The priority of this source relative to other sources when triggering attribution

registerattributionsource

Registers an attribution source with a source type "event"

Extend the a element’s DOM interface to include the following interface:

partial interface HTMLAnchorElement {
    [CEReactions] attribute USVString attributionDestination;
    [CEReactions] attribute DOMString attributionSourceEventId;
    [CEReactions] attribute USVString attributionReportTo;
    [CEReactions] attribute long long attributionExpiry;
    [CEReactions] attribute long long attributionSourcePriority;
    [CEReactions] attribute boolean registerAttributionSource;
};

The IDL attributes attributionDestination, attributionSourceEventId, attributionReportTo, attributionSourcePriority, registerAttributionSource must reflect the respective content attributes of the same name.

The IDL attribute attributionExpiry must reflect the attributionexpiry content attribute, limited to only non-negative numbers.

The attributiondestination attribute is a string representing an origin that is intended to be same site with the origin of the final navigation URL resulting from running follow the hyperlink with the a element.

The attributionsourceeventid attribute is a string containing information about the attribution source and will be supplied in the attribution report.

The attributionreportto attribute optionally declares the origin to send the attribution report for this source.

The attributionexpiry attribute optionally defines the amount of time in milliseconds the attribution source should be considered for reporting.

The attributionsourcepriority attribute optionally defines the priority of a source relative to other sources when triggering attribution. If not specified, 0 is used as the priority. An attribution trigger with a given reporting endpoint and trigger origin will always be attributed to the source with the highest priority value that has the same reporting endpoint and attribution destination.

The registerattributionsource attribute, if present, registers an additional source whose source type is "event".

Note: One simple priority scheme would be to use the current millisecond timestamp as the priority value.

2.3. Navigation

This section ensures that an attribution source associated with a navigation results in a top-level navigation whose final URL is same site with the attribution destination.

2.3.1. Navigation Params

A navigation params struct has an item:

attribution source

null or an attribution source declared when initiating a navigation

2.3.2. Navigate algorithm

Modify the navigate algorithm to accept a new optional parameter attributionSource of type attribution source defaulting to null.

In navigate, within step

  1. This is the step that attempts to obtain resource, if necessary. Jump to the first appropriate substep: ...

in the case where

If resource is a response

modify the substep

  1. Let navigationParams be a new navigation params whose request is null, response is resource ...

to set the attribution source of navigationParams to attributionSource.

In the case where

If resource is a request whose URL’s scheme is "javascript"

modify the substep

  1. Let navigationParams be a new navigation params whose request is resource, ...

to set the attribution source of navigationParams to attributionSource.

In the case where

If resource is a request whose URL’s scheme is a fetch scheme

modify the substep to pass attributionSource to the process a navigate fetch algorithm.

Note: The final case, where the request is not a javascript or fetch scheme, does not need to be handled as it will not result in the navigation of a top-level browsing context.

2.3.3. Process a navigate fetch

Modify the process a navigate fetch algorithm to accept a new optional parameter attributionSource of type attribution source defaulting to null.

In process a navigate fetch, modify the step

  1. Otherwise, if locationURL is a URL whose scheme is a fetch scheme, then run process a navigate fetch with a new request ...

to also pass attributionSource into the process a navigate fetch algorithm.

Modify the step

  1. Let navigationParams be a new navigation params whose request is request, response is response, ...

to set the attribution source of navigationParams to attributionSource.

2.3.4. Document creation

At the time create and initialize a Document object is invoked, the user agent knows the final URL used for the navigation and can validate the attribution destination.

In create and initialize a Document object, before

  1. Let permissionsPolicy be the result of creating a permissions policy from a response given browsingContext ...

add the following step:

  1. Execute maybe process a navigation attribution source with navigationParams and browsingContext.

Attribution source information declared on the a element needs to be passed to the navigate algorithm.

In follow the hyperlink after

  1. Let historyHandling be "replace" if windowType is not "existing or none"; otherwise, "default".

add the following steps:

  1. Let attributionSource be null.

  2. If subject is an a element, set attributionSource to the result of running obtain an attribution source with subject.

Modify the step:

  1. Queue an element task on the DOM manipulation task source given subject to navigate target to request ...

to call navigate with attributionSource set to attributionSource.

3. Fetch monkeypatches

In main fetch, within the step:

  1. If response is not a network error and any of the following returns blocked ...

add the following check to the list:

4. Permissions Policy integration

This specification defines a policy-controlled feature identified by the string "attribution-reporting". Its default allowlist is *.

5. Structures

5.1. Attribution source

An attribution source is a struct with the following items:

source identifier

A unique opaque string.

source origin

An origin.

event id

A non-negative 64-bit integer.

attribution destination

A site.

reporting endpoint

An origin.

source type

Either "navigation" or "event".

expiry

A point in time.

priority

A 64-bit integer.

source time

A point in time.

number of reports

Number of attribution reports created for this attribution source.

dedup keys

ordered set of dedup keys associated with this attribution source.

5.2. Attribution trigger

An attribution trigger is a struct with the following items:

trigger origin

An origin.

trigger data

A string.

event source trigger data

A string.

trigger time

A point in time.

reporting endpoint

An origin.

dedup key

Null or a 64-bit integer.

priority

A 64-bit integer.

5.3. Attribution report

An attribution report is a struct with the following items:

event id

A string.

source type

Either "navigation" or "event".

trigger data

A string.

reporting endpoint

An origin.

attribution destination

An origin.

report time

A point in time.

trigger priority

A 64-bit integer.

trigger time

A point in time.

source identifier

An opaque string.

6. Storage

A user agent holds an attribution source cache, which is an ordered set of attribution sources.

A user agent holds an attribution report cache, which is an ordered set of attribution reports.

The above caches are collectively known as the attribution caches. The attribution caches are shared among all environment settings objects.

Note: This would ideally use storage bottles to provide access to the attribution caches. However attribution data is inherently cross-site, and operations on storage would need to span across all storage bottle maps.

7. Source Algorithms

7.1. Parsing data fields

This section defines how to parse and extract event id, trigger data, and event source trigger data.

To parse attribution data given a string input modulo an integer maxData perform the following steps. They return a non-negative integer:

  1. Let decodedInput be the result of applying the rules for parsing non-negative integers to input.

  2. If decodedInput is an error, return zero.

  3. If decodedInput is greater than 264, return zero.

  4. Let clampedDecodedInput be the remainder when dividing decodedInput by maxData.

  5. Return clampedDecodedInput.

7.2. Parsing an attribution destination

To parse an attribution destination from a string str:

  1. Let url be the result of running the URL parser on the value of the str.

  2. If url is failure or null, return null.

  3. Return the result of obtaining a site from url’s origin.

7.3. Obtaining an attribution source from an a element

To obtain an attribution source from an a element anchor:

  1. Let sourceIdentifier be a new unique opaque string.

  2. Let currentTime be the current time.

  3. If anchor does not have both an attributiondestination attribute and an attributionsourceeventid attribute, return null.

  4. If anchor’s relevant settings object's responsible document is not allowed to use the attribution-reporting policy-controlled feature, return null.

  5. Let attributionDestination be the result of running parse an attribution destination with anchor’s attributiondestination attribute.

  6. If attributionDestination is null, return null.

  7. Let sourceOrigin be anchor’s relevant settings object's top-level origin.

  8. Let reportingOrigin be sourceOrigin.

  9. If anchor has an attributionreportto attribute, then:

    1. Let reportingUrl be the result of running the URL parser with anchor’s attributionreportto value

    2. If reportingUrl is failure or null, return null.

    3. Set reportingOrigin to reportingUrl’s origin.

  10. Let expiry be 30 days.

  11. If anchor has an attributionexpiry attribute, and applying the rules for parsing non-negative integers to the attributes’s value results in an integer greater than zero, then set expiry to that value.

  12. Let priority be 0.

  13. If anchor has an attributionsourcepriority attribute, and applying the rules for parsing integers to the attributes’s value results in an integer, then set priority to that value.

  14. Let source be a new attribution source struct whose items are:

    source identifier

    sourceIdentifier

    source origin

    sourceOrigin

    event id

    The result of running parse attribution data with anchor’s attributionsourceeventid attribute modulo max event id value.

    attribution destination

    attributionDestination

    reporting endpoint

    reportingOrigin

    expiry

    currentTime + expiry

    priority

    priority

    source time

    currentTime

    source type

    "navigation"

  15. Return source.

Max event id value is a vendor-specific integer which controls the maximum value which can be used as an event id.

7.4. Obtaining an event attribution source from an a element

To maybe obtain an event attribution source given an anchor, run the following steps:

  1. Let source be the result of running obtain an attribution source with anchor.

  2. If source is null, return null.

  3. If source does not have an registerattributionsource attribute, return null.

  4. Set source’s source type to "event".

  5. Round source’s expiry away from zero to the nearest day.

  6. Return source.

7.5. Processing an attribution source

To maybe process a navigation attribution source given a navigation params navigationParams and browsing context browsingContext, run the following steps:

  1. If browsingContext is not a top-level browsing context, return.

  2. Let attributionSource be navigationParams’s attribution source.

  3. If attributionSource is null, return.

  4. If attributionSource’s attribution destination is not same site to navigationParams’s origin, return.

  5. Queue a task to process an attribution source with attributionSource.

To process an attribution source given an attribution source source:

  1. Let cache be the user agent’s attribution source cache.

  2. Remove all entries in cache where all of the following are true:

    Note: This causes the user agent to favor triggering newer attribution sources over sources that have already been triggered.

  3. Remove all entries in cache where the entry’s expiry value is less than the current time.

  4. If the size of cache is less than an implementation-defined limit, append source to cache.

8. Triggering Algorithms

8.1. Creating an attribution trigger

To obtain an attribution trigger given a URL url and an environment settings object environment, run the following steps:

  1. Let triggerData be 0.

  2. If url’s query has a "trigger-data" field, set triggerData to the result of running parse attribution data with the value associated with the field modulo the user agent’s max trigger data value.

  3. Let eventSourceTriggerData be 0.

  4. If url’s query has an "event-source-trigger-data" field, set eventSourceTriggerData to the result of running parse attribution data with the value associated with the field modulo the user agent’s max event source trigger data value.

  5. Let dedupKey be null.

  6. If url’s query has a "dedup-key" field, and applying the rules for parsing integers to the field’s value results in an integer, then set dedupKey to that value.

  7. Let triggerPriority be 0.

  8. If url’s query has a "priority" field, and applying the rules for parsing integers to the field’s value results in an integer, set triggerPriority to that value.

  9. Let trigger be a new attribution trigger with the items:

    trigger origin

    environment’s top-level origin.

    trigger data

    triggerData.

    event source trigger data

    eventSourceTriggerData.

    trigger time

    The current time.

    reporting endpoint

    url’s origin.

    dedup key

    dedupKey.

    priority

    triggerPriority.

  10. Return trigger.

Max trigger data value is a vendor-specific integer which controls the potential values of trigger data.

Max event source trigger data value is a vendor-specific integer which controls the potential values of event source trigger data.

Formalize how to parse the query similar to URLSearchParams.

8.2. Should internalResponse to request be blocked as attribution trigger

Given a request request:

  1. If request’s current URL’s path is not equal to « ".well-known","attribution-reporting","trigger-attribution" », return allowed.

  2. Let environment be request’s window.

  3. If environment is not an environment settings object, return allowed.

  4. If environment’s responsible document is not allowed to use the attribution-reporting policy-controlled feature, return allowed.

  5. If environment’s origin is not a potentially trustworthy origin, return allowed.

  6. If environment’s top-level origin is not a potentially trustworthy origin, return allowed.

  7. If request’s current URL’s origin is not a potentially trustworthy origin, return allowed.

  8. If request’s redirect count is less than 1, return allowed.

  9. Let previousUrl be the second to last URL in request’s URL list.

  10. If request’s current URL’s origin is not same origin with previousUrl’s origin, return allowed.

    Note: The restriction to require a redirect is necessary to ensure that the request’s origin is aware and in control of the conversion registration. This could also be done with a header-based mechanism.

  11. Let trigger be the result of running obtain an attribution trigger with request’s current URL and environment.

  12. Queue a task to trigger attribution with trigger.

  13. Return blocked.

8.3. Triggering attribution

To trigger attribution given an attribution trigger trigger run the following steps:

  1. Let attributionDestination be the result of running parse an attribution destination with trigger’s trigger origin.

  2. Let matchingSources be all entries in the attribution source cache where all of the following are true:

  3. If matchingSources is empty, return.

  4. Set matchingSources to the result of sorting matchingSources in descending order, with a being less than b if any of the following are true:

  5. Let sourceToAttribute be the first item in matchingSources.

  6. If trigger’s dedup key is not null and sourceToAttribute’s dedup keys contains it, return.

  7. Let report be the result of running obtain a report with sourceToAttribute and trigger.

  8. If sourceToAttribute’s number of reports value is equal to the user agent’s max reports per source value, then:

    1. Let matchingReports be all entries in the attribution report cache where all of the following are true:

    2. If matchingReports is empty, then remove sourceToAttribute from the attribution source cache and return.

    3. Set matchingReports to the result of sorting matchingReports in ascending order, with a being less than b if any of the following are true:

    4. Let lowestPriorityReport be the first item in matchingReports.

    5. If report’s trigger priority is less than or equal to lowestPriorityReport’s trigger priority, return.

    6. Remove lowestPriorityReport from the attribution report cache.

  9. Remove sourceToAttribute from matchingSources.

  10. For each item of matchingSources:

    1. Remove item from the attribution source cache.

  11. If the size of the attribution report cache is greater than an implementation-defined limit, return.

  12. Add report to the attribution report cache.

  13. Increment sourceToAttribute’s number of reports value by 1.

  14. If trigger’s dedup key is not null, append it to sourceToAttribute’s dedup keys.

Max reports per source is a vendor-specific integer which controls how many attribution reports can be created for an attribution source.

Note: This parameter represents a privacy/utility tradeoff. Lower values mean that less trigger-side data can be associated with a source event id. Larger values allow for more attribution triggers to be reported.

8.4. Establishing report delivery time

To obtain a report delivery time given an attribution source source and a trigger time triggerTime, perform the following steps. They return a point in time.

  1. If source’s source type is "event", return source’s expiry + 1 hour.

  2. Let timeToTrigger be the difference between triggerTime and source time.

  3. Let expiryDelta be the difference between the source’s expiry and the source’s source time.

    Note: timeToTrigger is less than expiryDelta because it is not normally possible to convert an expired attribution source.

  4. If:

    timeToTrigger <= (2 days - 1 hour)
    return source time + 2 days.
    expiryDelta > (2 days - 1 hour)
    • and expiryDelta < (7 days - 1 hour)

    • and timeToTrigger <= expiryDelta

    return source’s expiry + 1 hour.
    timeToTrigger <= (7 days - 1 hour)
    return source time + 7 days.
    Otherwise
    return source’s expiry + 1 hour.

8.5. Obtaining a report

To obtain a report given an attribution source source and an attribution trigger trigger:

  1. Let triggerData be source’s trigger data.

  2. If source’s source type is "event", set triggerData to trigger’s event source trigger data.

  3. Let report be a new attribution report struct whose items are:

    event id

    source’s event id.

    trigger data

    triggerData.

    reporting endpoint

    source’s reporting endpoint.

    attribution destination

    source’s attribution destination.

    reporting time

    The result of running obtain a report delivery time with source and trigger’s trigger time.

    trigger priority

    trigger’s priority.

    trigger time

    trigger’s trigger time.

    source identifier

    source’s source identifier.

  4. Return report.

9. Security consideration

TODO

10. Privacy consideration

TODO

10.1. Clearing attribution storage

A user agent’s attribution caches contain data about a user’s web activity. When a user agent clears an origin’s storage, it MUST also remove entries in the attribution caches whose source origin, attribution destination, reporting endpoint, or trigger origin is the same as the cleared origin.

A user agent MAY clear attribution cache entries at other times. For example, when a user agent clears an origin from a user’s browsing history.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy. 16 July 2020. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SECURE-CONTEXTS]
Mike West. Secure Contexts. 18 September 2021. CR. URL: https://www.w3.org/TR/secure-contexts/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WebIDL]
Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

Informative References

[STORAGE]
Anne van Kesteren. Storage Standard. Living Standard. URL: https://storage.spec.whatwg.org/

IDL Index

partial interface HTMLAnchorElement {
    [CEReactions] attribute USVString attributionDestination;
    [CEReactions] attribute DOMString attributionSourceEventId;
    [CEReactions] attribute USVString attributionReportTo;
    [CEReactions] attribute long long attributionExpiry;
    [CEReactions] attribute long long attributionSourcePriority;
    [CEReactions] attribute boolean registerAttributionSource;
};

Issues Index

Formalize how to parse the query similar to URLSearchParams.