LayerSift documentation
A persistent visitor ID for every browser and every handset, plus Smart Signals for bots, VPNs, proxies, Tor, incognito, tampering, virtual machines, remote control, root and jailbreak, emulators, app cloning, instrumentation, MitM and location spoofing. One API call.
New here? Getting started has you identifying traffic in about five minutes.
Guides
| Architecture | How the whole system works and why — read this first |
| Getting started | Install the agent, read a result, verify it server-side |
| Core concepts | Visitor ID, confidence, environments, roles, keys |
| Browser agent | Every option, caching, the framework packages |
| Mobile SDKs | Android, iOS, React Native, Flutter |
| Smart Signals | What each signal means and how to act on it |
| Rules | Turn signals into a decision, without a deploy |
| Protecting sign-in | Credential stuffing and account takeover: at the edge with no code, from your server, or with the agent |
| Protecting checkout | Card testing and card cracking: what to send as card, and the declines that give them away; a checkout's steps taken faster than a person takes them (flow, or ANTIBOT_FLOWS at the edge) |
| Protecting text messages | SMS pumping and SMS bombing: blocks of numbers, codes never entered, texting only where you have customers |
| Measured against automation tools | Puppeteer, Playwright, Selenium, nodriver, Camoufox, Pydoll, Crawlee and the rest, as shipped and with their evasions: what each scores, what gives it away, and what is not caught yet |
| OWASP automated threats | The twenty-one threats OWASP names, and for each what is covered, what partly, and what not at all |
| Protecting forms from spam | Spam campaigns: one message from many senders, and what your moderators decided, without keeping a word of it |
| Protecting gift cards, vouchers and coupons | Codes guessed and PINs cracked: what to send as code, and the refusals that give them away |
| Protecting stock from being held | Carts, seats and bookings held and never bought: what to send as hold, and the lapses that give it away |
| Protecting limited releases from scalpers | The line, the cart and the checkout of a drop: one order per door, however the address is rewritten |
| Virtual waiting rooms | Queue-it-style rooms where a spot in line is a verdict with a ticket on it |
| Page scripts | PCI DSS 4.0's 6.4.3 and 11.6.1: every script your payment pages run, authorized with why, and word when a new one runs — from the agent or the browser's own report-only policy |
Reference
| Server API | Read, search, label and delete identifications |
| Server SDKs | Node, Python, Go, Java, PHP, .NET, Ruby — and their middleware for Express, Next.js, Django, Flask, FastAPI, Rails, Spring, ASP.NET Core and PSR-15 |
| Webhooks | Delivery, signatures, retries |
| Log streams | Every assessment and identification, as it happens, to Splunk, Datadog or your own HTTPS collector |
| Sealed results | Skip the round trip without trusting the client |
| What the agent stores | Every cookie and storage item it writes, for your cookie notice; what turns each off; where consent questions start |
| Management API | Provision from a script |
| User provisioning (SCIM) | Okta, Entra ID, OneLogin and JumpCloud create, update, deactivate and remove members |
| Terraform provider | Environments, rules, filters, webhooks, log streams and waiting rooms as code |
| OpenAPI | Every endpoint as an OpenAPI 3.1 document, generated from the code and checked in CI |
| Errors | Every code the API returns |
Deployment
| First-party integration | CDN proxy and custom subdomains, so blockers have nothing to match |
| Reverse proxies | nginx, Traefik, Caddy, Envoy and Kubernetes: the edge as a forward-auth service your own proxy asks |
| WordPress and WooCommerce | A plugin: sign-ins, comments, XML-RPC, REST and checkout assessed before WordPress acts |
| Laravel | Middleware: sign-ins with the starter kits' forms by default, the address Laravel reads, and $request->antibot() |
| Symfony | A bundle: the decision on the request event, sign-ins from form_login's redirects, and the address Symfony reads through framework.trusted_proxies |
| Spring Boot | A starter: the client, guard and filter from antibot.* properties, ordered ahead of Spring Security, and the address Spring reads through server.forward-headers-strategy |
| Environments | Keep development, staging and production apart |
| Launching | The steps from this repository to a service the public can sign up to, in order, with the check after each |
| Production checklist | The settings that depend on what is in front of the app, and what assumes there is only one copy of it |
| Releasing the SDKs | Versions that agree, a tag, and the registries the release workflow publishes to |
| Billing | The trial, Pro and Enterprise; what a billable call is; setting Stripe up |
| Deployment architecture | One stack per data region (US, EU, Asia-Pacific) chosen at sign-up, what fails and what it costs, and the providers compared |
| Privacy | Identify without retaining IP addresses, and how long identifications are kept |
Research
| PerimeterX public analysis | Everything known about PX from patents and published research — and how each mechanism maps to this codebase |
The one thing worth reading first
A result from a browser is a claim, not a fact. The agent runs on a machine
you do not control, so anything it reports can be edited by whoever owns that
machine. Every decision that matters should be made from a result your own
server fetched — either by calling GET /api/v4/events/{requestId}
with a secret key, or by opening a sealed result.
The rest of these docs assume you are doing that.