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