One visitor ID, however they come back
The agent turns more than 100 device signals into a visitor ID on the server. Incognito, cleared cookies and browser updates don't make a new visitor.
What a returning visitor can change
The ID is the device, not the cookie and not the connection.
| They come back with | Same visitor ID | Why |
|---|---|---|
| A private or incognito window | Same | Storage is empty, the hardware isn't. |
| Cleared cookies and site data | Same | The hardware anchor and the fingerprint still match. |
| A browser update | Same | A new version moves a few signals; fuzzy matching absorbs it. |
| A VPN or a new IP address | Same | The IP is no part of the ID. It shows up in the flags instead. |
| A new account on the same device | Same | That's how multi accounts show up: one device, many external IDs. |
| Another browser on the same device | New visitor | Every browser renders differently, so it's another fingerprint. |
| Another device | New visitor | The ID is the device. |
Matched in order
Each identification is checked against the project's visitors from the surest match down, and the event says which one held.
- Stored ID
- The ID the agent kept in storage and a first-party cookie, while the hardware still matches.
- Hardware anchor
- Graphics, cores, memory and platform, which a browser update or cleared storage doesn't change.
- Known fingerprint
- The exact same signals seen before in your project.
- Fuzzy matching
- Component by component against recent visitors on the same hardware, with a margin over the next best.
- Noise aware
- Canvas and audio are left out when a browser randomises them, like Brave and private windows.
import { start } from 'zeno-id'
const agent = start({ publicKey: 'pk_...' })
// A stable ID per device, and whether it was seen before.
const { visitorId, returning, requestId } = await agent.get({
externalId: user.id,
action: 'login',
})More than 100 signals
Collected from scratch, without WebRTC network addresses.
Rendering
Canvas, WebGL vendor, renderer, extensions and parameters, the WebGPU adapter and audio.
Device
Screen, color depth, pixel ratio, cores, memory, touch, platform, client hints, fonts and voices.
Settings
Time zone, languages, calendar, media preferences, storage quota and permission states.
Integrity
Automation leftovers, replaced natives and values that differ between the page, a worker and an iframe.
Honest about the limits
An ID you can build a decision on because it says how sure it is.
One ID per project
The ID is hashed with your project, so the same device has another ID everywhere else. Nobody can follow your visitors across services.
A confidence on every event
How sure the match is, from 0 to 1. A fuzzy match on a common device scores lower than a stored ID on rare hardware.
A lead, never proof
Identical devices, like the same phone model on the same OS, can share an ID. Review a shared ID together with the external IDs, flags and connection.
Identify your first visitor today
Install the agent, read the event on your server, and you're done.