Every identification, live
New events appear within seconds, with the visitor, the external ID and when.
Know a returning browser even in incognito or with cookies cleared, catch bots and spoofed devices, and confirm every result on your server before you act on it.
See what we can tell about this browser. Running the demo sends its signals to us and stores an ID in it.
In the API for your code, and in the dashboard for whoever reviews the case.
New events appear within seconds, with the visitor, the external ID and when.
Automation, headless browsers, software rendering, replaced natives and time zones that don't match.
A device lists every external ID seen on it, so multi accounts stand out.
The browser only gets a request ID. Your server fetches the event with its secret key and decides.
Delete an external ID and every event and device link of it is gone.
No plans or commitments. After each billing cycle you pay for the identifications you used, each with every signal, the server API and the dashboard.
See plans and every price →Prices shown do not include applicable taxes or fees (e.g. VAT).
The browser gets a request ID, your server gets the whole story.
One script tag served by the api, or a typed ES module from npm.
<script src="https://zenocdn.net/agent.js"></script>
<script>
const agent = FingerprintAgent.start({ endpoint: 'https://zenocdn.net', publicKey: 'pk_...' })
</script>Start it when the form opens, get a request ID once the user logs in.
// After a successful login:
const { requestId } = await agent.get({ externalId: user.id })
await fetch('/api/login/verify', { method: 'POST', body: JSON.stringify({ requestId }) })Read the event with the secret key and decide. The browser never sees a flag.
const response = await fetch(`https://api.zeno.id/events/${requestId}`, {
headers: { 'Auth-API-Key': process.env.FP_SECRET_KEY },
})
const event = await response.json()
if (event.bot === 'bad' || event.riskScore >= 15) {
throw new Error('Review this login')
}GET, PATCH and DELETE on /events, /visitors and /external-ids, with one header.
pk_ and sk_ prefixes with a checksum; secret keys are stored as a hash and shown once.
Filter by visitor, external ID, IP, flag, bot verdict, risk score and date.
DELETE /external-ids/{id} removes every event and device link of that ID.
Yes. The agent is a plain ES module without dependencies, so it runs in React, Svelte, Vue or no framework at all. Without a bundler, load /agent.js and use the global FingerprintAgent.
No. Identical devices, like the same phone model on the same OS, have the same fingerprint, so a browser without its stored ID can be matched to another's visitor ID. Treat it as a lead to review together with the external IDs, flags and connection.
More than 100 device signals: canvas, WebGL, audio, fonts, screen, hardware, locale, plugins and automation leftovers. It never reads WebRTC network addresses.
Identification pauses quietly: the agent resolves with capped instead of a request ID, so your users never see an error and your login keeps working. Set budgets per day, week or month, and a spend limit per key. Nothing else is rate limited.
You get your money back. Not satisfied in the first three months after your first paid bill? We refund everything you paid in that time, no questions asked.
In the EU, in AWS eu-west-1. Events are kept until you delete them, or for 1, 3 or 5 years if you pick that, and one API call erases everything stored for one of your users.
Pay as you go, every signal included.