@@ -1890,6 +1890,8 @@ if the user has opted out of collection of diagnostic data.
18901890
18911891# HTTP API # {#http-api}
18921892
1893+ ## Saving impressions ## {#http-api-impressions}
1894+
18931895\`<dfn http-header><code>Save-Impression</code></dfn> \` is a
18941896[=structured header/dictionary|Dictionary Structured Header=]
18951897set on a response requesting that the user agent invoke the
@@ -1983,6 +1985,151 @@ To <dfn noexport>parse a `Save-Impression` header</dfn> given a [=header value=]
19831985
19841986</div>
19851987
1988+ ## Measuring Conversions ## {#http-api-conversions}
1989+
1990+ \`<dfn http-header><code>Measure-Conversion</code></dfn> \` is a
1991+ [=structured header/dictionary|Dictionary Structured Header=]
1992+ set on a response requesting that the user agent invoke the
1993+ <a method for=Attribution>measureConversion()</a> API.
1994+
1995+ <div class=example id=ex-measure-conversion-header>
1996+ This is the HTTP equivalent of <a href=#ex-measure-conversion>the JavaScript `measureConversion` example</a> :
1997+ <xmp highlight=http>
1998+ Measure-Conversion: aggregation-service="https://aggregator.example/tee", histogram-size=20, epsilon=1.0, lookback-days=14, impression-sites=("publisher.example" "other.example"), impression-callers=("ad-tech.example"), match-values=(2), credit=(0.25 0.25 0.5), value=3, max-value=7
1999+ </xmp>
2000+ </div>
2001+
2002+ The following keys are defined, corresponding to the members of
2003+ the {{AttributionConversionOptions}} dictionary passed to
2004+ <a method for=Attribution>measureConversion()</a> . Default values for omitted
2005+ optional keys are populated the same way as the corresponding
2006+ {{AttributionConversionOptions}} field.
2007+
2008+ <dl dfn-for=measure-conversion>
2009+ <dt> <dfn noexport><code>aggregation-service</code></dfn> </dt>
2010+ <dd>
2011+ Value of <a dict-member for=AttributionConversionOptions>aggregationService</a> ,
2012+ a [=structured header/string=] . This key is required.
2013+ </dd>
2014+ <dt> <dfn noexport><code>epsilon</code></dfn> </dt>
2015+ <dd>
2016+ Value of <a dict-member for=AttributionConversionOptions>epsilon</a> ,
2017+ a positive [=structured header/decimal=] . This key is optional.
2018+ </dd>
2019+ <dt> <dfn noexport><code>histogram-size</code></dfn> </dt>
2020+ <dd>
2021+ Value of <a dict-member for=AttributionConversionOptions>histogramSize</a> ,
2022+ a positive [=structured header/integer=] . This key is required.
2023+ </dd>
2024+ <dt> <dfn noexport><code>lookback-days</code></dfn> </dt>
2025+ <dd>
2026+ Value of <a dict-member for=AttributionConversionOptions>lookbackDays</a> ,
2027+ a positive [=structured header/integer=] . This key is optional.
2028+ </dd>
2029+ <dt> <dfn noexport><code>match-values</code></dfn> </dt>
2030+ <dd>
2031+ Value of <a dict-member for=AttributionConversionOptions>matchValues</a> ,
2032+ an [=structured header/inner list=] containing non-negative [=structured header/integer|integers=] .
2033+ This key is optional.
2034+ </dd>
2035+ <dt> <dfn noexport><code>impression-sites</code></dfn> </dt>
2036+ <dd>
2037+ Value of <a dict-member for=AttributionConversionOptions>impressionSites</a> ,
2038+ an [=structured header/inner list=] containing [=structured header/string|strings=] .
2039+ Each string value includes a domain name using A-labels only;
2040+ [[RFC5890|Internationalized Domain Names]] therefore need to use [[RFC3492|punycode]] .
2041+ This key is optional.
2042+ </dd>
2043+ <dt> <dfn noexport><code>impression-callers</code></dfn> </dt>
2044+ <dd>
2045+ Value of <a dict-member for=AttributionConversionOptions>impressionCallers</a> ,
2046+ an [=structured header/inner list=] containing [=structured header/string|strings=] .
2047+ Each string value includes a domain name using A-labels only;
2048+ [[RFC5890|Internationalized Domain Names]] therefore need to use [[RFC3492|punycode]] .
2049+ This key is optional.
2050+ </dd>
2051+ <dt> <dfn noexport><code>credit</code></dfn> </dt>
2052+ <dd>
2053+ Value of <a dict-member for=AttributionConversionOptions>credit</a> ,
2054+ an [=structured header/inner list=] containing positive [=structured header/decimal|decimals=]
2055+ or positive [=structured header/integer|integers=] . This key is optional.
2056+ </dd>
2057+ <dt> <dfn noexport><code>value</code></dfn> </dt>
2058+ <dd>
2059+ Value of <a dict-member for=AttributionConversionOptions>value</a> ,
2060+ a positive [=structured header/integer=] . This key is optional.
2061+ </dd>
2062+ <dt> <dfn noexport><code>max-value</code></dfn> </dt>
2063+ <dd>
2064+ Value of <a dict-member for=AttributionConversionOptions>maxValue</a> ,
2065+ a positive [=structured header/integer=] . This key is optional.
2066+ </dd>
2067+ </dl>
2068+
2069+ Issue: Add a required field indicating where to send the resulting report.
2070+
2071+ <div algorithm>
2072+ To <dfn noexport>parse a `Measure-Conversion` header</dfn> given a [=header value=]
2073+ |input|, run these steps:
2074+
2075+ 1. Let |dict| be the result of [=structured header/parsing structured fields=]
2076+ with <var ignore> input_bytes</var> set to |input| and
2077+ <var ignore> field_type</var> set to "`dictionary`".
2078+ 1. If parsing failed, return an error.
2079+ 1. Let |aggregationService| be |dict|["<code>[=measure-conversion/aggregation-service=] </code> "] [=map/with default=] `undefined`.
2080+ 1. If |aggregationService| is not a [=structured header/string=] , return an error.
2081+ 1. Let |histogramSize| be |dict|["<code>[=measure-conversion/histogram-size=] </code> "] [=map/with default=] `undefined`.
2082+ 1. If |histogramSize| is not a positive [=structured header/integer=] , return an error.
2083+ 1. Let |opts| be a new {{AttributionConversionOptions}} with the following items:
2084+ : {{AttributionConversionOptions/aggregationService}}
2085+ :: |aggregationService|
2086+ : {{AttributionConversionOptions/histogramSize}}
2087+ :: |histogramSize|
2088+ 1. If |dict|["<code>[=measure-conversion/epsilon=] </code> "] [=map/exists=] :
2089+ 1. Let |epsilon| be its [=map/value=] .
2090+ 1. If |epsilon| is not a [=structured header/decimal=] , return an error.
2091+ 1. Set |opts|.{{AttributionConversionOptions/epsilon}} to |epsilon|.
2092+ 1. If |dict|["<code>[=measure-conversion/lookback-days=] </code> "] [=map/exists=] :
2093+ 1. Let |lookbackDays| be its [=map/value=] .
2094+ 1. If |lookbackDays| is not a positive [=structured header/integer=] , return an error.
2095+ 1. Set |opts|.{{AttributionConversionOptions/lookbackDays}} to |lookbackDays|.
2096+ 1. If |dict|["<code>[=measure-conversion/match-values=] </code> "] [=map/exists=] :
2097+ 1. Let |matchValues| be its [=map/value=] .
2098+ 1. If |matchValues| is not an [=structured header/inner list=] , or if any of
2099+ |matchValues|' [=list/items=] is not a non-negative [=structured header/integer=] ,
2100+ return an error.
2101+ 1. Set |opts|.{{AttributionConversionOptions/matchValues}} to |matchValues|.
2102+ 1. If |dict|["<code>[=measure-conversion/impression-sites=] </code> "] [=map/exists=] :
2103+ 1. Let |impressionSites| be its [=map/value=] .
2104+ 1. If |impressionSites| is not an [=structured header/inner list=] , or if any of
2105+ |impressionSites|' [=list/items=] is not a [=structured header/string=] ,
2106+ return an error.
2107+ 1. Set |opts|.{{AttributionConversionOptions/impressionSites}} to |impressionSites|.
2108+ 1. If |dict|["<code>[=measure-conversion/impression-callers=] </code> "] [=map/exists=] :
2109+ 1. Let |impressionCallers| be its [=map/value=] .
2110+ 1. If |impressionCallers| is not an [=structured header/inner list=] , or if any of
2111+ |impressionCallers|' [=list/items=] is not a [=structured header/string=] ,
2112+ return an error.
2113+ 1. Set |opts|.{{AttributionConversionOptions/impressionCallers}} to |impressionCallers|.
2114+ 1. If |dict|["<code>[=measure-conversion/credit=] </code> "] [=map/exists=] :
2115+ 1. Let |credit| be its [=map/value=] .
2116+ 1. If |credit| is not an [=structured header/inner list=] , or if any of
2117+ |credit|'s [=list/items=] is not a [=structured header/decimal=] or
2118+ [=structured header/integer=] , return an error.
2119+ 1. Set |opts|.{{AttributionConversionOptions/credit}} to |credit|.
2120+ 1. If |dict|["<code>[=measure-conversion/value=] </code> "] [=map/exists=] :
2121+ 1. Let |value| be its [=map/value=] .
2122+ 1. If |value| is not a positive [=structured header/integer=] , return an error.
2123+ 1. Set |opts|.{{AttributionConversionOptions/value}} to |value|.
2124+ 1. If |dict|["<code>[=measure-conversion/max-value=] </code> "] [=map/exists=] :
2125+ 1. Let |maxValue| be its [=map/value=] .
2126+ 1. If |maxValue| is not a positive [=structured header/integer=] , return an error.
2127+ 1. Set |opts|.{{AttributionConversionOptions/maxValue}} to |maxValue|.
2128+ 1. Return |opts|.
2129+
2130+ </div>
2131+
2132+
19862133# Implementation Considerations # {#implementation-considerations}
19872134
19882135* Management and distribution of values for the following:
@@ -3063,6 +3210,7 @@ urlPrefix: https://www.w3.org/TR/fingerprinting-guidance/; type: dfn;
30633210spec:structured header; type:dfn; urlPrefix: https://httpwg.org/specs/rfc9651;
30643211 text: structured header; url: #name-introduction
30653212 for: structured header
3213+ text: decimal; url: #decimal
30663214 text: dictionary; url: #dictionary
30673215 text: parse structured fields; url: #text-parse
30683216 text: string; url: #string
0 commit comments