Know the device,
not the cookie.
Sphoro Score identifies a returning browser with no cookie and nothing written to storage — and keeps identifying it after the browser updates, the GPU driver changes and three new fonts get installed.
10,000 identifications a month on the free tier. No card.
Runs entirely on this page — no request leaves your browser.
Collecting signals is easy. Three other things are not.
Every fingerprinting library reads the same browser APIs. What separates one that works from one that looks like it works is how it handles these.
Drift
A device's fingerprint changes constantly. Browsers auto-update, drivers update, fonts get installed, windows get resized, people travel. An exact hash match answers is this byte-identical — a question nobody asked.
Scale
Comparing a new collection against every stored one is O(n) and stops working somewhere around a hundred thousand rows. The interesting engineering is retrieving the right candidates without a scan.
Adversaries
The client is hostile by construction. Everything it says can be a lie, and the useful signal is usually in the contradictions between lies rather than in any single value.
Identity is a decision, not a hash.
Two fingerprints, because they answer different questions
The canonical fingerprint covers every normalised attribute and changes on any drift — it is an exact-identity key. The stable fingerprint covers only hardware-bound attributes and survives a browser update.
Neither is the device id.
Blocking keys keep matching sub-linear
Each fingerprint emits four coarse keys, each chosen to survive a different kind of drift — one survives a hardware-report change, one a driver update that alters rendering, one both.
Two collections from one device share at least one key even after several attributes move, so retrieval is an index lookup returning tens of rows. Measured recall after realistic drift: 100%.
Three bars, not one threshold
A candidate binds only if it clears all three: score ≥ 0.82 weighted similarity, coverage ≥ 0.5 of comparable weight, and a margin of 0.05 over the next-best device.
When two devices score within noise of each other, the honest answer is that the fingerprint cannot separate them. Binding to whichever won by 0.001 silently merges two people.
Every score ships with its evidence
35 rules across eight categories. Each reports severity separately from confidence — a software GPU renderer is strong evidence of virtualisation and a normal sight on an old laptop.
A score without its evidence cannot be disputed, audited, or used to tune the rules that produced it.
One script tag, or one signed request.
The SDK is 21 KB gzipped with no dependencies. Every collector is individually time-boxed, so a hostile or wedged browser API cannot hold your checkout open.
In the browser
<!-- 21 KB gzipped, no dependencies --> <script src="https://score.sphoro.com/score.js"></script> <script> const client = Sphoro.createClient({ endpoint: 'https://api.score.sphoro.com', publishableKey: 'pk_live_…', }); const { deviceId, riskScore, confidence } = await client.identify(); if (riskScore >= 75) stepUpAuth(); </script>
From your backend
// HMAC-signed. The signature binds method, path, // timestamp, a single-use nonce and the body. POST /v1/risk x-ds-key: sk_live_… x-ds-timestamp: 1785000000 x-ds-nonce: a1b2c3d4e5f60718 x-ds-signature: v1=… { "collection": { … }, "serverContext": { "ipIsAnonymiser": true, "geoTimezone": "America/Sao_Paulo" } }
Nothing is stored in the visitor's browser
No cookie, no localStorage value, no IndexedDB record, and no permission prompt. Storage APIs are probed for availability — each probe key is namespaced and removed immediately. Identification is entirely by device characteristics.
Measured, not claimed.
End-to-end against PostgreSQL with an 8,000-device corpus. The engines account for under 5% of total latency — the rest is the database, which is the shape you want.
| Stage | p50 | p95 | p99 | Budget |
|---|---|---|---|---|
| Fingerprint computation | 0.053 ms | 0.060 ms | 0.073 ms | 200 ms |
| Match against 50 candidates | 0.117 ms | 0.129 ms | 0.162 ms | 100 ms |
| Risk evaluation, 35 rules | 0.026 ms | 0.032 ms | 0.046 ms | 50 ms |
| End-to-end, returning device | 0.93 ms | 1.85 ms | 3.53 ms | 250 ms |
| End-to-end, drifted device | 3.95 ms | 6.42 ms | 10.69 ms | 250 ms |
The score is never withheld.
Free gets the fraud score and the category breakdown. What it does not get is the per-signal evidence explaining why. A number you cannot act on is not a product.
Free
Evaluate device intelligence on a single client account.
- 1 client account
- 10,000 identifications / month
- 60 requests / minute
- 30 day retention
- Fraud score and category breakdown
- Per-signal evidence
- Device history API
- Community support
Team
Production traffic across a book of client accounts.
- 10 client accounts
- 250,000 identifications / month
- 1,200 requests / minute
- 180 day retention
- Full per-signal evidence
- Device history API
- Webhooks
- Email support
Enterprise
Unlimited scale, full signal retention, tunable matching.
- Unlimited client accounts
- Unlimited identifications / month
- 12,000 requests / minute
- 730 day retention
- Raw signal retention
- Custom match weights
- On-premise deployment
- Dedicated support
What Sphoro Score does not do.
A fraud platform that overstates itself is worse than one that does not exist. These are the real limits, stated before you integrate rather than discovered after.
Tor Browser, Firefox with resistFingerprinting and several privacy extensions inject per-call noise into canvas and audio, producing a new device on every page load. We detect the condition, collapse confidence and raise risk — but we cannot identify the device, and no honest implementation can.
Any single check is defeatable by a determined shim. The defence is breadth: patching all of them consistently is much harder than patching one flag, and inconsistency between them is itself the signal.
A device match is evidence, not proof of identity. Devices are shared, sold and cloned. Use the score as one input to a decision, never as the decision.
Datacenter, VPN and geolocation flags come from your backend. Bundling an IP database would mean shipping one that is stale on arrival.
Identify your first device in about five minutes.
Sign up, create a client, drop the script tag in. The free tier covers 10,000 identifications a month and needs no card.
Start free