This page describes the behaviour of the DeviceAtlas API with respect to User-Agent Client Hints (UA-CH), traditional browser headers and JavaScript.
Identifier sources
In a web context DeviceAtlas utilises identifiers from the following sources:
- Traditional HTTP headers (primarily the User-Agent header but there are others also such as device-stock-ua and x-operamini-phone-ua).
- User-Agent Client Hint HTTP headers
- JavaScript-sourced properties including Client Hints.
With the advent of UA-CH there are now several new scenarios to be considered that necessitate additional logic in the DeviceAtlas API.
Identifier precedence & pairing
DeviceAtlas follows the following precedence of identifier sources in its consideration of tokens for browsers supporting UA-CH:
- JavaScript-sourced UA-CHs (via our DeviceAtlas Client-Side component)
- HTTP-sourced UA-CHs
- User-Agent header
A full list of the priority order is included in the Reference section at the end of this page.
DeviceAtlas examines each source of identifiers in turn and attempts to resolve them into a component such as a device model or browser along with its associated properties.
- If a source of identifiers isn’t capable of resolving a particular component the next source in the precedence order is considered.
- Some UA-CHs are inherently paired and thus must be considered together to be resolvable to a set of properties, for example platform and platformVersion hints.
- DeviceAtlas requires paired identifiers to both come from the same source in order to be utilised i.e. both identifiers must be present from a given source and have non-empty values to be considered.
The reasoning for this is as follows:
- Per the standard, UA-CHs should have the same value whether accessed from JavaScript or headers.
- If a browser withholds hints from one source it makes no sense to expose them via another.
- The behaviour of browsers with respect to high-entropy and low-entropy headers should align whether sourced from JavaScript or HTTP headers.
- Thus with a correctly functioning browser the UA-CHs should align both in value and availability.
Customers with a strong preference for how identifiers should be considered can override DeviceAtlas logic by building the appropriate input set for the API.
Scenarios
The following section considers some different scenarios to illustrate DeviceAtlas behaviour. Some of these examples will occur mostly during the transitional phases of Google's Chrome plans i.e. in the phase when Chrome is still sending a full User-Agent header, but also UA-CHs.
Frozen UA string, low-entropy UA-CH
This will be a common scenario from the first visit of a browser supporting UA-CH.
Example
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36
Sec-CH-UA-Mobile: ?1
Sec-CH-UA: "Google Chrome";v="110", " Not;A Brand";v="99", "Chromium";v="110"
Sec-CH-UA-Platform: "Android"
Behaviour: low-entropy headers utilised, reduced property set returned.
Frozen UA string, high-entropy UA-CH HTTP headers
This is the likely scenario from a second visit of a browser supporting UA-CH when high-entropy headers have been requested.
Example
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36
Sec-CH-UA-mobile: ?1
Sec-CH-UA: "Google Chrome";v="110", " Not;A Brand";v="99", "Chromium";v="110"
Sec-CH-UA-Platform: "Android"
Sec-CH-UA-Platform-Version: "11.2.1"
Sec-CH-UA-Model: "VOG-L09"
Sec-CH-UA-Full-Version: "110.0.4472.120"
Sec-CH-UA-WoW64:
Behaviour: high-entropy UA-CH headers utilised, full property set returned.
Frozen UA string, high-entropy UA-CH HTTP headers, JavaScript data
This is the likely scenario from a second visit of a browser supporting UA-CH when high-entropy headers have been requested.
Example
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36
Sec-CH-UA-Mobile: ?1
Sec-CH-UA: "Google Chrome";v="110", " Not;A Brand";v="99", "Chromium";v="110"
Sec-CH-UA-Platform: "Android"
Sec-CH-UA-Platform-Version: "11.2.1"
Sec-CH-UA-Model: "VOG-L09"
Sec-CH-UA-Full-Version: "110.0.4472.120"
js.Mobile: "true"
js.Platform: "Android"
js.Architecture: "ARM"
js.Bitness: "64"
js.fullVersionList: "Not_A Brand";v="99.0.0.0", "Google Chrome";v="109.0.5414.87", "Chromium";v="109.0.5414.87"
js.Model: "VOG-L09"
js.platformVersion: "11.0.0"
Js.wow64: ""
Behaviour: JavaScript-sourced UA-CH headers utilised, full property set returned
Full UA string, low-entropy UA-CH
This will often be the case in the transitional phase when UA-CHs are supported by a browser but the full User-Agent string is still being sent.
Example
User-agent: Mozilla/5.0 (Linux; Android 10; 5002H_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36
Sec-CH-UA: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"
Sec-CH-UA-Platform: "Android"
Sec-CH-UA-Mobile: ?1
Behaviour: fall back to User-Agent since the requisite UA-CH pair is not available.
Blended sources of UA-CH data
Some UA-CH data has been captured from JavaScript, some from HTTP headers.
Example
User-agent: Mozilla/5.0 (Linux; Android 10; 5002H_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36
Sec-CH-UA-Platform: "Android"
js.platformVersion: "12.0.1"
Behaviour: fall back to User-Agent since the requisite UA-CH pair is not available from a single source of identifiers.
Reference
Full priority order list
The table below depicts the priority order for different identifiers for each component of the DeviceAtlas model.
- Device: Properties related to the physical hardware of a device e.g. model name, screen pixel dimensions, wireless standards supported and so on.
- Operating system: Properties related to the operating system e.g. OS name, OS vendor, OS family.
- Browser: Properties related to the browser e.g. browser name, browser vendor, browser rendering engine.
Device priority order | OS priority order | Browser priority order |
|
|
|
The prefix ch.* is used when an identifier is sourced from the DeviceAtlas client-side JavaScript library.