How Akamai scores a session
Akamai scores at two layers. JA4+ at the EdgeWorker fires before HTML is served — the TLS handshake alone can produce a block. If the request passes that layer, the page loads with an inlined or near-inlined sensor.js script that runs the deeper checks: canvas hash, WebGL renderer, AudioContext, navigator properties, Battery API, and a probe that fetches 60 known chrome-extension:// URLs. Real Chrome users have at least a few extensions installed (uBlock Origin, 1Password, LastPass); a headless browser fails all 60 simultaneously, which is statistically impossible for a real user.
The script POSTs collected signals to /_bm/data. Only after a successful POST does _abck flip from ~-1~ to ~0~. Protected XHR endpoints check the cookie state — a request with ~-1~ gets 412 Pardon Our Interruption regardless of everything else.
What does and does not work
Does not work: headless Chrome (no GPU, WebGL context is null), SwiftShader (device ID 0x0000C0DE is blocklisted), playwright-stealth (Function.toString() exposes JS patches), Page.addScriptToEvaluateOnNewDocument injection (CDP timing artifacts visible), datacenter proxies of any kind, rotating residential mid-session (resets trust accumulation).
Does work: finding the mobile or GraphQL backend first (often unprotected — confirmed on a major retailer with a direct GraphQL endpoint), curl_cffi with impersonate="chrome131" for medium-strength deployments, Go-level TLS reimplementation (e.g. akamai-v3-sensor called from a Scrapy spider via a sidecar HTTP service) for hard deployments, CloakBrowser with real extensions loaded for the 60-probe check.
Session hygiene that matters
Akamai's multi-request scoring punishes inconsistency more than other vendors:
- Use a single ISP static residential IP for the entire session — never rotate mid-flight.
- Warm up: visit homepage, dwell 2–3 seconds, scroll, then navigate to the data URL.
- Match
Accept-Languageto the proxy country. - Reuse cookies across requests — trust builds from
_abckcontinuity.
