AI-generated Key Takeaways
-
The User-Agent header, historically used for targeting data, is being replaced by User-Agent Client Hints due to privacy concerns and usability issues.
-
The
BidRequest.device.suafield contains aUserAgentmessage populated with Client Hints when available, otherwise it is populated based on the User-Agent header string inBidRequest.device.ua. -
Bidders should use the structured
UserAgentmessage rather than parsing the User-Agent string for more reliable information. -
The
UserAgentmessage fields like browsers, platform, mobile, architecture, bitness, and model are populated differently depending on whether they are sourced from the User-Agent header or Client Hints. -
The
sourcefield within theUserAgentmessage indicates whether the data was populated from the User-Agent string or Client Hints, and if Client Hints were low or high entropy.
The User-Agent header has historically been included in bid requests to provide useful targeting data such as the initiating device's browser and platform. However, browsers often heavily redact the User-Agent due to its difficulty of use and to better protect user privacy. In response to this, Google supports User-Agent Client Hints, which are included in bid requests when available to supplement the User-Agent header. These Client Hints (for short) can be sourced from Sec-Ch-UA* headers or from the Javascript Client Hints API.
The User-Agent header is exposed as a string in the BidRequest.device.ua
field.
A UserAgent
message will be populated with Client Hints when they are available, but will
otherwise be populated based on values parsed from the User-Agent header. This
is exposed in the BidRequest.device.sua field.
Bidders are strongly encouraged to use the UserAgent message rather than the
User-Agent string.
How the UserAgent is populated
Unlike the User-Agent header, the UserAgent message represents the user agent
information broken down into multiple fields for specific information.
Depending on whether Client Hints are available in the ad request, the
UserAgent message can be populated in the following ways:
- If the request contains at least
low-entropy
Client Hints, the
UserAgentis populated based on their contents. - If the request contains only the User-Agent header,
UserAgentis populated based on what can be parsed from the header.
Example: Populating UserAgent based on the User-Agent header
Suppose there is an ad request where the browser sends the following headers:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
A UserAgent populated solely based on the User-Agent header might look like
the following:
browsers: [{ brand: "Mozilla", version: ["5", "0"] },
{ brand: "AppleWebKit", version: ["537", "36"] },
{ brand: "Chrome", version: ["103", "0", "0", "0"] },
{ brand: "Safari", version: ["537", "36"] }],
platform: { brand: "Windows NT", version: ["10", "0"] },
mobile: false,
architecture: "x86",
bitness: "64",
model: "x64",
source: USER_AGENT_STRING
Example: Populating UserAgent based on Client Hints
Suppose there is an ad request where the browser sends the following headers:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Sec-Ch-Ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
Sec-Ch-Ua-Arch: x86
Sec-Ch-Ua-Full-Version: 103.0.5060.134
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: Windows
Sec-Ch-Ua-Platform-Version: 15.0.0
In cases where at least low entropy Client Hints are included, the UserAgent
will be populated based on the contents of those headers even if User-Agent
headers are present. It would look like the following:
browsers: [{ brand: ".Not/A)Brand", version: ["99", "0", "0", "0"] },
{ brand: "Google Chrome", version: ["103", "0", "5060", "134"] },
{ brand: "Chromium", version: ["103", "0", "5060", "134"] }],
platform: { brand: "Windows", version: ["15", "0", "0"] },
mobile: false,
architecture: "x86",
bitness: "64",
source: CLIENT_HINTS_HIGH_ENTROPY
Populating based on the User-Agent header versus Client Hints
Some fields are populated differently depending on whether they are based on the User-Agent header or Client Hints. The following is a summary of these differences:
- For identical browsers and platforms,
UserAgent.browsers.brandandUserAgent.platform.brandwill often differ between aUserAgentbased on the User-Agent header or Client Hints. For example,UserAgent.platform.brandmight appear as “Windows NT” if it were based on the User-Agent header, or “Windows” if it were based on Client Hints. - Some
UserAgent.browsersentries are unique to the User-Agent header or to Client Hints. For example, “AppleWebKit” would appear ifUserAgentwere based on the User-Agent header, whereas “Chromium” would only appear if it were based on Client Hints. - Only a
UserAgentbased on the User-Agent header can contain frozen values. For example, if the platform were Windows 11 22H2,UserAgent.platform.brandwould be set to “Windows NT” andUserAgent.platform.versionwould be set to[“10”, “0”]because that is the frozen value for any Windows version at or above 10.
Data in UserAgent that is based on Client Hints will not normally be an
inaccurate replacement for frozen or redacted information. If there is any
inconsistency between the User-Agent header and a UserAgent based on Client
Hints, the information from the UserAgent should be preferred.
UserAgent object fields
This section summarizes each field, with a focus on Google RTB-specific behavior and best practices for usage.
Browsers
Contains a list of
BrandVersion
entries that are generally ordered by specificity–for example, if you were to
list out the contents of browsers, the brand for each entry might appear
in the following order:
| Brand | Meaning |
| Mozilla | Mozilla-compatible |
| AppleWebKit | AppleWebKit-based, a subset of Mozilla. |
| Chrome | Chrome browser, a subset of AppleWebKit-compatible browsers |
| Safari | Desktop variant, as opposed to mobile. |
The UserAgent will not always list browsers in any specific order, especially
if it is based on Client Hints. The following describes other differences
that you can expect to see based on the value of source:
USER_AGENT: Theversionfield may be reduced to a major version or frozen (depends on agent-specific policy). Note that there will be no indication that the value is frozen.CLIENT_HINTS_LOW_ENTROPYandCLIENT_HINTS_HIGH_ENTROPY: Entries are not ordered by any criteria; for example, the same browser might send these entries in different orders in each request. They may also contain a GREASE entry, which should be ignored.CLIENT_HINTS_HIGH_ENTROPY: Allversionfields found in browsers may be set to full versions.
Platform
A BrandVersion
entry describing the platform. This may not be compatible across the User-Agent
header and Client Hints, so targeting of some platforms may require testing
two names. For example, Apple’s Macintosh operating system is branded as
“Macintosh” in the User-Agent header, but “macOS” in Client Hints.
The following describes other differences that you can expect to see based on
the value of source:
USER_AGENT: Theversionfield may be reduced to a major version or frozen. Note that there will be no indication that the value is frozen.CLIENT_HINTS_LOW_ENTROPY: Theversionfield will not be populated.CLIENT_HINTS_HIGH_ENTROPY: Theversionfield may be set to the full version.
Mobile
Indicates whether content like ads should be optimized for small screens and/or touch input. Note that this is not necessarily an indicator of device type, as mobile browsers can be configured to request a “desktop site”.
Architecture
Identifies the platform’s architecture such as “x86” or “arm”.
For a UserAgent based on Client Hints, note that this will only be populated
when source is set to CLIENT_HINTS_HIGH_ENTROPY.
Bitness
Identifies the platform’s bitness, such as whether it has a 32-bit or 64-bit CPU. The field is an integer string that provides additional information about its architecture; for example, an “x86” architecture can have a bitness set to either “32” or “64”.
For a UserAgent based on Client Hints, note that this will only be populated
when source is set to CLIENT_HINTS_HIGH_ENTROPY.
Model
Identifies the device model. For mobile devices–meaning not laptops or desktops–this will be populated with a model name like “Pixel 6 Pro”.
The following describes differences that you can expect to see based on the
value of source:
USER_AGENT- Non-mobile devices: The
modelfield will often contain a combined architecture and bitness value such as “x64” for Windows. This value is not cross-platform; for example, Linux might use “x86_64” for the same hardware. - Mobile devices: This field will not include architecture and bitness.
If you are interested in these values, see
UserAgent.architectureandUserAgent.bitness.
- Non-mobile devices: The
CLIENT_HINTS_LOW_ENTROPY: Themodelfield will not be populated.CLIENT_HINTS_HIGH_ENTROPY: Themodelfield will only be populated for the device model of mobile devices. No value is set for desktop platforms.
Source
Identifies which headers were used to create the UserAgent. For Client Hints,
this also distinguishes between the following two cases:
CLIENT_HINTS_LOW_ENTROPY: Only basic Client Hints are available.CLIENT_HINTS_HIGH_ENTROPY: Client Hints are available, including at least one field classified as high entropy.