Quickstart
From zero to a server-verified visitor ID in 6 steps. You need a browser page, a backend that can make one HTTP call, and about ten minutes.
1. Get your API keys
Grab both keys from the dashboard under API keys. The public key (vp_pk_...) goes in the browser; the secret key (vp_sk_...) stays on your server. If you are running the stack locally with docker compose up, a demo pair is pre-seeded:
# Seeded by the local docker compose stack (API on http://localhost:8080)
NEXT_PUBLIC_VERIPRINT_KEY=vp_pk_demo_public_key
VERIPRINT_SECRET_KEY=vp_sk_demo_secret_key2. Install the SDK
npm i @veriprint/sdk3. Identify in the browser
Create a client once and call identify(). The call collects device signals, posts them to the API, and resolves in one round trip.
import { Veriprint } from '@veriprint/sdk';
const vp = new Veriprint({ apiKey: 'vp_pk_demo_public_key' });
const visitor = await vp.identify();
console.log(visitor.visitorId); // "vp_9f2c31e8a4d0"
console.log(visitor.confidence); // 0.94: a 0..1 score, varies per request
console.log(visitor.bot.result); // "notDetected"
console.log(visitor.latencyMs); // round-trip time measured by the SDKPrefer a one-shot call? import { identify } from '@veriprint/sdk' and await identify({ apiKey }) does the same thing without holding an instance.
/api/veriprint/v1/identify on your own origin by default, so the request is not blocked as third-party traffic. Point it elsewhere with the endpoint option. For local dev, use endpoint: 'http://localhost:8080'. After each response the SDK writes the visitor ID into a cookie, localStorage, and the Cache API, so identity re-anchors after any one store is cleared.4. The response shape
Every identify call (SDK or raw HTTP) resolves to the same JSON:
{
"visitorId": "vp_9f2c31e8a4d0",
"requestId": "vpr_01j8x2m9k4",
"confidence": 0.94,
"confidenceLevel": "high",
"ip": "203.0.113.42",
"geo": {
"country": "Germany",
"countryCode": "DE",
"region": "Berlin",
"city": "Berlin",
"latitude": 52.52,
"longitude": 13.405,
"asn": 3320,
"asnOrg": "Deutsche Telekom AG",
"isDatacenter": false,
"isTor": false
},
"incognito": false,
"bot": {
"result": "notDetected",
"type": null,
"score": 0.02,
"reasons": []
},
"vpnLikely": false,
"firstSeenAt": "2026-05-03T09:12:44.000Z",
"lastSeenAt": "2026-07-16T14:03:12.000Z",
"visitCount": 23,
"matchedVia": ["cookie", "fingerprint"]
}confidence is computed per request. Treat it as a score to threshold on, not a constant. matchedVia tells you how the visitor was recognized this time: anchor stores (cookie, localStorage, cache), the fingerprint similarity match, or new for a first sighting.
5. Verify server-side
The browser response is convenient but spoofable. A hostile client can claim any visitorId or report bot.result: "notDetected". Before acting on it (blocking a signup, skipping a CAPTCHA), have your backend fetch the authoritative record by requestId using the secret key:
curl http://localhost:8080/v1/events/vpr_01j8x2m9k4 \
-H "x-api-secret: vp_sk_demo_secret_key"
# or equivalently:
# -H "Authorization: Bearer vp_sk_demo_secret_key"{
"requestId": "vpr_01j8x2m9k4",
"identification": {
"visitorId": "vp_9f2c31e8a4d0",
"confidence": 0.94,
"bot": { "result": "notDetected", "type": null, "score": 0.02, "reasons": [] },
"...": "the full identify response, exactly as computed server-side"
}
}A public key here returns 401; an unknown requestId returns 404. Compare the verified identification.visitorId against whatever the client claimed. A mismatch is itself a strong fraud signal.
6. No JavaScript? Call the API directly
POST /v1/identify is plain JSON over HTTP, so non-JS backends and native apps can call it directly with whatever signals they can collect. Fewer signals means lower confidence, but the contract is identical:
curl -X POST http://localhost:8080/v1/identify \
-H "x-api-key: vp_pk_demo_public_key" \
-H "content-type: application/json" \
-d '{
"signals": {
"timezone": "Europe/Berlin",
"platform": "MacIntel",
"hardwareConcurrency": 10,
"deviceMemory": 16,
"languages": ["de-DE", "en"]
},
"anchors": { "cookieId": "vp_9f2c31e8a4d0" },
"url": "https://example.com/checkout",
"sdkVersion": "raw-http"
}'