Identify the device,not the cookie.
One verify call fingerprints the browser and returns a 16-character device id scoped to your project, with the confidence behind it.
The same id came back twelve times
The count and the dates arrive with the id, so a repeat visit needs no lookup on your side.
af6aaf8b92b2233a
Every visit arrived as a new browser.
The id comes with the signals that produced it
{
"action": "ALLOW",
"is_bot": false,
"score": 0,
"issued_at": 1785942067,
"request_id": "d1e23499e6c16c6",
"schema_version": 5,
"risk": { "score": 17, "level": "low", "reason_codes": ["TAMPERED_ENVIRONMENT", "ANTI_DETECT_BROWSER"] },
"identity": { "device_id": "af6aaf8b92b2233a", "confidence": 100, "returning": true },
"device": { "class": "desktop", "browser_family": "chrome", "...": "..." },
"network": { "country": "EE", "connection_type": "residential", "...": "..." },
"integrity": { "tampered": true, "anti_detect_browser": true, "...": "..." },
"behavior": { "mouse": { "verdict": "human", "human_score": 91, "...": "..." } },
"velocity": { "device": { "last_1h": 3, "last_30d": 12, "...": "..." } },
"flags": { "bot": false, "anti_detect_browser": true, "...": "..." }
}One field to key everything on
import { useTrustSig } from "@trustsig/react";
const { getResponse } = useTrustSig();
const { token } = await getResponse();import { TrustSig } from '@trustsig/server';
const ts = new TrustSig({ secretKey: process.env.TRUSTSIG_SECRET_KEY });
app.post('/login', async (req, res) => {
const token = req.headers['x-trustsig-response'];
const { action, identity } = await ts.verifyRemote(token);
// Fail closed: proceed only on an explicit ALLOW.
if (action !== 'ALLOW') {
return res.status(403).json({ error: 'Access denied.' });
}
// degraded marks an id a large cohort shares, so it names a crowd.
if (identity.degraded) {
return completeLogin(req, res);
}
// Your table, keyed on the id the verdict carries.
await devices.bind(req.body.email, identity.device_id, {
first_seen: identity.first_seen,
sightings: identity.sightings,
});
return completeLogin(req, res);
});It tells you when the id is weak
- A shared fingerprint names a crowd
identity.degraded - The browser gave up a surface millions of machines share, so the id names a cohort rather than a machine.
- A wiped profile reads as a new machine
integrity.tampered - The integrity findings an anti-detect build leaves behind still come back in the same response.
- A second laptop costs the attacker a laptop
identity.linked_devices - Different hardware, different id. The graph reports once it has resolved more than one id to one machine.
- A sighting is one request
velocity.device - An ordinary customer reading your pricing page produces a dozen in one session.
The questions a device id raises
identity.device_id, 16 hex characters, one machine, scoped to your project. The same verdict carries identity.confidence, first_seen, last_seen, sightings and returning, so a repeat visit arrives already counted rather than as a lookup you have to run.
A fingerprint is the raw surface a browser exposes, and it drifts on every driver update, font install and screen change. The id is resolved from that surface inside an identity graph, so ordinary drift lands on the id that was already there. identity.confidence reports how much of the surface the browser actually gave up.
At the collection layer, yes: the scan reads the same surface a device fingerprinting library reads, canvas, WebGL, fonts, hardware and the rest. It resolves that surface to a standing id instead of hashing it, which is why a driver update does not produce a new device.
No. Device identity is computed from telemetry rather than written to the visitor's machine, so there is nothing to clear and nothing to store. The id is scoped to one project, so the same machine reads differently everywhere else and cannot be joined against another site. See the privacy note.
Yes. Cleared cookies, cleared site data and a private window all leave identity.device_id where it was, and the private window is reported on its own as device.incognito rather than as a change to the id.
You can. identity.degraded marks an id whose fingerprint a large cohort shares, so a block that would land on a crowd rather than a machine is visible before you place it.
Packages ship for the browser, React and Node. Everything else posts the token to the verify endpoint and reads the same JSON, which is what the PHP and Python examples in the documentation do.
Put a device id on your next request.
The id lands in your logs on the first request after you install.