PerimeterX is now HUMAN, and here is what its bot detection checks
A button that says "Press and hold" sits where the page should be, and the cookies on the site start with _px. That is HUMAN's Bot Defender, the product that used to be sold as PerimeterX. The two companies merged under the HUMAN name, and HUMAN's documentation for Bot Defender still lists the _px cookies.
HUMAN's documentation describes the moving parts in some detail. This post follows it, and leaves out anything it does not say.
Three parts: sensor, detector, enforcer
HUMAN splits Bot Defender into three components, and knowing which one you are dealing with explains most of what you see.
The Sensor is a JavaScript snippet inserted into the site's pages. HUMAN says it gathers data about the device, user behaviour and network activity, and sends it to HUMAN.
The Detector runs in HUMAN's cloud. It "evaluates sensor and enforcer data in real-time using machine learning and behavioral analytics" and returns a risk score to your browser in "a secure and encrypted token".
The Enforcer is a module the site installs on its web application, load balancer or CDN. It is the part that actually allows, blocks or challenges. For each request it reads the command from a cookie. If that cookie is missing, expired or fails validation, the enforcer falls back to a synchronous server-to-server call to HUMAN before answering.
The score itself is documented in HUMAN's API reference as "a scale of 0-100, where 0 is not a bot and 100 is a bot". The action returned with it is one of four: a allow, c CAPTCHA, b hard block, r rate limit.
What the _px cookies are for
HUMAN publishes a full table of the cookies and storage keys Bot Defender uses. The ones you will see most:
| Name | HUMAN's description | Lifetime |
|---|---|---|
_px, _px2, _px3 |
maintain a session with HUMAN | 5.5 minutes |
_pxvid |
browser detection, telling real users from bots | 1 year |
_pxhd |
server-side detection | 1 year |
_pxde |
data enrichment such as access-control status | 5 days |
_pxff_* |
browser-detection feature flags | 1 day |
pxcts |
cross-tab session | session |
HUMAN also lists px_hvd in local storage as a hashed visitor ID, and px_fp in session storage as a fallback store for fingerprint data.
One more line from that page matters for automation. HUMAN's cookies are not set HttpOnly by default, because "Sensor needs to access HUMAN cookies". The sensor in the page reads and writes them itself.
The press and hold challenge
The Human Challenge is HUMAN's CAPTCHA replacement. Its documentation describes a button users "need to press, hold, and release" to prove they are not a bot, and adds that "the amount of time users need to hold the button varies, and only a human can tell what that amount of time is". Sites can configure its look and options, and it is deployed through the enforcer.
Treat the challenge as a result, not as the obstacle. By the time it appears, the enforcer has already decided your score is too high to pass silently, and a solved challenge does not change why.
Playwright and PerimeterX
A Playwright script that works once and then gets challenged has several explanations in HUMAN's own documentation:
- The session cookie is short.
_px3and its siblings live 5.5 minutes. A script that idles longer than that comes back with an expired token, and the enforcer has to ask HUMAN's servers again. - A fresh context has no history.
_pxvidand_pxhdare meant to last a year. A Playwright run that starts from a new, empty context every time throws them away and is always a first-time visitor. Our post on persistent contexts in Playwright covers how to keep them. - Blocking the sensor is visible. Routing rules that drop third-party scripts or strip cookies stop the sensor from writing its cookies, so the enforcer has no cookie to read and falls back to its server-side call.
- Sharing a jar links identities.
_pxvidexists to recognise a browser. Copying it into several accounts tells HUMAN they are one browser.
For a legitimate multi-account setup, the expectation is simple: each identity keeps its own _px state, built by its own visits, from an exit address that fits it.
When we are not the answer
If you are testing your own site behind HUMAN, the clean fix is an allowlist for your test traffic in the site's own configuration, not a browser that looks like a customer. If you run one account, a normal browser is correct. And if the enforcer returns b from the first request on every browser you try, the address or the request is the problem, which no browser fixes. AntiBrow gives each identity a separate local profile with its own cookies and an engine-level fingerprint, and local profiles are free and unlimited. That covers per-identity state, not reputation.
Check it yourself
Open DevTools on a protected site, go to Application, and look for _px3 and _pxvid. Note the expiry on each, close the browser, reopen the same profile, and check that _pxvid is still there. For how this fits with other vendors, see how anti-bot systems work and the Cloudflare version of the same question.
Sources, fetched 2026-10-22: HUMAN cookies and web storage, Bot Defender overview, Risk API request reference, Human Challenge, SecurityWeek on the merger.
Try it on the free tier.
Unlimited local profiles, no credit card. Check it against the detectors yourself.