Device fingerprinting that returns one stable visitor ID
Veriprint is a device intelligence API that returns a stable visitor ID and a risk signal for every browser. One POST /v1/identify call reads ~70 entropy sources from the browser and network, resolves them against every device we have seen for your app, and returns a visitorId with a confidence score in ~40ms p95. The score is computed per request, never hard-coded. Fingerprinting is probabilistic and we report it that way.
How does device identification work?
Six mechanisms, each one verifiable in the docs. Signals go in, weighted similarity comes out. No black box.
Fuzzy identity persistence
One stable ID that survives browser updates and cleared cookies.
Signals are weighted by how much they distinguish one device from another, so the GPU renderer, fonts, and render hashes decide identity while a match above 0.82 links. An EMA decay follows the device as it drifts.
Incognito & storage-independent
Recognize a returning device even in a private window.
Three durable anchors (cookie, localStorage, Cache API) plus a probabilistic fingerprint. Losing any one anchor re-links on the others.
Server-verified results
The browser can never spoof its own verdict.
GET /v1/events/:requestId returns the result WE computed, gated by your secret key. Public key in the browser, secret key on your server.
Bot & automation detection
Separate headless Chrome and Selenium from real users.
Weighted scoring over navigator.webdriver, plugin/permission anomalies, and UA/platform mismatch. Search engines are classified separately from evasive bots.
IP intelligence
Flag datacenter, VPN, and TOR traffic.
Geo + ASN resolution with a datacenter/hosting-range check; vpnLikely is true for cloud egress or a known TOR exit.
~40ms p95, one call
Fast enough for the login path.
A single POST /v1/identify returns id, confidence, geo, bot, and VPN signals. Rate-limited per key, Redis-backed, horizontally scalable.
What signals does browser fingerprinting read from a device?
Every signal is weighted by how stable it is in practice. Timezone and hardware survive browser updates; canvas and WebGL do not, so they count for less. That weighting is why the ID holds when individual signals drift.
- Canvas2D render hash. Low weight, drifts on browser updates
- WebGLGPU vendor, renderer, shader precision. Low weight
- AudioOfflineAudioContext output hash, ~30ms to collect
- FontsInstalled-font detection via measured glyph widths
- ScreenResolution, color depth, device pixel ratio
- TimezoneIANA zone plus offset. High weight, rarely changes
- HardwareCPU cores, device memory. High weight, tied to the machine
- IPResolved server-side, never trusted from the client
- GeoCountry and city from the IP, returned on every call
- ASNAutonomous system number and org name
- Datacenter / TORHosting-range check plus known TOR exit list; feeds vpnLikely
Network signals are resolved on our servers from the request itself. The browser never self-reports its IP, so a spoofed client cannot fake its network position.
How do you verify a result server-side?
The public key (vp_pk_...) runs in the browser and can be read by anyone. That is fine, because the browser result is only a hint. Before you block a signup or flag a login, fetch the server-verified copy with your secret key.
# Verify the browser verdict server-side before you act on it.
curl https://api.veriprint.dev/v1/events/req_9f2c81d4 \
-H "x-api-key: vp_sk_live_..."
// The response is the result we computed for that requestId:
// visitorId, confidence, bot, vpnLikely, gated by your secret key.
// A client can lie about its own verdict. It cannot forge this one.Two keys, two trust levels
vp_pk_... identifies from the browser. vp_sk_... reads the verified event from your server. The secret key never ships to the client.
requestId is the receipt
Every /v1/identify response carries a requestId. Pass it to your backend, exchange it for the record we stored, not the one the client claims.
Same shape, verified source
GET /v1/events/:requestId returns the identical payload (visitorId, confidence, geo, bot, vpnLikely) computed and stored server-side at identification time.
See your first visitorId in five minutes.
A free key with 20,000 identifications a month, no credit card. One POST, one ID.