> ## Documentation Index
> Fetch the complete documentation index at: https://docs.surfsky.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

> How Surfsky runs isolated cloud browsers, routes their traffic, builds their fingerprints, and connects them to your code.

Surfsky runs antidetect Chrome in its own cloud. Each session has a browser process in an isolated container with a private filesystem and network stack. Your automation client connects over the Chrome DevTools Protocol (CDP), ChromeDriver, or HTTP.

<span id="how-surfsky-solves-this" />

<span id="what-surfsky-does-about-it" />

<span id="the-connection-flow" />

## Starting a browser

A start request passes through these stages:

1. **Validation and limits.** The request body is checked and your concurrency and quota are verified.
2. **Container.** A fresh container is allocated for the session. For a persistent profile, saved data starts downloading at the same time.
3. **Network.** Surfsky connects your proxy or VPN, or a proxy from a Surfsky pool, inside the container's network namespace. It checks the exit IP through that connection and looks up its country, region, city, timezone, and coordinates.
4. **Fingerprint.** Surfsky selects a device from fingerprints collected on real machines, matching the OS and any hardware fields you set. Location-dependent fields such as timezone and language are derived from the exit IP unless you set them. A persistent profile reuses the device chosen at creation. Surfsky signs the configuration and sends it to the browser.
5. **Browser.** Chrome starts inside the namespace, reads the configuration at engine level, and restores profile data.

The response carries `ws_url` for CDP and `internal_uuid` for HTTP calls and for stopping. The inactivity timer starts here; see [Sessions](/sessions#how-a-session-ends). If a stage fails, the [error code](/errors) says which one.

<span id="-developer-friendly" />

## Connect to the browser

* **CDP over WebSocket.** Connect to `ws_url` from your [automation framework](/quickstart#connect-your-existing-code) or an [SDK](/sdk). The connection goes through a Surfsky layer that adds [human emulation](/human_emulation), [CAPTCHA](/captcha-solving), and [screencast](/screencast) commands on top of standard CDP.
* **ChromeDriver.** [Selenium](/quickstart/selenium) connects over the WebDriver protocol to a ChromeDriver started next to the browser.
* **HTTP.** The [Scraping API](/quickstart/scraping_api) loads a page and returns its content without a persistent connection.

Every CDP command, WebDriver request, or scrape call resets the inactivity timer. An open but idle socket does not. [Stop the session](/quickstart#3-stop-it) when you are done.

<span id="-real-fingerprints" />

<span id="browser-configuration" />

<span id="core-capabilities" />

<span id="what-makes-it-different" />

<span id="️-bypass-detection" />

<span id="1-use-quality-proxies" />

<span id="2-act-human" />

<span id="3-rotate-smartly" />

<span id="getting-good-results" />

<span id="quick-start-tips" />

<span id="the-detection-problem" />

<span id="what-gets-detected" />

<span id="what-affects-access-to-a-website" />

<span id="why-you-need-this" />

## Fingerprint

A fingerprint consists of browser and device properties exposed to a page, including the user agent, Client Hints, OS, hardware, screen, fonts, media devices, location, and WebRTC settings. Surfsky generates a signed configuration on the server. The browser engine applies it at startup without an injected script or extension.

### Consistent fingerprint

Fingerprint fields are selected as a compatible set. The OS determines the available GPU presets, screen sizes, and fonts. Each GPU preset includes WebGL parameters recorded on a real machine. CPU and memory values follow supported hardware combinations: an Apple M-series renderer determines its core count and memory options, and a Windows core count determines its memory options. The generated user agent and Client Hints match the browser build. Random selection is weighted toward common hardware.

You override fields in the [fingerprint configuration](/fingerprints). Setting one field does not adjust the others, so keep overrides consistent.

### Fields that follow the IP

When unset, `timezone`, `languages`, and `geolocation` are derived from the exit IP at each start. Explicit values remain fixed when the proxy changes. For example, changing a persistent profile's proxy country updates its generated timezone but preserves an explicit timezone override.

### What stays fixed

A persistent profile's device identity (OS, hardware, GPU, screen, user agent, fonts, etc.) is generated once at creation and reused on every start. Change it with `PATCH /profiles/{profile_uuid}` while the profile is stopped. Changing hardware fields changes the device a site sees, even when cookies are restored.

### Canvas and WebGL

For the fingerprinting scripts used by Akamai, ThreatMetrix, Cloudflare, Google, and similar services, the browser returns a canvas image recorded on a real machine with the profile's GPU. The same profile returns the same image in every session. WebGPU adapter information describes the same GPU. No configuration is needed.

### Noise

`noise` can perturb `webgl`, `canvas`, `audio`, and `client_rects` outputs. It is off by default on desktop profiles, and each profile's perturbation is constant across sessions. Leave it off unless a site links your profiles by these hashes. Android profiles use their own preset.

### Headless and screen

The browser runs headless on the server and reports screen dimensions from the fingerprint's `screen` setting. Window sizes, pixel ratio, available screen area, and orientation are consistent with that setting. Android profiles report touch input, and human emulation uses touch gestures for them.

### Beyond the fingerprint

Detection scripts also check browser behavior and consistency across execution contexts. Surfsky handles these checks in the engine:

* **Protocol traces.** Surfsky suppresses observable effects of CDP automation, including runtime-domain activation, console serialization hooks, and automation stack frames.
* **Cross-realm consistency.** The engine reports consistent device properties in the main window, iframes, and workers.
* **Network stack.** The browser uses Chrome's TLS and HTTP/2 implementations, so their fingerprints match the browser build.
* **Anti-debugging.** Detection scripts can use `debugger` statements and execution timing to check for an attached inspector. Surfsky preserves the behavior of a browser without an inspector attached.
* **Port scanning.** Pages probe localhost for the control ports of automation tools and other antidetect browsers.
* **Feature parity.** The browser exposes DRM, a WebAuthn platform authenticator, Bluetooth, and speech voices consistent with the configured device.

## Network

### Full tunnel with kill switch

The browser runs in a network namespace that routes outbound traffic through your proxy or VPN. A firewall blocks traffic outside the tunnel, including DNS lookups. If the proxy disconnects, requests fail rather than falling back to the datacenter connection.

### UDP, QUIC, and WebRTC

UDP support depends on the connection type:

| Connection                      | TCP                | UDP (HTTP/3, WebRTC)                  |
| ------------------------------- | ------------------ | ------------------------------------- |
| SOCKS5 with UDP support         | Through the proxy  | Through the proxy                     |
| SOCKS5 without UDP, HTTP, HTTPS | Through the proxy  | Blocked. Chrome falls back to HTTP/2. |
| OpenVPN, WireGuard              | Through the tunnel | Through the tunnel                    |

WebRTC uses the proxy when it supports UDP. Otherwise, the browser reports the proxy's IP in WebRTC responses. This behavior is configured automatically.

### Blocking and routing

Use these settings to block or route requests:

* **Block domains** with `proxy_blacklist`. Requests to blocked domains do not reach the proxy or consume metered traffic. Blocking happens at the network layer, and the page receives a connection failure.
* **Route domains** to a different proxy with `domain_routes`. For example, send static assets through a datacenter proxy while keeping the target site on a residential connection. The first matching rule applies; unmatched traffic uses the main proxy.

See [Proxies](/proxies) for patterns and rule syntax.

<span id="-built-for-scale" />

<span id="performance" />

<span id="what-you-work-with" />

## Profiles and sessions

A **profile** holds the fingerprint, network settings, and saved browser data. A **session** is a running browser using that profile.

**One-time profiles** suit tasks that do not need saved state, such as a single scrape or form submission. One request creates and starts the browser. Its container and profile data are discarded when the session stops.

**Persistent profiles** preserve a device identity and selected browser state between runs. Use them for account automation or to reuse valid login and challenge cookies. Create the profile once; each start restores its fingerprint and saved storage.

When a persistent session stops, the browser closes cleanly and the selected storage is packed, encrypted with AES (AES-128-CBC with HMAC-SHA256, key derived per profile), and uploaded to S3 as a new profile version. Profile data is never stored unencrypted at rest.

See [Sessions](/sessions) for storage options and lifecycle details.

<span id="get-started" />

<span id="next" />

<span id="perfect-for" />

<span id="skip-if-you-need" />

<span id="when-it-is-worth-it" />

<span id="when-to-use-surfsky" />

<span id="choose-an-integration" />

Start your first browser with the [Quickstart](/quickstart).
