How to Bypass DataDome in 2026: What Actually Works (and What Wastes Your Time)

Bottom line
Last updated: June 13, 2026.
- DataDome is not Cloudflare, and the difference matters. DataDome leans harder on the TLS handshake (JA4/JA4H) and on behavioral telemetry than it does on the JavaScript fingerprint. The site owner paid for it and usually tuned it. You almost never meet a lazily-configured DataDome zone.
- One leaky layer fails the whole request. A perfect residential IP behind a stock Playwright browser still gets a 403, because the TLS fingerprint and the CDP
Runtime.enablesignal give you away before any of your spoofing JavaScript runs. - The durable approach is four coherent layers, not one clever trick: a TLS fingerprint that matches your User-Agent, a CDP-clean browser, a clean residential IP held sticky per session, and human-paced behavior. Assemble it yourself across four vendors, or use a managed stack that ships all four wired together.
Jump to: how DataDome actually works · the four signal layers · what doesn't work · what does · code · FAQ. For the Cloudflare-specific version of this problem, see our Playwright Cloudflare guide.
Want all four layers in one API call?
Human Browser ships a CDP-patched browser + matched TLS + residential IPs + a challenge solver + human-paced input behind a single endpoint. Pay-as-you-go, no subscription, try it for $1, then top up from $5. Try Human Browser for $1.
Contents
- How DataDome actually works (and how it differs from Cloudflare)
- The four signal layers DataDome reads
- What doesn't work in 2026
- What does work — the four-layer playbook
- Code — a coherent request, end to end
- FAQ (8 questions)
DataDome doesn't catch you on one signal. It catches you on the disagreement between signals.
How DataDome actually works (and how it differs from Cloudflare)
DataDome is a SaaS bot-detection layer that site owners install in front of their application — at the CDN, the reverse proxy, or via a server-side module. When a request arrives, DataDome makes a millisecond-scale allow/challenge/deny decision based on a bundle of signals it collects from the network layer, the TLS handshake, the HTTP headers, and (for browser pages) a JavaScript probe that runs in the page and reports back. If the decision is "challenge," you get the device check — an interstitial that collects a fingerprint plus a small proof-of-work and, on success, issues a datadome cookie that vouches for subsequent requests.
People assume DataDome and Cloudflare are interchangeable because they both serve "Just a moment"-style interstitials. They are not interchangeable, and conflating them is the most common reason a setup tuned for Cloudflare fails against DataDome:
- DataDome is opt-in and paid; Cloudflare's bot defense is often default. A huge share of the Cloudflare-protected web is running free-tier defaults that nobody tuned. DataDome is a line item on someone's budget — they installed it on purpose, usually because bots were already costing them money, and they tuned the sensitivity. The average DataDome deployment is stricter than the average Cloudflare zone even though the underlying tech is comparable.
- DataDome weights TLS and behavior more heavily out of the box. Cloudflare's 2026 ML model (v9) leans on TLS+CDP signals too, but DataDome has always treated the TLS handshake (JA4/JA4H) and behavioral telemetry as first-class first-pass filters. A request that "looks" right in JavaScript but handshakes like Python is dead on arrival.
- DataDome adapts per customer. The model is informed by traffic patterns specific to each protected site. A fingerprint that sails through one DataDome customer can get challenged on another because their normal-traffic baselines differ. There is no single "DataDome bypass" that holds across all deployments.
- The device-check client rotates. DataDome ships heavily obfuscated client-side script and rotates it frequently. Anyone who reverse-engineers the payload to replay it by hand is signing up for a maintenance treadmill that breaks every few weeks.
The four signal layers DataDome reads

To get a request through, you have to be self-consistent across four layers. Detectors don't score them in isolation; they score the agreement between them. Here's each one and what leaks it.
1. Network / IP reputation
The first filter is where you're coming from. Datacenter ASNs (AWS, GCP, Hetzner, OVH, DigitalOcean) are flagged before anything else runs — a huge fraction of bot traffic originates there, so DataDome treats those ranges with suspicion by default. A residential or mobile IP with no abuse history clears this gate. This is necessary but, on its own, almost worthless: a clean IP attached to a leaky browser just means DataDome challenges you a layer later instead of dropping you immediately.
2. TLS fingerprint (JA4 / JA4H)
Before your client sends a single HTTP byte, it completes a TLS handshake, and that handshake has a shape: the list of cipher suites it offers, the TLS extensions, the order of both. JA4 hashes that shape into a fingerprint. Real iPhone Safari has one JA4. Stock headless Chrome on Linux has another. Python requests has a third that screams "script." If your User-Agent claims one thing and your JA4 says another, DataDome catches the contradiction in the handshake — before JavaScript, before the device check, before anything you can patch from inside the page. This is the layer that User-Agent spoofing has never touched, and it's why UA spoofing died years ago.
3. Browser / device fingerprint (the device check)
For pages (as opposed to bare API calls), DataDome's obfuscated client script runs in the browser and collects a device fingerprint: canvas and WebGL hashes, audio-context output, screen and font metrics, the navigator object, and — critically — automation tells. The big one is the CDP Runtime.enable leak: when Playwright or Puppeteer attaches to Chromium over the DevTools Protocol, it issues a command whose side effects are detectable from inside the page. This happens beneath the JavaScript layer, so playwright-extra-plugin-stealth and other monkey-patch approaches structurally cannot hide it. We wrote about why that whole class of plugin breaks in production.
4. Behavioral telemetry
You can pass every static fingerprint check and still get scored as a bot because of how you act. DataDome's model reads mouse-path entropy, scroll velocity and cadence, dwell time, and time-to-first-interaction. A page that renders and then receives a click 40ms later — faster than any human reaction time — is a bot. A form filled at a perfectly constant 0ms-per-keystroke is a bot. No fingerprint trick fixes this; it is an engineering problem of pacing input the way a person would.
Three of the four layers have nothing to do with the JavaScript you can edit. That's the part most scrapers never internalize.
What doesn't work in 2026
Before the playbook, here is the graveyard — approaches that still show up in tutorials and Stack Overflow answers but that DataDome closed years ago or that never scaled.
- User-Agent string swapping alone. Setting
navigator.userAgentto iPhone Safari over a Linux-Chrome TLS handshake is the textbook JA4 contradiction. It fails in the handshake. Dead since ~2023. - Stock Playwright / Puppeteer +
playwright-extra-plugin-stealth. The stealth plugin monkey-patches the page, but the CDPRuntime.enablesignal lives below where any injected script can reach. Against tuned DataDome it fails the device check regardless of how many flags you patch. See our teardown of why playwright-stealth stopped working. - Selenium + undetected-chromedriver. The W3C WebDriver protocol broadcasts automation at the driver level and leaks distinctive command-timing patterns.
undetected-chromedriverpapers over the obvious flags but is in the same architectural bind as the stealth plugin. - Hand-replaying the device-check payload. You can spend a weekend reverse-engineering the obfuscated client and forging a valid
datadomecookie. It will work until DataDome rotates the script — usually within weeks — and then you do it again. This is a treadmill, not a solution. - Datacenter proxies, no matter how many. Rotating through 10,000 datacenter IPs doesn't help when the ASN is the thing being flagged. You're just getting blocked 10,000 different ways.
- Bought
datadomecookies. The cookie is bound to the IP range, TLS fingerprint, and device fingerprint present at issue time, and DataDome re-validates continuously. A cookie minted on someone else's stack doesn't transfer to your request, and the ones that briefly do have very short useful lives.
What does work — the four-layer playbook

The thing that works is not exotic. It's coherence across all four layers at once. Get any one wrong and the contradiction flags you; get all four agreeing and you look like a person on a phone.
Layer 1 — a real residential or mobile IP, held sticky
Start from a residential or mobile IP with a clean reputation and no datacenter ASN. Equally important: keep one IP sticky for the lifetime of a session. The datadome cookie is validated against the signals present when it was issued; if your IP rotates mid-session, the cookie's IP binding breaks and you re-challenge. Our residential proxy benchmark covers which providers actually deliver clean IPs.
Layer 2 — a TLS fingerprint that matches your User-Agent
Your JA4 has to agree with the OS/browser your User-Agent claims. There are two ways to get this right:
- For full browser pages (which is most of DataDome's surface), use a real browser whose TLS stack is coherent by construction — a stealth-patched Chromium fork (Patchright) or a patched Firefox (Camoufox). A real browser ships a real TLS handshake; you just have to keep the UA consistent with it.
- For protected JSON APIs that gate only on TLS + headers and run no device check, a JA4-matching HTTP client (curl-impersonate or an impersonation library) is lighter and faster than a full browser. Know which case you're in — using a bare HTTP client against a page that requires the device check is the most common dead end.
Layer 3 — a CDP-clean browser so the device check sees no automation
This is the layer most people get wrong. The device check reads automation tells beneath the JavaScript layer, so you need a browser that's patched at the CDP / binary level, not a stock browser with a stealth plugin bolted on. Patchright applies the fixes at the DevTools Protocol layer (including the Runtime.enable leak); Camoufox patches the Gecko engine in C++ and ships the strongest canvas/WebRTC/audio defaults. Either one passes the device check that stock-Playwright-plus-plugin fails.
Layer 4 — human-paced behavior
Once the fingerprint is clean, the behavioral model is what's left. Move the mouse along Bezier curves rather than teleporting it. Type at 60–220ms intervals with variance, not a constant rate. Let the page sit for a beat before the first interaction. Scroll at human velocity. This is unglamorous engineering, but against a tuned DataDome zone it's frequently the difference between a 200 and a silent shadow-block where you get served subtly wrong data.
Code — a coherent request, end to end
Same task three ways: load a DataDome-protected page, wait for the datadome cookie to be issued, and extract the content. The point isn't line count — it's where the four layers live.
Stock Playwright (the baseline that fails)
// datadome_baseline.js — blocked: leaks CDP + datacenter IP + wrong TLS
const { chromium } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://datadome-protected-target.com');
const body = (await page.textContent('body')).slice(0, 2000);
await browser.close();
// → device-check interstitial or 403. No datadome cookie issued.Patchright + residential proxy + human pacing (the DIY stack)
// datadome_diy.js — CDP-clean browser, sticky residential IP, paced input
const { chromium } = require('patchright'); // was: require('playwright')
const browser = await chromium.launch({
proxy: {
server: 'http://gate.residential-provider.com:7000', // residential, sticky session
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS
}
});
const ctx = await browser.newContext({
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X)' +
' AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1' +
' Mobile/15E148 Safari/604.1',
viewport: { width: 393, height: 852 },
isMobile: true, hasTouch: true,
locale: 'en-US', timezoneId: 'America/New_York' // match the IP's geo
});
const page = await ctx.newPage();
await page.goto('https://datadome-protected-target.com', { waitUntil: 'domcontentloaded' });
// human pacing so the behavioral model doesn't flag you
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
await sleep(900 + Math.random() * 1400);
await page.mouse.move(120, 240, { steps: 14 });
await page.mouse.move(280, 560, { steps: 20 });
await sleep(500 + Math.random() * 900);
await page.evaluate(() => window.scrollBy({ top: 480, behavior: 'smooth' }));
await sleep(1300);
// the datadome cookie should now be present
const cookies = await ctx.cookies();
const dd = cookies.find(c => c.name === 'datadome');
const body = (await page.textContent('body')).slice(0, 2000);
await browser.close();
// Still BYO: a challenge solver for zones that force the device check anyway.Human Browser via A2A (the bundled stack)
// datadome_a2a.js — TLS + CDP-clean browser + residential + solver + pacing, one POST
const r = await fetch('https://agent.humanbrowser.cloud/a2a', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HB_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0', id: 1, method: 'message/send',
params: { message: { role: 'user', parts: [{ kind: 'text',
text: 'Go to https://datadome-protected-target.com and return the first 2000 chars of body text.' }] } }
})
});
const { result } = await r.json();
// result.artifacts[0].parts[0].text contains the extracted content.The DIY stack is real, maintainable code — pick it if you already run proxy and solver contracts and have the ops headroom. The bundled version exists because wiring matched-TLS + CDP-clean browser + sticky residential + a device-check solver + behavioral pacing into one coherent request is roughly two weeks of plumbing before your first successful page. Where you spend that time is the real decision.
Try the bundled stack — $1 for about 4 typical tasks
Human Browser ships a CDP-patched headful Chrome (Patchright) + matched TLS + residential IPs in 75 countries + a challenge solver + human-paced input behind a single API. Pay-as-you-go: $0.10/hr browser time, $4/GB residential proxy, $0.005/challenge, $0.02 per agent step with the AI included. No subscription, unused balance never expires. Try it for $1 — humanbrowser.cloud.
FAQ
Is DataDome harder to bypass than Cloudflare?
For most scrapers, yes — but not because the technology is fundamentally different. DataDome's defaults weight TLS (JA4/JA4H) and behavioral telemetry more aggressively than Cloudflare's free-tier defaults, and DataDome is almost always deployed by a customer who paid for it and tuned it. You rarely meet a lazily-configured DataDome zone the way you meet a default Cloudflare zone. The detection stack is comparable; the average deployment is stricter.
Why does my Playwright script fail DataDome even with a clean residential proxy?
Because a clean IP only clears the reputation gate. DataDome still reads your TLS fingerprint (JA4), your CDP-layer automation signals (the Runtime.enable leak that stock Playwright and playwright-stealth both emit), and your behavioral telemetry. Stock Playwright on a perfect residential IP still announces itself at the TLS and CDP layers within the first handshake. Clean IP plus leaky browser equals a 403 or a device-check interstitial.
What is the DataDome device check, and how do I solve it?
The device check is DataDome's interstitial challenge — a page that collects a fingerprint and a small proof-of-work before issuing the datadome cookie. You don't "solve" it by reverse-engineering the payload for long; DataDome rotates the obfuscated client script frequently. The durable approaches are: (1) present a clean enough browser and behavior that you never trigger the interstitial, or (2) use a challenge solver that maintains the device-check payload as a service. Hand-rolled payload replay breaks within weeks.
Does curl-impersonate or a TLS-impersonation library beat DataDome?
It clears the TLS layer, which is necessary but rarely sufficient. curl-impersonate (or a JA4-matching HTTP client) gives you a correct TLS fingerprint for pure HTTP endpoints. But DataDome-protected pages that matter usually require the datadome cookie issued after the JS device check runs, and a bare HTTP client executes no JavaScript. TLS impersonation is excellent for protected JSON APIs that only gate on TLS + headers; it doesn't run the device check, so it fails on full browser-rendered pages.
Can I just buy a DataDome cookie or session?
The datadome cookie is bound to signals collected at issue time — IP range, TLS fingerprint, and device fingerprint. A cookie minted on someone else's IP and browser doesn't transfer to your request without those same signals, and DataDome re-validates continuously, not just at issue. Bought-cookie services exist but are brittle and expensive per request because the cookies have short useful lives. Generating your own valid session from a consistent browser+IP is more durable.
What is JA4 and why does it matter for DataDome?
JA4 (and the JA4+ suite) is a TLS client fingerprint: a hash of the cipher suites, extensions, and ordering your client offers during the TLS handshake. It's computed before any HTTP request or JavaScript runs. If your User-Agent says iPhone Safari but your TLS handshake matches Linux Python or stock headless Chrome, the JA4 mismatch flags you instantly. DataDome reads JA4/JA4H as a first-pass filter, which is why User-Agent spoofing alone has been dead for years.
Which sites use DataDome?
DataDome is common on e-commerce, sneaker/ticketing, classifieds, real-estate, travel/fare aggregation, and parts of social and recruiting — LinkedIn famously layers DataDome with its own anti-bot. If you see a datadome cookie in your network tab, an X-DataDome response header, or an interstitial served from a captcha-delivery domain, you're dealing with DataDome.
Will Web Bot Auth let me through DataDome?
Web Bot Auth is a Cloudflare-led verified-agent standard; it governs Cloudflare's verified-bot lane, not DataDome's. DataDome runs its own bot-allowlisting and partner program. As of mid-2026 there's no cross-standard passport that DataDome honors from the Cloudflare ecosystem. If your target uses DataDome and you're a legitimate agent, the path is DataDome's own allowlist/partner channel, not Web Bot Auth.
Related Articles
- Playwright Stealth Not Working in 2026? Here's Why — Stealth
- Why Stealth Plugins Break in Production — Architecture
- How to Bypass Cloudflare with Playwright in 2026 — Pillar · Cloudflare
- Best Residential Proxies for Scraping 2026 — Real Benchmarks — Pillar · Proxies
- How to Scrape LinkedIn Without Getting Banned — Guide
- Cloudflare Turnstile Bypass — What Actually Works — Guide