This page runs the WhiskerJS collector in your browser and shows exactly what it returns: the visitorId, the structured id with one short hash per signal group, every component with its status, and the integrity flags. Run it again, come back tomorrow, and see whether the id holds, and if it does not, which group moved.
Privacy: what happens on this page
What is collected: 46 browser and device signals (screen, languages, time zone, fonts, graphics and audio rendering, and similar). Large values such as images and font lists are reduced to a SHA-256 digest in your browser. Nothing asks for permission: it reads which permissions you have already granted or refused without requesting any. For a moment it also adds invisible test boxes (to see whether an ad blocker hides them) and one blank, invisible frame (to compare built-in functions against a clean copy), and removes them at once. No network addresses.
Nothing is sent without a lab key. For every visitor this demo makes no network requests: WhiskerJS has no network code, the page has no analytics or third-party scripts, and the page's security policy allows no outgoing connection except to OpenStake's own lab server. The one exception is lab mode with a lab key, which only OpenStake's own test devices have: it sends this device's lab results (device label, time, browser and OS, session, visitorId, structuredId with its group hashes, library versions and the names and statuses of components that were not ok; no component values) to OpenStake's own server, diagnostics.whiskerjs.com. Without a lab key the page sends nothing.
It stays on this device. The library stores nothing. This page keeps a history of your runs (time, id, structured id, versions and component values), your device label and a session counter in this browser's local storage, so it can show whether your id stays the same across visits.
Clearing it: press Clear my history below to remove everything this page stored, or clear this site's data in your browser settings.
Result
What WhiskerJS returned
Loading WhiskerJS...
visitorId
First run on this device
version
-
signalsVersion
-
idVersion
-
duration
-
components ok
-
session on this device
-
structuredId
one short hash per signal group, so two runs can be compared group by group
The format is the idVersion, then one 12-character hash for each group, joined by underscores. Each hash covers only that group's components, so a new GPU driver changes the gpu part and leaves the rest alone.
Integrity flags
signs of automation or tampering; WhiskerJS reports them, your server decides
What every flag means
Components
Every component WhiskerJS reported, with what it measures, its status, the reason when it is not ok, whether it counts in the visitorId, and its value.
Component
Status
Reason
In id
Value
What the statuses mean
ok
The value was collected.
unavailable
The browser does not offer the API, or it gave nothing.
blocked
The API refused, threw an error or returned an empty result.
noisy
Two renders differed: the browser adds random noise, so the value is left out.
excluded
Not collected, because this browser is known to fake or randomise it, or the page asked.
timed_out
It took longer than its time limit.
This library version adds no new status, but it adds reason codes. The one you are most likely to see:
skipped
Shown as unavailable with this reason: WhiskerJS chose not to read the signal in this browser. audio_latency is only read in Safari and on Android, because elsewhere opening an audio device without a tap makes the browser print an autoplay warning. Nothing is wrong with your browser.
unknown
A component gave a reason WhiskerJS does not recognise, so it reports this one instead.
Components marked new arrived with this library version. Some report a plain word instead of a measurement: none means nothing was found (no ad blocker, no Apple Pay), and canvas_readback reports exact when a test pixel reads back unchanged or altered when something adds noise to canvas reads. In ua_client_hints, he=blocked means the site's policy refused the detailed hints.
"In id: yes" means the component is part of the visitorId. A component that is not ok still counts, as a fixed "missing" marker, so a signal that is blocked in one run and timed out in the next gives the same id. Digests are the first 128 bits of SHA-256, made in your browser.
Stability
This device, visit after visit
Each run is kept in this page's own local storage on this device. The library stores nothing; the page does, so it can compare. Newest first, with the structuredId groups and the components that changed since the run before. Runs made with a different library version are never compared: a new version is expected to give a new id, so the list marks the boundary instead.
This browser does not let the page use local storage (for example a private window), so runs are not remembered after you leave.
Lab testing mode
Measure it on your own devices
Give this device a label, for example "Windows Chrome" or "iPhone Safari".
Load the page three times on each device (reload it, or close it and open it again), and after each load press "Copy result line". With a lab key saved on this device, every run is sent to the lab log automatically instead.
After a browser update, run it again on that device.
Paste every line into one sheet. The lines are tab separated, so each value lands in its own column; "Copy header line" gives the column names.
Remembered in this browser only.
Session-Goes up by one each time the page loads.
Lab key saved on this device.
Only for OpenStake's own test devices. Kept in this browser's local storage only and never shown again. With a key and a device label, each run is sent to OpenStake's lab log.
Result line preview. Browser and OS as this page detects them: -