# Signals

## Raw payload sections

The widget sends these sections in strict mode:

- `page`
- `document`
- `navigator`
- `screen`
- `browser`
- `timezone`
- `media`
- `storage`
- `permissions`
- `automation`
- `canvas`
- `webgl`
- `webgl2`
- `audio`
- `fonts`
- `network`
- `css`
- `battery`
- `behavior`
- `timing`

## Matching model

The backend calculates three server-side hashes:

- `stable_hash`: normalized identity-like browser/device fingerprint
- `volatile_hash`: noisy values that can change more often
- `payload_hash`: hash of the full sanitized raw payload

The backend stores the complete raw payload in `raw_payload` and compares selected raw paths with the previous observation under the same signed browser token.

## Stable mismatch fields

The backend currently checks these stable changes:

- UA family
- UA major version
- platform
- languages
- hardware concurrency
- device memory
- max touch points
- screen bucket
- timezone
- WebGL vendor
- WebGL renderer
- canvas hash
- audio hash

## Raw mismatch paths

The backend also checks raw paths such as:

- `navigator.userAgent`
- `navigator.appVersion`
- `navigator.platform`
- `navigator.vendor`
- `navigator.languages`
- `navigator.highEntropy`
- `screen`
- `browser.outerWidth`
- `browser.outerHeight`
- `timezone.timeZone`
- `timezone.timezoneOffset`
- `webgl.unmaskedVendor`
- `webgl.unmaskedRenderer`
- `webgl2.unmaskedVendor`
- `webgl2.unmaskedRenderer`
- `canvas.hash`
- `audio.hash`
- `fonts.detected`
- `media`
- `storage`
- `permissions`
- `automation.webdriver`
- `automation.globals`
- `network`
- `css`

## Automation signals

The widget and backend look for:

- `navigator.webdriver === true`
- Selenium-style globals
- Playwright-style globals
- Puppeteer-style globals
- Phantom/Nightmare globals
- Headless-like browser inconsistencies
- zero outer window size
- collection timing anomalies
- user-agent disagreement between client payload and HTTP header

## Account matching

When `linkAccount($accountId)` is called after login, the backend records the current browser token under that account hash.

It flags:

- first browser for account
- new browser for existing account
- many browsers for account in 24 hours
