Core concepts
Visitor ID
A stable identifier for a browser or a handset, derived from what the device looks like rather than from anything stored on it. Clearing cookies does not change it.
The agent collects 28 entropy sources — canvas geometry and text rasterisation,
a WebGL shader checksum, an audio oscillator, installed fonts, screen geometry,
codec support, engine-specific Math results, and more — hashes each one, and
sends the hashes. Your server never receives the raw values.
Matching is not a single combined hash. Each component carries a weight, and a device matches an existing visitor when either:
- the eight highest-stability components hash identically, or
- weighted similarity clears 82% and the five anchor components (canvas, fonts, WebGL, audio, screen) clear 60%.
That second rule is why a GPU driver update does not mint a new visitor, while a genuinely different machine does not collapse into an existing one.
Nothing identity is made of carries the browser's version except its client hints, a small weight, so a browser that has updated is still its visitor unless the release changed how it draws; and nothing of the hour, so a system that turns dark at sunset is the same visitor at night.
Brave draws its canvas, audio, cores, plugins and voices afresh every session, on purpose. For a browser that says it is Brave those five are left out of who it is, compared with a visitor that was Brave too: it is matched on the rest, and a restarted Brave is still its visitor. Against any other visitor nothing is left out, so saying it is Brave makes no browser easier to take for someone else.
The visitors it is compared with are, first, the one the browser's own hint
names: the agent keeps a signed hint of its visitor in the site's storage
(rememberVisitor) and sends
it with the next identification. Then those of the same coarse configuration
(operating system, engine, device type, colour depth, cores) seen last and,
when none of them is it, those seen lately from the same address.
The hint decides nothing by itself: the device must match its visitor by the two rules above, so a hint copied to another machine names a visitor that machine does not match. It is signed for one environment and dies with the organization's session keys. What it adds is reach. Without it, a browser whose rendering drifted (a GPU driver, a browser update) is found only among the last few hundred of its configuration, which on a busy site is the last hour; with it, months later (in Safari, a week later — it deletes what scripts write after seven days with no interaction with the site — unless the first-party proxy keeps the hint as a cookie of the site's own, which it does not delete). Without it, too, a device that changes its configuration and its network at once (cores drawn afresh by Brave, say, on a train's Wi-Fi) is a new visitor, and so is a private window, or a browser whose site data was cleared, that drifted since.
A visitor's record follows its device: what it presents now is kept after an exact match, and after a near one that clears 90%; for a browser that matches by its own hint, one that clears 85%. The margin is what keeps a chain of devices, each near the last, from walking one record from one device to another — a hint can be copied, so it lowers the bar rather than removing it. So the record stays current for the private window, or the cleared browser, that comes later.
Devices alike in every component. Two iPhones of one model and system
version draw alike in everything a page can read, and so do a company's
laptops built from one image: by their components alone they are one device.
What tells them apart is where they are and what they keep. A visitor whose
browser has come back with its own hint keeps what it is given; while it has
been heard from in the last day, from another address, a browser that looks
the same but brings no hint is another device, and gets a visitor of its own —
which its own hint then names. A device is in one place at a time. Without its
hint, a browser is still its visitor when it comes from an address that
visitor was heard from (the same device's private window at home), when that
visitor has been quiet for a day (a browser Safari emptied after its seven
days), and when that visitor's browser never kept a hint (a script that clears
what it is given stays one device across the addresses it rotates through —
found among the last few visitors alike, which in a crowd of one common phone
are people's: there, without a hint, it is a newcomer each time, as each
newcomer is, and is left to what it does rather than given a crowd's history,
or the crowd its).
What this gives up: a private window opened on another network, while the
same device was in use elsewhere within the day, is a visitor of its own. What
it does not do: behind one address — an office's laptops from one image on its
one connection, a household's two phones of one model on its Wi-Fi — devices
alike are one visitor still. There, a browser without its hint may as well be
that visitor's own private window, and a private window must not be a way to a
new visitor. With rememberVisitor: false no browser keeps
a hint, and devices alike are one visitor wherever they are, as they look.
A visitor ID is not a person. Two people sharing a laptop are one visitor.
One person on a phone and a desktop is two. Use linkedId to tie your own
account id to identifications; use related visitors
to find devices that share one.
Confidence
Every identification carries confidence.score, from 0 to 1.
| Score | Reading |
|---|---|
| ≥ 0.99 | Exact match on the high-stability components |
| 0.6 – 0.99 | Matched with drift, the nearer the higher: a driver update changed the canvas |
| 0.5 – 0.95 | Newly minted (visitorFound: false): the richer the payload, the surer no device seen before was missed |
A payload that looks tampered with is scored at three quarters of that.
Treat a low score as "I am not sure who this is", not as "this is suspicious". A brand-new visitor is not a threat; it is a new visitor.
High Recall ID
A second identifier that leans the other way. The standard visitor ID prefers to mint a new id when signals are ambiguous, because being wrong about who someone is costs more than not knowing. That is right for a fraud decision and wrong for "welcome back" — a returning customer whose browser changed enough looks brand new.
The high-recall id weights durable components up (screen, CPU, platform, fonts, locale) and high-entropy ones down, and drops the anchor guard entirely. It never recalls less than the standard id does: a visitor the standard id recognises gets the high-recall id it had last time, however many devices like it, such as phones of one model, have come by since. It is off by default, enabled per organization in Settings, and carries no confidence score on purpose: a number would invite exactly the high-stakes use it is not for.
Browser only. Mobile identifications never receive one.
Suspect score
A weighted 0–100 summary across every signal. It is a documented rule set, not a trained model, so every contribution is auditable.
| Band | Typical handling |
|---|---|
| 0–29 | Allow |
| 30–69 | Watch, or step up on sensitive actions |
| 70–100 | Challenge or review |
Use it as a first cut. Use the individual signals when you need to explain a decision to a customer, because "your score was 74" is not an explanation.
Organizations, roles, members
Every tenant is an organization. People belong to many organizations through a membership that carries their role. An organization holds up to 50 environments and 200 API keys not revoked; one person creates up to 10 organizations a day.
| Role | Can |
|---|---|
| Viewer | Read identification data. Cannot see API keys or webhook signing secrets. |
| Member | + label events as fraudulent or legitimate; view API keys and webhooks for integration work |
| Admin | + manage keys, webhooks, members, settings, audit log, data purge |
| Owner | + delete the organization and transfer ownership |
Permissions are cumulative up the ladder. Two rules sit outside it because they are about who you may act on rather than what you may do: an admin can never modify or remove an owner, and nobody may grant a role above their own. The last owner cannot be demoted, removed or leave, so an organization can never end up with nobody who can administer it.
Invitations are mailed from LayerSift, up to 30 an hour and 100 a day for an
organization, and the same for each person sending them. Past that an
invitation is still made, but not mailed: Members shows its link to pass on
yourself. Names in invitations are written so no mail client turns them into
links (pay-back[.]example). To bring many people in at once, use
SCIM or the Management API's invitations, which return the links and
send no mail.
Two-factor sign-in. Anyone can turn it on under Security: add the setup key to an authenticator app (1Password, Google Authenticator, Authy…), confirm with a code, and save the ten recovery codes, which are shown once. From then on a right password alone opens nothing — it earns five minutes and five attempts to enter a code (or a recovery code) at the next step, from the same browser. A code is accepted once, a step either side of the current one for a phone's clock; recovery codes are single-use and stored hashed. Turning it off takes the password and a code. Every step is in the audit log. Owners and admins can mint secret keys and change what is blocked, so they are the accounts to protect first.
Passkeys are the other second factor, and the stronger one: add one under
Security (Touch ID, Windows Hello, a phone or a security key), and the second
step offers it before the code. A code can be phished — a fake sign-in page asks
for it and relays it within its thirty seconds — but a passkey cannot: the browser
binds what it signs to the page's origin, and the server refuses a signature made
anywhere but the dashboard's own. The first factor added, whichever kind, comes
with the recovery codes. In production passkeys need ANTIBOT_PUBLIC_URL, which
names the site they are bound to.
An admin can require it for the whole organization (Settings → Sign-in), once it is on for their own account. A member without it is then sent to Security to set it up and can use nothing else of that organization — its pages redirect there and its actions refuse — and nobody can turn theirs off while an organization they belong to requires it. Members shows who has it. Management API keys are not sessions and are not affected.
Single sign-on. An admin can connect the organization's identity provider —
anything that speaks OpenID Connect: Okta, Entra ID, Google Workspace, Auth0,
OneLogin, Keycloak — under Settings → Single sign-on. Register the redirect
URI shown there with the provider (scopes openid email profile), then enter its
issuer URL, client ID and client secret, the email domains it speaks for, and the
role people join as. Each domain needs a DNS TXT record before anyone on it is
sent to the provider: a provider can assert any address, so it is believed only
for domains the organization has proved it owns, and only one organization can
prove a given domain. People then sign in with Sign in with single sign-on on
the login page; the first time, their account and membership are made, the
membership taking a seat of the plan as an invitation does — with none free,
the sign-in is refused and says to ask an admin (an invitation already out to
the address holds its seat, and is accepted by signing in). An
account someone made earlier on that address with a password, which nobody had
proved, is claimed first — its password, second factors and sessions removed —
since whoever registered it may not be the person the provider vouches for —
an owner's too, so keep one owner on an address outside those domains as the
way back in. Removing
someone takes the provider and this organization — the next sign-in through the
provider brings them back otherwise.
The provider has to say the address is verified (email_verified). Entra ID
does not send that claim by default; add it as an optional claim, or the sign-in
is refused. A session that came through the organization's single sign-on meets
its two-factor requirement — how its people prove who they are is the provider's
to decide — but not any other organization's.
Require single sign-on turns passwords off for the domains: sign-in and sign-up
with a password are refused for those addresses, and their password sessions end.
The organization's owners keep their password, so there is a way in on the day the
provider is down. It can only be turned on after a sign-in has worked through the
connection. In production single sign-on needs ANTIBOT_PUBLIC_URL, which is
where the provider sends people back.
Environments
Development, staging and production live inside one organization, each with its own keys, visitors, events, rules, webhooks and filters.
The API key decides the environment. Nothing in a request payload names one, so a client cannot claim to be staging to dodge a production rule, and adopting environments needs no SDK change — you point a build at a different key.
Identity is scoped too. The same handset hitting staging and production is deliberately two visitors: a device you are testing with should never appear in production analytics.
See Environments.
Keys
| Kind | Prefix | Stored as | Grants |
|---|---|---|---|
| Public | pk_live_… |
verbatim | Creating events. Ships in clients. |
| Secret | sk_live_… |
SHA-256 hash | Reading identification data |
| Management | mk_live_… |
SHA-256 hash | Administering the organization, by scope |
A management key is deliberately a different credential from a secret key. Reading identification data and minting new credentials are different powers, and a leaked analytics token should not be able to grant itself more.
Decisions
If you use rules, every identification also returns a decision:
{ "decision": { "action": "challenge", "matched": ["High risk checkout"] } }
action is one of allow, flag, challenge, block. Every enabled rule is
evaluated so the dashboard can show all matches, but the first match in
priority order decides.
The engine recommends; it does not enforce. LayerSift never blocks your visitor. Only you know what the request was trying to do, so the decision stays on your side of the trust boundary.
Shared addresses
One address is often many people: a consumer VPN's server, iCloud Private Relay's egress, a Tor exit, a mobile carrier's NAT, an office, a campus. What a request assessment counts of the address — its pace, a trap link followed, what other sites and public blocklists said of it, the accounts, cards, numbers, codes, holds and posts tried from it, the pages fetched from it without the agent running — is then everyone's at once, and one scraper among them would get them all blocked.
An address is a crowd's when it is a privacy service's exit (a VPN's, a
relay's, Tor's — not a proxy network's own addresses, which are rented to
whoever pays), or when twenty devices or more ran the agent from it within the
hour in your environment, paid its proof of work and were not convicted
(rate.devicesFromAddress, for a rule). On a crowd's address:
- what is counted of the address brings a request up to a challenge and no
further — short of the block, where your block threshold is your challenge
threshold — and
ip:crowdsays where that lowered the score; - whoever passed the challenge is not asked again for it: what their own device did — accounts, failed sign-ins, cards, numbers, posts, counted by the session token's visitor from whatever address — stands in for the address's, and holds a browser working down a list to account (codes, and holds but for an item held again as each hold lapses, a passed challenge excuses anywhere, crowd or not);
- the per-address limits on the integrity key, identification, challenges, the pulse and the waiting room grow with it once spent: as much again for every two of its devices.
What the request itself says — a library's headers, an automation tool's name — what the device did, Spamhaus DROP and a request another site's Cloudflare Worker sent are weighed in full. A script that cannot pass a challenge is stopped either way. What a crowd does give way on is the address's own count: a farm of browsers that each pass the challenge and each stay under what one device may do — a few accounts, a few numbers, a few dozen posts an hour — is weighed as that many people, and caught by what it repeats (one message from many senders, one block of numbers, one card declined again and again) rather than by how much its address does.