DataDome
Bot management
Also known as: captcha-delivery, DataDome Bot Protection
Blocks and challenges on 403, and is the easiest vendor in this glossary to attribute thanks to an explicit x-datadome header and a captcha-delivery.com bootstrap in the body.
DataDome runs as a module or edge worker in front of the application, calling its Protection API on each request. The documented contract is precise: the module reads an X-DataDomeResponse header from the API and treats 200 as allow, treats anything else as an instruction to return DataDome's response verbatim without contacting the backend, and treats a missing header as a signal to fail open so that a fault in the detection path does not take the site down.
DataDome offers nine response types, which is the widest published set here. Alongside Allow, Block, and Captcha, it documents Device Check (a silent interstitial that verifies the environment without user interaction), Timeboxing (allow during configured hours, enforce outside them), Rate Limiting (allow below a volume threshold, enforce above it), Custom (allow the request but tag it with a header so the application can decide), and Monetize (hand compliant bot and LLM traffic to a partner workflow rather than refusing it).
That last group matters for anyone building legitimate automation, because it means a DataDome site can be configured to admit declared bots on commercial terms rather than block them. The block is a policy choice, not a technical inevitability.
How to identify it
- x-datadome: protected on the response. This appears on allowed traffic as well as blocked traffic, so it attributes the vendor and not the verdict.
- x-dd-b on a response is the block marker, and is what actually separates a refusal from a pass.
- server: DataDome on some deployments, which is as unambiguous as attribution gets.
- A datadome cookie set with a one-year Max-Age.
- A body containing a var dd = { ... } object naming host: 'geo.captcha-delivery.com', with a script from ct.captcha-delivery.com.
Headers
- x-datadome: Set to protected. Marks DataDome's presence on both allowed and blocked responses, so it must not be read as a block signal on its own.
- x-dd-b: Present on block responses. Combined with the status code this is the reliable verdict marker.
- x-datadome-cid: The client identifier DataDome associated with the request. Useful to quote when reporting a false positive.
- X-DataDomeResponse: Internal header on the Protection API response, read by the integration module. 200 means allow; any other value means return DataDome's response to the client unchanged.
Cookies
- datadome: The single session cookie. DataDome documents it as used for both server-side and client-side detection, encrypted, and containing no personally identifiable information. Typically set with a one-year lifetime.
Status codes
403 Block or challenge page
Blocked. Documented by the vendor.
DataDome enforced a response. Both hard blocks and CAPTCHA challenges arrive as 403, and the body distinguishes them.
What triggers it
- A detection model scoring the request as automated, drawing on TLS and HTTP fingerprints, client-side signals, and behaviour.
- A custom rule, or a rate limiting response whose volume threshold was crossed.
- A request with no valid datadome cookie on an endpoint that expects one.
How to confirm it
- x-dd-b on the response alongside x-datadome: protected.
- A body defining var dd = { ... } with a host of geo.captcha-delivery.com.
- Inside that object, a t field: a value of bv indicates a block, while fe indicates a challenge the client is expected to complete.
What to do about it
- Read the t field before deciding anything. A block and a challenge are the same status code and completely different situations, and this is the field that separates them.
- Capture x-datadome-cid. It is the identifier a site operator needs to trace your request.
- If you are running declared, legitimate automation, approach the site operator. DataDome's response set includes Allow rules for verified bots and AI agents, and a Monetize path for commercial bot traffic, so an operator has options short of refusing you.
HTTP/2 403
x-datadome: protected
x-dd-b: 2
x-datadome-cid: AHrlqAAAAAMAZc-WcMV57acAoE9qgA==
set-cookie: datadome=GLGPOXLEKAsX3BfQ8z5GnmEH2y01g0APdCcQa6O7...; Max-Age=31536000; Path=/; Secure; SameSite=Lax
<html lang="en"><head><title>example.com</title></head><body style="margin:0">
<p id="cmsg">Please enable JS and disable any ad blocker</p>
<script data-cfasync="false">var dd={'rt':'c','cid':'AHrlqAAAAAMA...','t':'bv',
'host':'geo.captcha-delivery.com','cookie':'...'}</script>
<script data-cfasync="false" src="https://ct.captcha-delivery.com/c.js"></script></body></html>
200 Device Check interstitial
Challenge. Documented by the vendor.
A silent verification page was served in place of the resource. DataDome documents Device Check as an interstitial that runs without any user interaction and then redirects to the requested resource if the client is legitimate.
What triggers it
- DataDome detected bot signals that were not strong enough to justify a block or a CAPTCHA.
- The request was for a sensitive resource or arrived in a risky context, so verification was raised pre-emptively.
How to confirm it
- x-datadome: protected on a response whose body is a short interstitial rather than the page.
- A captcha-delivery.com script reference.
- A page that briefly displays a verification message before redirecting, or nothing at all in invisible mode.
What to do about it
- Do not record this as a successful fetch. It is a 200 carrying an interstitial, and any pipeline keying on status will store it as content.
- DataDome documents that the outcome can be Allowed, escalated to the Slider challenge, blocked, or discarded when the client-side check never loads. A client that cannot execute the check falls into that last bucket by construction.
403 Slider CAPTCHA
Challenge. Documented by the vendor.
An interactive challenge was served. DataDome's is a slider puzzle with an audio alternative.
What triggers it
- Signals strong enough to warrant interaction but not a block.
- Escalation from a Device Check that found something suspicious.
How to confirm it
- A t value of fe in the dd object, indicating a challenge rather than a block.
- The captcha-delivery.com host in the bootstrap.
What to do about it
- Treat a challenge as an invitation the client cannot accept rather than as an error. DataDome documents that it detects automated challenge solvers and redirects them to a block page, so attempting to defeat the challenge programmatically converts a soft response into a hard one.
- The productive path is access on agreed terms with the site operator.
429 Rate limiting response
Rate limited. Documented by the vendor.
A Rate Limiting rule's volume threshold was crossed. DataDome documents this response as allowing traffic below a threshold over an hour or a day, then applying a CAPTCHA, Block, or Device Check above it.
What triggers it
- Exceeding the configured request count for the rule's hourly or daily window.
How to confirm it
- x-datadome: protected, with retry-after on some configurations.
What to do about it
- Because the window is a full hour or a full day, the reset is on a clock boundary rather than a rolling one. Waiting a few seconds will not help; waiting until the window rolls over will.
200 Custom response tag
Allowed. Documented by the vendor.
The request was allowed through but tagged with an HTTP header so the application can apply its own logic, such as serving alternate content.
What triggers it
- An operator using the Custom response to keep detection in DataDome while making the enforcement decision in their own application.
How to confirm it
- An enriched request header such as X-DataDome-isbot reaching the application, which callers cannot see from outside.
What to do about it
- From outside, this is indistinguishable from a normal response, which is the point. If the content you receive is consistently thinner than what a browser sees, this pattern is one possible explanation.
If you run a site behind it
- The fail-open default is deliberate and worth preserving: DataDome documents that a missing X-DataDomeResponse header should be treated as allowed, so a detection outage degrades to permitted traffic rather than to a dark site.
- Never forward DataDome's pointer headers, or the headers they name, to the end user. The documentation calls this out explicitly as a security guardrail.
- Use the Allow and Monetize responses for declared bots rather than blocking indiscriminately. Legitimate integrators, AI agents, and commercial crawlers are easier to manage when they have a sanctioned path.
- For MCP endpoints, DataDome returns a structured JSON-RPC error with code -32000 and the message Access denied rather than an HTML page, so agent clients get a parseable refusal.
If your traffic is being caught by it
- x-datadome: protected does not mean you were blocked. Look for x-dd-b and the status code together.
- The t field in the dd object is the fastest way to tell a block from a challenge without rendering anything.
- DataDome explicitly instructs blocked AI agents not to retry automatically, warning that retrying without addressing the cause may result in further blocking. That guidance applies just as well to conventional clients.