The first time an Akamai-protected site stopped talking to me, it did not say no. It said nothing. Requests that had run green for eleven days started hanging for twenty-five seconds and returning a 200 with a body that contained a skeleton page and no data. No 403. No captcha. No log line anywhere that said blocked. My monitoring was watching HTTP status codes, so my dashboard stayed a cheerful green while the pipeline quietly filled the warehouse with empty rows.
That is the thing people miss when they go looking for a way to bypass Akamai Bot Manager scraping problems. They picture a wall with a gate, and they go hunting for the key. Akamai is not a gate. It is a scoring system that runs continuously across four independent layers, and its most common response to a low score is not rejection — it is degradation. You get slower responses, stale cache, partial payloads, or a page that renders for a human and returns nothing to a parser. By the time you notice, you have been shadow-throttled for a week.
This guide is about what those four layers actually measure, why the popular one-trick fixes stop working within days, and how to build a collection setup that survives. I am going to be blunt about one thing up front: there is no header string, no library flag, and no magic user agent that solves this. Anyone selling you a single line of code is selling you something that worked last quarter.
What Akamai Bot Manager actually is
Akamai sits in front of somewhere around a fifth of the web's serious commercial traffic — airlines, sneaker retailers, banks, ticketing platforms, big-box e-commerce. Bot Manager is the module that decides, per request, how much it trusts you. It runs at the CDN edge, which matters enormously: the decision happens before the origin server ever sees your request, so the site's own developers often cannot tell you why you are being blocked. They genuinely do not know.
The scoring is continuous and cumulative. Your session does not start at zero and get points added; it starts at a provisional score and gets adjusted as evidence arrives. A request from a clean residential IP with a plausible TLS handshake starts well. Three page loads later, if the JavaScript sensor has not posted anything back, that same session degrades. This is why so many scrapers work beautifully for the first few requests and then fall apart — you are watching a score decay in real time.
The four layers of the trust score
Every serious analysis of Bot Manager converges on the same four signal families, and it is worth naming them separately because they fail independently and they need different fixes:
- Network reputation — the ASN, the IP's history, whether it is a known datacenter range, how many other clients have recently hit this property from the same address.
- Protocol fingerprint — the TLS handshake (JA3/JA4) and the HTTP/2 frame settings your client sends before a single byte of your request is parsed.
- The JavaScript sensor — an obfuscated script that gathers a hundred-plus browser and device signals, encrypts them, and POSTs them back to the edge. This is what mints and refreshes the
_abckcookie. - Behavioural telemetry — pointer paths, key timing, scroll cadence, focus and blur events, the gap between a page loading and something being clicked.
Here is the load-bearing insight: these layers are checked against each other, not just individually. A perfect Chrome 140 user agent string paired with a Python requests TLS handshake is not two half-passes. It is an active contradiction, and contradictions score worse than an honest bot. The system is looking for internal consistency far more than it is looking for any particular value.
Layer 1: the network, and why it is the cheapest thing to fail
IP reputation is the first filter and the one most people get wrong by trying to save money. Akamai maintains a live view of address space, and datacenter ranges from the big cloud providers are labelled as such the moment they are allocated. You are not fooling anyone with an AWS Elastic IP. The address itself announces where it came from.
But reputation is more subtle than datacenter-versus-residential. A residential IP that has served four hundred requests to the same airline in the last hour is worse than a datacenter IP that has never been seen. Akamai correlates across its whole customer base, which is the structural advantage of a CDN — a proxy pool that got burned scraping a sneaker site is already suspect on a banking site, because the edge saw both.
Datacenter, residential, and mobile in practice
Datacenter proxies are fine for reconnaissance — checking whether a site is behind Akamai at all, mapping URL structure, testing your parser against saved HTML. They are essentially useless for sustained collection from a protected property.
Residential proxies are the working default. The important variables are not the marketing ones. What matters is: how many other customers share the pool, how long you hold a given exit, and whether the exit is geographically coherent with everything else about your identity. A US-English browser reporting America/New_York and exiting through a Bucharest residential IP is a contradiction the edge notices instantly.
Mobile proxies (real carrier NAT) carry the strongest reputation because thousands of genuine humans share each address, making blanket blocks expensive for the site. They are also slow, expensive, and often unnecessary. Reserve them for the handful of endpoints that genuinely refuse everything else.
The operational rule I have settled on: one exit IP per identity, held for the life of that identity. Rotating IP per request is a habit inherited from scraping unprotected sites, and on Akamai it is actively harmful. A session whose IP changes mid-flight while carrying the same _abck cookie is a screaming anomaly. If you want the full reasoning on pairing exits to identities rather than to requests, we go deep on it in the antidetect browser with residential proxies playbook.
Layer 2: the handshake, before your request even exists
This is the layer that quietly destroys most homegrown scrapers, and it is invisible if you are only looking at headers.
When a client opens a TLS connection, it announces its supported versions, cipher suites, elliptic curves, signature algorithms, and extensions — in a specific order. That ordering is a fingerprint. Hash it and you get a JA3, or the newer and more robust JA4. Akamai publishes JA4 client fingerprint settings in its own developer documentation, which tells you how seriously they take it: it is a first-class, configurable control surface for their customers, not an implementation detail.
The consequence is stark. Python's requests library uses OpenSSL with a distinctive cipher ordering. Node's axios has its own. Go's net/http has another. None of them look like Chrome, because Chrome uses BoringSSL with GREASE values and a particular extension order that changes with each major release. You can set your User-Agent header to Chrome 141 all you like — the handshake already said I am Python three round trips ago.
HTTP/2 tells the same story twice
HTTP/2 adds a second, independent fingerprint. Every client sends a SETTINGS frame at connection open with values for header table size, max concurrent streams, initial window size, and max frame size, plus a pseudo-header ordering and a stream priority scheme. Chrome's values differ from Firefox's, which differ from every HTTP library ever written. Akamai's edge reads them all.
So when someone tells you they solved detection by copying the request headers out of DevTools, they have matched one layer out of four and missed two that fire before the headers are read. There are TLS-mimicking libraries that patch this at the socket level, and they work — for a while, against a specific browser version, until Chrome ships a new build and your fingerprint becomes Chrome 138 in a world where Chrome 138 is extinct, which is arguably a worse signal than being obviously a script.
The structurally sound answer is to stop mimicking a browser handshake and start using one. A real Chromium binary produces a real BoringSSL handshake and real HTTP/2 settings, for free, forever, and it updates when the engine updates.
Layer 3: the sensor, _abck, and what the cookies really mean
If you open DevTools on an Akamai-protected site you will typically see four cookies: _abck, ak_bmsc, bm_sz, and sometimes bm_s or bm_sv. People treat these as tokens to be captured and replayed. That misunderstanding wastes more engineering hours than anything else in this space.
The cookie is a scoreboard, not a key
_abck is not a session key you can lift from a browser and paste into a script. It is a signed, structured value in which one segment encodes the current verdict — a ~0~ versus ~-1~ distinction that tells you whether the last sensor payload was accepted or rejected. It refreshes as new sensor data arrives. A commonly reported pattern is that the edge wants roughly three accepted sensor posts before a session is genuinely trusted, which is exactly why your first two requests succeed and the third one falls off a cliff.
bm_sz is generally a short-lived session cookie tied to the specific page context. ak_bmsc carries edge-side session state. Copy any of them into a client that then fails to keep posting valid sensor data, and the score decays until the cookie is worthless. You have not stolen a key; you have borrowed a scoreboard that resets when you stop playing.
What the sensor actually reads
The sensor script — usually served from a path containing something like /akam/ or a randomised endpoint, heavily obfuscated and re-obfuscated on a rolling basis — collects a broad sweep of the browser's self-description. Publicly documented signal categories include canvas rendering hashes, WebGL vendor and renderer strings, the AudioContext output signature, installed font enumeration, screen and viewport geometry, navigator properties (platform, hardware concurrency, device memory, languages, plugins), timezone, and a battery of automation tells.
Those automation tells are the ones worth internalising, because they are cheap for the sensor to check and catastrophic for you to fail:
navigator.webdriver— set to true by every WebDriver-controlled browser. MDN documents it plainly as an automation indicator. It is the single most-checked property on the internet.- CDP artefacts — an attached Chrome DevTools Protocol client leaves observable traces. Calling
Runtime.enablein particular is detectable from page context, which is why serious automation avoids it entirely. - Headless signatures — even Chrome's modern headless mode, which shares far more code with headful Chrome than the old implementation, still differs in ways a determined sensor can find: missing GPU paths, absent window chrome dimensions, permission API quirks.
- Patched-property signatures — and this is the subtle killer. If you override
navigator.webdriverin JavaScript, the property's descriptor changes, itstoString()output changes, and its position in the prototype chain may change. The sensor does not just read the value; it interrogates how the value got there. A crudely patched browser is more identifiable than an unpatched one, because genuine Chrome has no reason to have a redefined getter on a native property.
This is the point where the whole strategy has to change. Every patch-it-in-JavaScript approach is a race you lose, because you are adding evidence rather than removing it. Fingerprint values need to come from inside the browser engine — where a canvas hash is just what the renderer produced, and navigator.hardwareConcurrency is just what the runtime reports — so there is no override to detect. We break down that distinction properly in how to change your browser fingerprint, and if the underlying concepts are new to you, start with browser fingerprinting explained for beginners.
On forging sensor payloads
There is a cottage industry in reverse-engineering the sensor and generating valid sensor_data payloads from a plain HTTP client. It is real, it works, and I would not build a business on it. The obfuscation rotates. The signal set changes. A generator that took three weeks to build breaks on a Tuesday deploy and takes another week to fix, and during that week your data is gone. It is also the approach most likely to be characterised as circumvention rather than access, which matters legally in a way that using a real browser does not. If your requirement is this pipeline must run for two years, forging is the wrong architecture regardless of whether it works today.
Layer 4: behaviour, the part everyone skips
Assume you have cleared all three previous layers. Real IP, real handshake, real browser, valid sensor posts. You will still get scored down if you behave like nothing that has ever held a mouse.
Behavioural telemetry looks at pointer movement paths and their acceleration curves, the interval between keystrokes, scroll velocity and the small overshoot-and-correct that humans do, the delay between a page becoming interactive and the first interaction, and whether focus and blur events fire when they should. Synthetic events dispatched from JavaScript — element.dispatchEvent(new MouseEvent('click')) — carry isTrusted: false and are trivially distinguishable from a click that originated in the browser's own input pipeline.
The practical version of this is less exotic than it sounds. You do not need to model human motor control. You need to:
- Drive input through the browser's real input pipeline (CDP
Input.dispatchMouseEventat the browser level produces trusted events; JavaScript-dispatched events do not). - Move the cursor along a path with a few intermediate points instead of teleporting.
- Put a variable pause between page load and first action — 800ms to 3s, not a constant.
- Scroll before you read content that is below the fold, because a human would have.
- Do not fire requests at a perfectly regular interval. Human traffic is bursty and irregular; a request every 4.00 seconds for six hours is a signature all by itself.
Four architectures, honestly compared
| Approach | What it clears | Where it breaks | Maintenance load | Best for |
|---|---|---|---|---|
| HTTP client + copied headers | Nothing meaningful | TLS/HTTP2 fingerprint, immediately | Constant firefighting | Unprotected sites only |
| HTTP client + TLS impersonation + forged sensor | Network, protocol, sometimes sensor | Sensor obfuscation rotates; no behaviour layer | Very high, breaks on vendor deploys | Short bursts, high volume, disposable |
| Stock headless automation (Playwright/Selenium) | Protocol layer | navigator.webdriver, CDP traces, shared fingerprint across all workers |
Medium, and losing ground | Internal testing, logged-in QA |
| Real browser profiles with native fingerprints + sticky residential exits | All four layers | Slower per page; needs proxy budget | Low once built | Sustained, long-lived collection |
| Third-party unblocker API | All four (someone else's problem) | Per-request cost, no control, data leaves your infra | None | Low volume, no engineering time |
There is no universally correct row. If you need eight hundred thousand pages in six hours and you do not care about next month, row two is rational. If you need forty thousand pages a day for the next two years without a dedicated engineer babysitting it, row four is the only one that amortises.
A setup that actually holds up
Here is the sequence I would follow building this today, roughly in order of what breaks first if you skip it.
Step 1 — Establish what you genuinely need
Most scraping specs are inflated. Before touching infrastructure, work out the minimum: which URLs, at what freshness, in what volume. The difference between every product page hourly and the two thousand SKUs that actually move, twice daily is usually a factor of thirty in cost and risk. Aggressive volume is what turns a tolerated crawler into a targeted one.
While you are here, read the site's robots.txt and terms. The Robots Exclusion Protocol is a formal standard now — RFC 9309 — and ignoring it is both a legal exposure and a reliability problem, because disallowed paths are exactly where the aggressive rules live.
Step 2 — Build identities, not sessions
An identity is a persistent bundle: a fingerprint, a cookie jar, a localStorage and IndexedDB state, a proxy exit, a timezone, a language set. It lives for weeks. It accumulates history. Its _abck matures.
This is the mental shift that changes results more than any technical trick. A scraper that mints a fresh browser context per job is asking Akamai to evaluate a stranger, every single time, and strangers start from provisional trust. An identity that has visited the site nineteen times over three weeks, with real cookies and real cached assets, is a returning visitor. The edge treats them completely differently.
Each identity needs its own persistent data directory. Not a fresh temp dir. Not a shared profile. Its own, kept on disk between runs.
Step 3 — Make every identity internally coherent
This is where most setups leak. A coherent identity means the timezone matches the proxy exit's geography, the Accept-Language header matches the locale which matches navigator.languages, the platform in the user agent matches the platform in the Client Hints headers which matches the WebGL renderer string, and the screen resolution is one that the claimed device actually ships with. A MacBook Pro user agent reporting an NVIDIA GeForce RTX 4090 as its WebGL renderer is not a near miss; it is a device that does not exist.
The reason antidetect browsers are useful here has nothing to do with hiding. It is that they generate the whole bundle consistently, from one internally-validated model, instead of leaving you to hand-assemble forty correlated values and get three of them wrong. This is also the clearest answer to the perennial question of whether a VPN would do — it would not, and we spell out exactly why in antidetect browser vs VPN.
Step 4 — Warm before you extract
Do not have a brand-new identity's first ever request be the deep product endpoint you actually want. Land on the homepage. Let the sensor script load, execute, and post. Wait. Click into a category. Wait. Then go where you were going.
This costs you three page loads and buys you a mature _abck. Given the reported requirement of multiple accepted sensor posts before real trust, warming is not superstition — it is paying the entry price the system explicitly charges.
Step 5 — Drive with trusted input
Never dispatch synthetic events from page JavaScript. Use browser-level input injection so events carry isTrusted: true. Avoid enabling the CDP domains that are observable from page context — Runtime.enable above all. If your automation framework insists on attaching a full debugging client and enabling everything by default, that framework is working against you.
Step 6 — Pace it, and jitter everything
Concurrency is the variable that turns a working setup into a burned one. Ten identities doing four pages a minute each is invisible. One identity doing forty pages a minute is a siren. Spread load across identities and exits, add jitter to every delay, and respect off-hours — a crawler that runs at exactly the same intensity at 4am local time as at 2pm is describing itself.
Step 7 — Instrument for silence, not for errors
Back to where we started. Monitor content, not status codes. Concretely:
- Assert on a required selector or a minimum extracted-field count per page, and alert when it drops.
- Track response body size distribution — a bimodal distribution with a cluster of small responses is a skeleton-page block.
- Track median latency per identity. A sudden climb is throttling before it is failure.
- Log the
_abckverdict segment. When it flips negative, that identity is done; retire it and stop burning its proxy exit. - Alert on absence of data, not just presence of errors. A pipeline that writes zero rows should page someone.
Where Dual Login fits
I will be direct about scope, because overselling this category is the norm and it helps nobody.
Dual Login is a browser profile manager. It launches a real Chromium process per profile, each with its own persistent data directory, its own proxy, and a fingerprint applied natively inside the engine rather than injected as JavaScript over the top. That last distinction is the whole point for this use case: there is no patched navigator getter for a sensor to find, because the value is not patched — it is what the engine reports. The fingerprint reaches Web Workers and iframes for the same reason.
Because it is a real browser, you inherit a genuine BoringSSL TLS handshake and genuine HTTP/2 settings without maintaining a single line of impersonation code, and both stay current as the engine updates. Because profiles are persistent, identities accumulate the cookie history and sensor maturity that Step 2 is about. And because there is an automation API that drives tabs over raw CDP without enabling the observable domains, you can script collection while keeping navigator.webdriver false and events trusted.
What it does not do: it will not fix a burned proxy pool, it will not make a request pattern of two thousand pages an hour from one identity look reasonable, and it is not a bypass service. It handles the identity and execution layers well and leaves the network and pacing layers to you, which is the honest division of labour. Teams already running this pattern for multi-account e-commerce operations tend to find the collection use case slots into the same infrastructure.
Mistakes that cost people weeks
- Rotating IPs mid-session. An
_abckthat travels across three ASNs in five minutes is not a session. - Copying cookies out of a real browser into a script. The score decays without continued sensor posts. You bought maybe ninety seconds.
- Patching
navigatorin page JavaScript. You added a detectable modification to remove a detectable property. Net negative. - One fingerprint across a hundred workers. Uniqueness is not the goal; diversity is. A hundred sessions with an identical canvas hash from a hundred different IPs is a cluster, and clusters are what the edge is built to find.
- Perfect regularity. Fixed intervals, fixed concurrency, fixed session lengths. Nothing organic is that tidy.
- Monitoring on HTTP status. Covered above, and I still see it in production systems built by good engineers.
- Testing headless and deploying headless. Some of the most useful signals only differ in headless mode. Run headful in a virtual display if you must run on a server.
- Scaling up the day it works. Working at 5 requests a minute tells you nothing about 500. Ramp over days and watch the latency curve.
The line I would not cross
Worth saying plainly. Collecting publicly accessible information — prices, availability, published listings — is broadly lawful in most jurisdictions and is how price comparison, market research, and academic work function. That is not the same as authenticating into accounts you do not own, evading a rate limit you agreed to in a contract, scraping personal data without a lawful basis under GDPR or equivalent, or hammering infrastructure hard enough to degrade it for real users.
Read the terms. Honour robots.txt. Check whether an official API exists and costs less than the engineering you are about to do — it very often does. Rate-limit yourself below the threshold where you become someone's incident. And if a site has told you in writing to stop, stop; no fingerprint configuration solves a cease-and-desist.
The techniques here are about looking like the ordinary user you legitimately are, at a scale that does not harm anyone. They are not a licence to ignore that distinction.
FAQ
Can I bypass Akamai Bot Manager with just a good user agent string?
No, and this is the single most common misconception. The user agent is one header among four independent detection layers. Your TLS handshake and HTTP/2 settings are fingerprinted before the header is even read, and the JavaScript sensor checks a hundred-plus signals afterwards. A Chrome user agent on a Python handshake is worse than no spoofing at all, because it creates a contradiction the scoring system is specifically designed to catch.
Why does my scraper work for a few requests and then stop?
Because Akamai's trust score is cumulative, not binary. Reports consistently indicate the edge wants several accepted sensor_data posts before a session is genuinely trusted. If your client never runs the sensor script, the session starts on provisional trust and decays as evidence fails to arrive. Warming an identity on the homepage before touching your target endpoint usually fixes exactly this symptom.
Is headless Chrome detectable by Akamai in 2026?
Modern headless Chrome shares far more code with headful Chrome than the old implementation did, so the crude tells are gone. But differences remain in GPU paths, window geometry, and permission behaviour, and a sensor with a hundred signals only needs a couple. If your workload can tolerate it, run headful inside a virtual display — the cost is a little RAM, and the signal improvement is meaningful.
Can I just copy the _abck cookie from my browser into my script?
It will work for a very short window and then stop. _abck is not a static key; it is a signed scoreboard that refreshes as new sensor payloads are validated, and its verdict segment flips negative once the score decays. Without a browser continuing to post sensor data, a copied cookie is a receipt for trust you are no longer earning.
Do I need residential proxies, or will datacenter ones do?
Datacenter IPs are fine for reconnaissance and parser development but not for sustained collection from an Akamai-protected property — the address space is labelled and the reputation penalty is immediate. Residential is the working default. What matters more than the label is stickiness: hold one exit per identity for that identity's whole life rather than rotating per request.
How many concurrent profiles can I safely run against one site?
There is no universal number, because it depends on the property's configuration and how large its genuine audience is. The useful framing is per-identity rate rather than total concurrency: keep each identity's pace within what a curious human could plausibly do — a handful of pages per minute, with irregular gaps — and scale by adding identities rather than by speeding any one of them up.
Closing
The honest summary is that there is no bypass, in the sense people mean when they use the word. There is a scoring system that measures whether your traffic is internally consistent and behaves like a person, and there are two ways to satisfy it: convincingly fake all four layers and maintain that forgery forever against a vendor with more engineers than you, or stop faking and use a real browser with a coherent identity, a stable exit, and a sane pace.
The second is less clever and considerably more durable. Most of the work is not adversarial at all — it is discipline about identity persistence, proxy hygiene, request pacing, and monitoring that notices silence. Teams that get those four right rarely need anything exotic on top.
If you want to build on that foundation, Dual Login gives you the identity and execution layers out of the box: real Chromium per profile, native fingerprints with nothing patched in JavaScript, persistent data directories so sessions mature, per-profile proxies, and a raw-CDP automation API that keeps events trusted. There is a free trial worth testing properly before you commit to anything — spin up a handful of profiles, point them at whatever is currently blocking you, and watch what the four layers say.