DEV Community

Cover image for What DataDome actually checks — and why your Cloudflare playbook doesn’t transfer
Bassem Shahin
Bassem Shahin

Posted on • Originally published at blog.captchaai.com

What DataDome actually checks — and why your Cloudflare playbook doesn’t transfer

What DataDome actually checks — and why your Cloudflare playbook doesn’t transfer

You’ve got your Cloudflare setup dialed in — clean residential IPs, a real browser, a solver for the Turnstile widget — and then you hit a site that blocks you anyway, with a challenge that looks nothing like Cloudflare’s. Odds are it’s DataDome, and the reason your playbook stops working is that DataDome isn’t primarily a captcha. It’s a request-analysis and device-fingerprinting engine that sometimes shows a captcha. Treat it like Cloudflare and you’ll spin.

Here's how to recognize it, what it's really doing, and how to approach it honestly.

How to know it’s DataDome (not Cloudflare)

Read the response — the markers are distinct:

import requests

r = requests.get(url, headers=headers)
print(r.status_code) # often 403
print("datadome" in r.headers.get("set-cookie", "").lower()) # a `datadome` cookie
print(r.headers.get("x-datadome") or r.headers.get("x-dd-b")) # DataDome response headers
print("captcha-delivery.com" in r.text) # DataDome's challenge/captcha host
print('"dd"' in r.text) # a {"dd": {...}} JSON block in the 403 body
Enter fullscreen mode Exit fullscreen mode
  • A datadome cookie, an x-datadome header, references to captcha-delivery.com / ct.captcha-delivery.com, or a {"dd": {...}} JSON block in a 403 → that’s DataDome.
  • Cloudflare’s tells are different: cf-mitigated, cdn-cgi/challenge-platform, cf_clearance. If you see those, it’s Cloudflare, and a different guide applies.

Getting the vendor right is the whole first step, because the fix is not the same.

Why it’s harder than “solve the captcha”

DataDome decides whether to even show a captcha based on a risk score it builds from:

  • Request fingerprint — TLS/JA3, HTTP/2 settings, header order. A raw client (or an obvious headless browser) scores badly before any challenge.
  • Device signals — a heavy client-side JS payload reads canvas/WebGL/fonts/timing/sensors; inconsistencies (a “desktop Chrome” with mobile-ish signals, or a timezone that disagrees with the IP) flag instantly.
  • Behavior — mouse movement, timing, navigation patterns.

So the captcha is the last gate, not the first. This is why people who “solve the DataDome captcha” still get blocked on the next request: the captcha token doesn’t fix a fingerprint that already looks automated. The defense is mostly upstream of the challenge.

How to handle it

  1. Confirm it’s DataDome first (above) — don’t apply Cloudflare clearance logic to it.
  2. Look for a way around the wall. Often the cheapest win: check whether the site exposes the same data via an official API or a backing JSON endpoint the page itself calls (devtools → Network → XHR). That can skip DataDome entirely.
  3. If you must go through the front, fix the layers in order:
    • IP — residential/mobile, geo-matched to your profile. Datacenter IPs score poorly with DataDome.
    • Fingerprint — a real or patched-stealth browser whose values are internally consistent (and consistent with the IP’s geo). DataDome is stricter than Cloudflare on automation tells, so default Selenium/Playwright usually won’t survive.
    • Behavior — human-ish timing and interaction, not machine-perfect.
  4. The interactive captcha, when it appears (DataDome’s image/slider), is solvable like other image/interactive captchas — but only after the fingerprint/behavior look legitimate; otherwise a solved challenge just bounces on the next request. And the datadome cookie you earn is bound to the IP + UA + fingerprint that earned it (much like cf_clearance), so pin the session and don’t rotate mid-flow.

The honest summary: DataDome is a fingerprint/behavior problem with a captcha on top, not a captcha problem. Spend your effort on the IP + fingerprint + behavior stack; the challenge is the easy 20%.

TL;DR

  • Identify by the response: datadome cookie / x-datadome header / captcha-delivery.com / {"dd":...} 403 → DataDome (not Cloudflare).
  • It scores fingerprint + device + behavior before showing a captcha, so a solved challenge alone won’t save a bad fingerprint.
  • Order of fixes: residential geo-matched IP → internally-consistent real/stealth browser → human-ish behavior → (only then) the interactive challenge.
  • Pin the session — the datadome cookie is bound to IP+UA+fingerprint.

For the everyday captcha types you hit alongside this — reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest, image — CaptchaAI is 2Captcha-API-compatible, so an existing client is mostly a base-URL change, and the trial is free (3 days, no card).

Top comments (0)