The [User-Agent](https://www.rfc-editor.org/rfc/rfc7231.html#section-5.5.3)
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](https://wicg.github.io/ua-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`](https://developers.google.com/authorized-buyers/rtb/openrtb-guide#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](https://wicg.github.io/client-hints-infrastructure/#low-entropy-table) 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.

> [!NOTE]
> **Note:** The `source` field can be used to differentiate what is used to populate `UserAgent`. For example, if it were set to `USER_AGENT_STRING`, that would suggest `UserAgent` was populated based on the contents of the User-Agent headers.

## 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.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](https://developers.google.com/authorized-buyers/rtb/realtime-bidding-guide#brandversion-object)
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](https://wicg.github.io/ua-client-hints/#grease), which should be ignored.
- `CLIENT_HINTS_HIGH_ENTROPY`: All `version` fields found in browsers may be set to full versions.

## Platform

A [BrandVersion](https://developers.google.com/authorized-buyers/rtb/realtime-bidding-guide#brandversion-object)
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.