For AI agents: a documentation index is available at /llms.txt
Skip to main content

OS emulation

Browserless sessions run on Linux, so they expose a Linux fingerprint by default. Bot detection systems cross-check signals like the User-Agent, navigator.platform, UA Client Hints, GPU renderer, and media devices, and flag sessions where these don't line up. The emulationOs query parameter switches the session to a coherent operating system identity — set it to windows or macos to move off the default Linux fingerprint.

Prerequisites

emulationOs is a URL query parameter you add to the endpoint. It works on every stealth and BQL route and on any regional endpoint — it is not a header, a launch option, or a mutation.

Accepted values

ValueEmulated identity
windowsWindows / Chrome on Win64
macosmacOS / Chrome on Intel Mac
linuxNative Linux identity (the default when omitted)

Only desktop Windows and macOS identities are supported — mobile OS emulation (Android, iOS) is not available. Any unrecognized value (a mobile OS name, a typo, or wrong casing) is silently ignored and the session runs as native Linux with no error, so verify navigator.platform if you're unsure the value took effect.

What gets spoofed

When emulationOs is set, the session presents one internally consistent set of signals for the target OS:

  • User-Agent (e.g. Windows NT 10.0; Win64; x64)
  • UA Client HintsSec-CH-UA-Platform, Sec-CH-UA-Platform-Version, getHighEntropyValues()
  • navigator.platformWin32, MacIntel, or Linux x86_64
  • GPU / WebGL renderer and CPU core count (navigator.hardwareConcurrency) for the platform
  • Media devices, speech-synthesis voices, and AudioContext latency for the OS

These signals stay consistent for the session's lifetime, including across navigations and new windows.

What it doesn't change

emulationOs only sets OS-derived browser signals. It does not change:

  • Timezone, locale, and Accept-Language — these follow your proxy's location, not the emulated OS.
  • Screen and viewport size — set these on the client (defaultViewport / setViewport).
  • WebRTC handling — applied uniformly to every stealth session.

A Windows identity served with a mismatched timezone or locale is itself a detection signal, so pair emulationOs with a region-matched proxy for a fully coherent profile.

Usage with stealth routes

Stealth routes (/stealth, /chromium/stealth, /chrome/stealth) already run the full stealth stack. Adding emulationOs shifts the whole identity to the target OS:

import puppeteer from "puppeteer-core";

const TOKEN = "YOUR_API_TOKEN_HERE";

const browser = await puppeteer.connect({
browserWSEndpoint:
`wss://production-sfo.browserless.io/stealth?token=${TOKEN}&emulationOs=windows`,
});

const page = await browser.newPage();
const platform = await page.evaluate(() => navigator.platform);
console.log(platform); // "Win32"

await browser.close();

With emulationOs=windows or macos, the session's User-Agent is authoritative: any --user-agent you pass in launch options is overridden to keep the identity coherent. To control the User-Agent yourself, omit emulationOs or use BrowserQL's userAgent() mutation.

Usage on BQL routes

BQL routes (/chromium/bql, /chrome/bql, /stealth/bql) accept emulationOs the same way, and all of them run stealth-hardened. See OS emulation in BrowserQL for BQL-specific usage.

FAQ & Troubleshooting

I set emulationOs but the site still detects me. What else can I do?

OS emulation is one layer of the stealth stack. For heavily protected sites, pair it with a region-matched residential proxy — which also aligns timezone and locale — and make sure you're on a stealth or BQL route rather than a plain /chromium connection. Some sites also fingerprint TLS and HTTP/2 traits that are independent of the OS identity.

Does emulationOs work on plain (non-stealth) WebSocket routes?

No. On routes like /chromium or /chrome the parameter is accepted but no stealth hardening is injected, so the spoofing never takes effect. Use a stealth route (/stealth) or a BQL route.

Can I change emulationOs mid-session?

No. The emulated OS identity is fixed when the session is created and reused for the connection's lifetime, including across reconnects — you don't need to re-append emulationOs to a reconnect URL. (The User-Agent itself can still be replaced mid-session with BrowserQL's userAgent() mutation, but that doesn't change the emulated platform or GPU.)

Next Steps