User-Agent targeting

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.

Depending on the protocol used, the User-Agent header is exposed with one of the following string fields:

  • Google: BidRequest.user_agent
  • OpenRTB: BidRequest.device.ua

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. Depending on the protocol used, this will be exposed as one of the following fields:

  • Google: BidRequest.user_agent_data
  • OpenRTB: BidRequest.device.sua

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 UserAgent is populated based on their contents.
  • If the request contains only the User-Agent header, UserAgent is 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 headere or Client Hints. The following is a summary of these differences:

  • For identical browsers and platforms, UserAgent.browsers.brand and UserAgent.platform.brand will often differ between a UserAgent based on the User-Agent header or Client Hints. For example, UserAgent.platform.brand might appear as “Windows NT” if it were based on the User-Agent header, or “Windows” if it were based on Client Hints.
  • Some UserAgent.browsers entries are unique to the User-Agent header or to Client Hints. For example, “AppleWebKit” would appear if UserAgent were based on the User-Agent header, whereas “Chromium” would only appear if it were based on Client Hints.
  • Only a UserAgent based on the User-Agent header can contain frozen values. For example, if the platform were Windows 11 22H2, UserAgent.platform.brand would be set to “Windows NT” and UserAgent.platform.version would 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: The version field 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_ENTROPY and CLIENT_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: All version fields 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: The version field 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: The version field will not be populated.
  • CLIENT_HINTS_HIGH_ENTROPY: The version field 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 model field 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.architecture and UserAgent.bitness.
  • CLIENT_HINTS_LOW_ENTROPY: The model field will not be populated.
  • CLIENT_HINTS_HIGH_ENTROPY: The model field 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.