How PerimeterX scores requests
All five vectors must pass simultaneously: TLS fingerprint, IP reputation, HTTP header order and content, JavaScript fingerprint (canvas, WebGL, audio), and behavioural signals (mouse, scroll, dwell). Fixing only one or two has zero effect — the unified score requires the full set. This is unlike Cloudflare (where TLS plus IP gets you a long way) or DataDome (where IP weight is dominant).
The fingerprint is sent in the _px3 cookie and a POST to collector-PXxxxxxx.perimeterx.net. The "Human Challenge" — a press-and-hold button — is the visible fallback when the score is borderline; a hard block returns 403 with no challenge.
The network effect
Because HUMAN ingests signals from 29,650 sites simultaneously, a fingerprint that gets flagged on one customer is automatically lower-trust on all others. The practical implication for scrapers: never reuse a browser fingerprint across different protected domains. Generate a fresh canvas hash, WebGL renderer, and TLS profile per session per target. Camoufox's per-instance fingerprint randomisation handles this if you spin up a new browser instance for each domain.
What works
Address all five vectors at once:
- TLS:
curl_cffiwith current Chrome impersonation, or a real Camoufox / Chrome browser. - IP: residential or mobile. Datacenter is dead on PerimeterX regardless of fingerprint.
- Headers: match Chrome's exact order and casing —
curl_cffihandles this. - JS fingerprint: Camoufox or CloakBrowser — JS patches are detected via Function.toString().
- Behaviour: realistic warm-up navigation, Bezier-curve mouse paths (Botasaurus), human-like timing.
Managed APIs (Bright Data ASP, Zyte) handle all five transparently at the cost of per-request pricing. For high-volume scraping the engineer-time crossover usually favours the managed option.
