How to bypass DataDome bot detection when scraping
Your scraper ran clean for a week. Then DataDome started answering with a 403, a blob of JSON, and a slider puzzle that no amount of retrying clears. Here's what it's actually testing, how to read the block, and the stack that gets you back to the data.
Disclosure: some links here are affiliate links. If you sign up through them we may earn a commission at no extra cost to you. We only recommend tools we'd use ourselves. Hire a Clawd is our own service.
DataDome is the anti-bot vendor scrapers gripe about most, and the gripes are earned. Cloudflare gives you a few chances. DataDome scores your very first request, and if it doesn't like the shape of you, it hands back a 403 before your code does anything a person would call suspicious. No warning. No warm-up.
It leans on two things harder than almost anyone else: the reputation of the IP you show up on, and whether the story your browser tells about itself holds together. Get either wrong and you're done. So let's read the block first, then fix it layer by layer, in the order I'd actually try. The whole way through, the goal is pulling public data at a reasonable pace, not battering a login. If you want the vendor-agnostic version of this, the general anti-bot checklist covers every layer at once.
What a DataDome block looks like
DataDome leaves fingerprints of its own. Once you know them, you stop guessing about who's blocking you and why.
- The
datadomecookie. First-party, set on nearly every response with aSet-Cookie: datadome=.... It's a signed token tied to your IP and fingerprint. Pass the checks and that same cookie is your pass into the site. Fail and it's the leash. There's usually anx-datadomeresponse header alongside it, often readingprotected, which just confirms the request went through DataDome at all. - A 403 with a JSON body. When an XHR or API call gets blocked, DataDome answers 403 with
content-type: application/jsonand a body like{"url": "https://geo.captcha-delivery.com/captcha/?initialCid=...&cid=...&t=fe", ...}. Thaturlis the CAPTCHA. Ask for an HTML page instead and you get an interstitial carrying an inlinevar dd = {...}object with the samecid,hsh, andtvalues. - Read the
t.t=femeans a challenge: clear the slider and you're likely back in.t=bvis closer to a hard block, your device or IP is in the penalty box and no puzzle will save it. If you keep seeingbv, stop solving captchas and go fix your IP. - The slider. DataDome's CAPTCHA is a slide-the-puzzle-piece widget, the same shape as GeeTest, served from
captcha-delivery.com. It isn't there to be solved once by a human. It's there to watch how you solve it.
How DataDome decides you're a bot
DataDome builds a risk score server-side, in a couple of milliseconds, out of two piles of signal. One pile it collects before your browser runs a line of JavaScript. The other it collects after. Then it checks the two piles against each other.
- IP reputation and ASN. The first gate, and the one DataDome is known for. It sees traffic across thousands of protected sites, so an IP that misbehaved on one is flagged on all of them. Datacenter ranges from AWS, Google, Azure, OVH, Hetzner, and DigitalOcean get scored as bots on sight. This is why a flawless browser on a cloud box still eats a 403 before anything else runs.
- Device fingerprint, and a lot of it. DataDome loads a tag from
js.datadome.cothat reads canvas, WebGL, audio, fonts, screen geometry, dozens ofnavigatorproperties,navigator.webdriver, Chrome DevTools Protocol traces, and hundreds of other values, packs them into a payload, and posts them back. It's one of the most aggressive client-side collectors in the business. - Coherence. Here's the part that catches people. DataDome cross-checks the JavaScript story against the network story. If your TLS handshake says one engine and your JS says Chrome, if your JS timezone is New York while your exit IP sits in Frankfurt, if your headers claim a language your locale doesn't back up, the mismatch itself is the tell. Every layer can be perfect on its own and still convict you together.
- Behavior. Mouse paths, scroll, keypress cadence, and above all how the slider gets dragged. DataDome sells behavioral detection as a headline feature, and on the CAPTCHA a robotic drag fails even when the puzzle piece lands in exactly the right spot.
The thing to sit with: DataDome isn't hunting for one bad value. It's hunting for a story that doesn't add up. That's why coherence matters more here than almost anywhere else, and why half-measures fail worse than doing nothing clever at all. A great User-Agent over a Python handshake. A real browser on a dirty IP. Each one is a fresh contradiction for the score to catch.
Step 1: read the block before you change anything
Before you rewrite your scraper, look at what you're getting. Half the people who "rebuild the whole stack" were one grep away from seeing the IP was the problem all along.
curl -s -D - -o /tmp/dd-body.html \
-A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0 Safari/537.36' \
https://example.com/ | grep -i -E 'HTTP/|x-datadome|set-cookie: datadome'
grep -o -E "captcha-delivery.com|t=[a-z]+" /tmp/dd-body.html | head
A 403 with a datadome cookie and an x-datadome header tells you who you're
up against. The second grep pulls the CAPTCHA domain and the t value out of the saved
body, so you know whether you drew a challenge (t=fe) or a hard block (t=bv).
If it's bv, no browser trick matters yet. The IP is the whole problem. Diagnose, then act.
Step 2: fix the IP first
This is the biggest lever you have against DataDome, bigger than it is against Cloudflare. Because DataDome's reputation database is so wide, the IP you arrive on decides most of the outcome before your browser fingerprint gets a vote.
Datacenter IPs are a non-starter. You want residential, and for the meanest targets, mobile. Mobile
4G and 5G pools are the strongest option DataDome faces, because a carrier puts thousands of real
people behind one NAT'd address, so banning it means banning paying customers. Rotate residential IPs
for independent pages, and hold a sticky session when you're moving through a multi-step flow so your
datadome cookie stays valid. We go deep on picking a pool in
the residential proxy guide, and
on wiring rotation cleanly in
rotating residential proxies in Python.
Doing a logged-in flow? Sticky sessions matter even more there;
scraping behind a login gets into that.
A clean home IP might squeak through at tiny volume. Point any real throughput at a DataDome site from cloud space and you'll 403 on request one.
Recommended tool
Start with the IP, not the browser
DataDome scores your IP before it scores anything you can spoof, and its reputation data spans every site it protects. A rotating residential pool with clean, un-flagged addresses is the one change that moves the most DataDome jobs from "blocked on request one" to "through." For the nastiest targets, reach for the pool's mobile IPs.
See our proxy pick →Affiliate link, at no extra cost to you.
Step 3: a real browser that spoofs at the source
Once the IP is clean, the job is making the browser's whole story agree with itself. DataDome runs its JavaScript tag on nearly every protected page, so a headers-only client rarely gets the cookie it needs. This is a browser game.
The wrong tool is a patched Chromium with evasion scripts injected at runtime. DataDome is good at spotting both the Chrome DevTools Protocol traces and the injection itself, which is why undetected-chromedriver keeps getting caught on serious targets. The right tool is a browser that lies at the binary level, so the values read back native. That's Camoufox, a patched Firefox built for exactly this. Two settings carry the load against DataDome:
from camoufox.sync_api import Camoufox
with Camoufox(
headless="virtual", # real display via Xvfb on a Linux box, trusted more than pure headless
geoip=True, # timezone, locale, and geolocation follow the proxy's exit IP
humanize=True, # curved, human-paced cursor movement
proxy={
"server": "http://gate.example-proxy.com:8080",
"username": "user",
"password": "pass",
},
) as browser:
page = browser.new_page()
page.goto("https://example.com/", wait_until="networkidle")
# DataDome sets its cookie once you pass; grab it to reuse on later requests
cookies = {c["name"]: c["value"] for c in page.context.cookies()}
if "datadome" in cookies and "captcha-delivery.com" not in page.content():
print("through:", page.title())
else:
print("blocked, check IP reputation and geo coherence")
geoip=True is the setting people skip, and against DataDome it's the difference-maker.
It pins the browser's timezone, locale, and geolocation to the proxy's exit IP, so a residential
address in Chicago doesn't sit behind a browser insisting it's in London. DataDome checks that
agreement directly, and a clash is a clean bot signal. headless="virtual" runs Firefox
on a virtual display on a server, which reads as more real than pure headless mode.
Recommended tool
The browser layer, without the fiddling
A source-level anti-detect browser is what makes the JS fingerprint and the network handshake tell one coherent story, which is the exact thing DataDome cross-checks. Get this layer wrong and every other fix is wasted. This is the browser stack we reach for first.
See the browser pick →Affiliate link, at no extra cost to you.
Firefox helps for a second reason too. DataDome tunes hardest against the Chromium automation stack that most scrapers reach for, so a well-disguised Firefox is simply less expected, and less pattern-matched, than the tenth undetected-chromedriver of the day.
This is a lot of plates to keep spinning
Clean residential IPs, a coherent browser, geo that lines up with the exit node, human timing, and all of it drifting every time DataDome retunes its scoring. Hire a Clawd is a personal AI agent that runs the browser automation for you, around the clock, and owns the whole stack. You get the public data you asked for without babysitting the machine that fetches it.
See plans from $49/mo →Step 4: move like a human
A perfect browser on a clean IP still trips if it acts like a machine, and DataDome watches behavior closer than most vendors do. The slider is where it watches closest. A cursor that teleports to the exact target and drags the piece in one straight shot at constant speed fails the behavioral check even when the puzzle lands right.
- Randomize every delay. A fixed
sleepis a fingerprint of its own. - Keep
humanizeon so cursor paths curve and vary, but don't lean on it for timing. It won't jitter your waits for you. - Reuse the
datadomecookie you earned instead of re-triggering a check on every hit. It's bound to your IP and fingerprint, so never carry it to a different exit node. - One identity per browser process. Sharing a single Firefox across identities lets DataDome correlate them straight past your proxy rotation.
Step 5: the slider, when it still shows
Get the IP, the browser, and the behavior right and the DataDome slider often never appears, or appears once and clears quietly. But some flows, the high-value ones especially, will put the puzzle in front of you no matter how clean you look. You can't fingerprint your way past a rendered slider, and solving by hand doesn't scale past a handful.
That's when you hand it to a solver. The service returns a token, or drives the slide itself, and your script keeps going. Pay-per-solve pricing keeps low-volume jobs cheap. We compare the options in the CAPTCHA solver roundup. One caveat specific to DataDome: a solved slider on a burned IP still fails, because the reputation and behavioral checks outrank the puzzle. Fix the IP first, then let the solver mop up what's left.
Recommended tool
For the slider you can't dodge
When DataDome renders its puzzle anyway, a solving service returns a token your script submits so the run doesn't die at the challenge. It's the fallback layer, not the plan, cheap per solve and only firing when the cleaner layers didn't already wave you through.
See the CAPTCHA pick →Affiliate link, at no extra cost to you.
What stopped working
A pile of advice that used to move the needle is dead against current DataDome. Chasing it burns days.
- User-Agent swapping. Changing the string changes a label, not the TLS handshake, the JS fingerprint, or the IP underneath it. DataDome reads all three. A shiny Chrome UA over a Python handshake just makes the incoherence louder.
- cloudscraper and header-spoof kits. They were built for an old Cloudflare challenge, and they do nothing for DataDome, which ships a different tag and expects real client-side execution. They loop or 403.
- Datacenter rotation. Rotating through a hundred cloud IPs is a hundred flagged IPs. Reputation is the gate, and datacenter ranges never pass it. Rotate residential, not cloud.
- Plain undetected-chromedriver. It helped once. DataDome now catches the CDP traces and the Chromium tells it leaves behind, so a source-level Firefox holds up far better.
No single trick beats DataDome, and anyone selling you a one-liner is selling last year's bypass. What works is the stack: a clean residential or mobile IP, a source-level browser whose story is coherent, geo that matches the exit node, human timing, and a solver for the slider when it shows. Drop one layer and the score tips against you fast. If your target sits behind Cloudflare instead, the moves rhyme but the details differ, and the Cloudflare playbook walks that one.
Skip the setup
The Anti-Detect Scraping Starter Kit
A ready-to-run Camoufox + residential proxy Python template with humanized behavior baked in, a setup guide, and a pre-flight checklist that walks every layer on this page. Cookie handling and geo matching wired up, so your first DataDome scrape doesn't 403 on request one.
$19 one-time
Get the kit →FAQ
Why do I still get blocked by DataDome with residential proxies?
Because the IP is only one layer. A clean residential IP behind a raw handshake, or a Chromium full
of automation tells, is still incoherent, and DataDome scores the mismatch. Fix the browser too, and
match your timezone and locale to the exit IP with something like geoip=True. And check
the t value in the block: if you're seeing t=bv, that specific IP is already
burned, so rotate to a fresh one instead of hammering the same address.
What is the datadome cookie?
It's DataDome's signed clearance token, set as a first-party datadome cookie. Pass the
checks and it's your pass into the site, reused on later requests until it expires. It's bound to your
IP and fingerprint, so copying it to another IP or a different browser stack won't work.
Can I bypass DataDome without running a browser?
Rarely. DataDome runs its JavaScript tag on almost every protected page and expects the client-side
payload it collects, so a headers-only client usually can't earn the cookie it needs. A
TLS-impersonating client like curl_cffi fixes the handshake, but it still can't execute
the tag. For most DataDome targets, you need a real browser.
Is it legal to scrape a site protected by DataDome?
Scraping publicly available data is broadly legal in a lot of places, and DataDome sitting in front of a site changes none of that by itself. But the site's terms of service, its robots rules, rate limits, and privacy law still apply, and they vary by where you and the site sit. This isn't legal advice. If a project is high-stakes, talk to a lawyer before you point a scraper at someone's servers.
Or just hand the whole thing to an agent
If reading this far wore you out, fair. Clean IPs, a coherent browser, dodging the slider, and keeping it all alive as DataDome shifts its scoring is real, ongoing work. Hire a Clawd runs the automation for you, 24/7, and pings you on Telegram or Signal when the data's ready. No scripts to maintain.
Get your own agent →