Client hints
Your Sec-CH-UA Headers
Chromium's structured UA replacement, both the wire-level headers your browser sent and the JS API's view of them.
Client hints (JavaScript view)
From navigator.userAgentData
Requesting high-entropy client hints...
Client hints (server view)
From the Sec-CH-UA-* headers the browser sent to the server
Fetching /api/headers.php...
Reading the two panels together
The JavaScript view comes from navigator.userAgentData, plus the extra values we asked for via getHighEntropyValues. The server view is a snapshot of the Sec-CH-UA-* headers your browser actually sent to /api/headers.php. If they disagree, something in the middle (an extension, a corporate proxy, a spoofer) is rewriting one but not the other.
The hints anti-bot systems weight most heavily
Sec-CH-UA-Platformvs the OS token in the UA string. Real Chrome ties them together; sloppy spoofers desync them.Sec-CH-UA-Mobilevs whether the UA contains "Mobile Safari". Very easy to get wrong.Sec-CH-UA-Full-Version-Listvs the version number in the UA. Off-by-a-major is a giveaway.- Presence of the header set at all on a Chromium UA. Missing hints = bot.
Frequently asked questions
→What are User-Agent Client Hints?
A structured replacement for the User-Agent string, driven by Chromium. Instead of one long UA line, the browser sends a set of Sec-CH-UA-* headers, and exposes the same info to JavaScript via navigator.userAgentData. Only Chromium-family browsers (Chrome, Edge, Opera, Brave) implement it so far; Firefox and Safari have declined.
→Which hints are 'low entropy' and always sent?
Sec-CH-UA (brand list), Sec-CH-UA-Mobile, and Sec-CH-UA-Platform. Browsers ship these on every request without asking. They're deliberately coarse: e.g. platform is 'Windows', not 'Windows 11 Pro build 26100'.
→What are 'high entropy' hints and how does a site request them?
Fine-grained hints: platform version, architecture, bitness, model, wow64, full version list. The server has to opt in by sending an Accept-CH response header (e.g. Accept-CH: Sec-CH-UA-Platform-Version), then subsequent requests include them. JS can also call navigator.userAgentData.getHighEntropyValues().
→Why do client hints matter for bot detection?
They're a cross-check. A UA claiming Chrome 132 on Windows should have Sec-CH-UA-Platform: 'Windows' and Sec-CH-UA-Mobile: ?0. If those headers disagree with the UA, or are missing entirely on a Chromium UA, you're flagged. Many old stealth scripts spoof the UA but forget the hints.
→How do I fake client hints when scraping?
Playwright: set them in context options via extraHTTPHeaders (though this only affects the wire, not JS). Puppeteer: use CDP's Network.setExtraHTTPHeaders plus Emulation.setUserAgentOverride, which accepts a userAgentMetadata object that patches both the headers and navigator.userAgentData. Match every hint to your UA carefully.