---
title: "How does Cloudflare bot management detect an agent?"
description: "What Cloudflare's bot management reads before it challenges a browser: the 1 to 99 score, JA4, JavaScript detections, behaviour, and what stealth plugins miss."
canonical: "https://scalebrowser.net/blog/cloudflare-bot-detection"
last_modified: "2026-10-10"
published: "2026-10-10"
author: "davide"
category: "detection"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://scalebrowser.net/llms.txt
> Use this file to discover all available pages before exploring further.

# How does Cloudflare bot management detect an agent?

> What Cloudflare's bot management reads before it challenges a browser: the 1 to 99 score, JA4, JavaScript detections, behaviour, and what stealth plugins miss.

The "Verify you are human" box is the part of Cloudflare everyone sees, and it is the last step, not the first. By the time it appears, Cloudflare has already read the connection, run a script in the page and compared the request with its own traffic of the last hour. An agent that only prepares for the box has prepared for the step where the decision is mostly made already.

## What is Cloudflare bot detection?

Cloudflare bot detection is the set of engines that give every request to a protected site a bot score and let the site's rules act on it. Cloudflare's [bot score documentation](https://developers.cloudflare.com/bots/concepts/bot-score/) defines the score as "a score from 1 to 99 that indicates how likely that request came from a bot", and groups it into four bands.

| Bot score | Cloudflare's group | What sets it |
| --- | --- | --- |
| 0 | not computed | the request never reached Bot Management |
| 1 | automated | high-confidence heuristic matches, or a missing `User-Agent` header |
| 2 to 29 | likely automated | mostly the machine learning engine |
| 30 to 99 | likely human | mostly the machine learning engine |

The score itself blocks nothing. A site owner writes rules that block, challenge or allow a request by its score, which is why the same browser can pass one Cloudflare site and be stopped on the next. Granular scores are only available to Enterprise customers who bought Bot Management; Pro and Business plans see the groups in their bot analytics.

## Which 4 layers does Cloudflare read?

Cloudflare reads four layers, in the order a page load reaches them, and its documentation names the engine behind each.

1. **The connection.** The TLS handshake becomes a JA3 and a JA4 fingerprint, and Cloudflare's [JA4 documentation](https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/) lists ten hourly statistics it keeps per fingerprint across its network, such as `browser_ratio_1h`. The [Heuristics engine](https://developers.cloudflare.com/bots/concepts/bot-detection-engines/) "processes all requests" and matches them against "a growing database of malicious fingerprints".
2. **The JavaScript environment.** JavaScript Detections inject an invisible script into every HTML page, identify "headless browsers and other malicious fingerprints", and keep the result in the `cf_clearance` cookie with a lifespan of 15 minutes.
3. **The control plane.** The same engine is documented as catching "headless browsers (browsers controlled by software, with no visible window or human operator) and other automation tools". What drives the browser is judged apart from what the browser claims to be.
4. **Behaviour.** [Precursor](https://developers.cloudflare.com/cloudflare-challenges/precursor/) runs a script throughout a session to find automation "that appears legitimate in individual requests but exhibits non-human patterns across a session", and the `__cf_bm` cookie ties one visitor's requests together.

The machine learning engine, which Cloudflare says "accounts for the majority of all detections", takes headers, session characteristics and browser signals and turns them into the final score. A browser that is perfect on three layers and wrong on one still hands that one wrong input to the model. How a spoofed user agent shows is covered in user agent spoofing.

The free path shows what covering a single layer is worth. [puppeteer-extra-plugin-stealth](https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth) rewrites values a script reads, which is layer 2, and leaves the connection, the control plane and behaviour as [Puppeteer](https://pptr.dev/) and the machine leave them. What a page reads to find the control plane, such as `navigator.webdriver`, is covered in navigator.webdriver and CDP detection.

<Evidence source="GitHub issue search for berstend/puppeteer-extra, npm registry and npm download API, read 29 September 2026" href="https://github.com/berstend/puppeteer-extra/issues">

| Measure | Value |
| --- | --- |
| Open issues in the repository | 238 |
| Open issues matching "cloudflare" | 18 |
| Open issues matching "detected" | 41 |
| Latest release of the stealth plugin | 2.11.2, 1 March 2023 |
| npm downloads, 28 August to 26 September 2026 | 4,432,694 |

</Evidence>

More than four million downloads a month go to a plugin that has not been released for three and a half years, and the issue tracker is where its users report the sites it no longer gets through.

## When does 'Verify you are human' appear?

'Verify you are human' appears when a site's rule answers a score or a rate limit with a challenge, so it is an escalation for a request Cloudflare is unsure about, not a verdict. Cloudflare's [challenge page documentation](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/) describes three actions. A non-interactive challenge runs JavaScript only and "typically takes less than five seconds". A managed challenge, the one Cloudflare recommends, lets "most human visitors" through with a **Successful** message and asks for a click only when it "detects non-human attributes". An interactive challenge always asks.

So a checkbox means the earlier layers left doubt. The same holds for any [automated browser detection](/blog/bot-detection): a challenge is the defence buying one more reading. Cloudflare's [list of challenge limitations](https://developers.cloudflare.com/cloudflare-challenges/concepts/how-challenges-work/) names one that matters for agents in particular: a managed challenge solved from a different IP address than the one it was issued to is not valid, and the visitor lands in a challenge loop. A proxy that rotates its exit between two requests produces exactly that. Which signals give a proxy exit away is covered in proxy detection. What a Cloudflare 403 forbidden means for an AI agent is covered in Cloudflare 403 forbidden for an AI agent.

## How does Turnstile treat an agent's browser?

Turnstile treats an agent's browser like any other visitor: it decides in the background and asks for a click only on doubt, and Cloudflare's own sign-up page asked. On 14 August 2026 our agent clicked that forced checkbox on dash.cloudflare.com/sign-up and passed in 2 of 2 runs, after it had failed twice on 4 August; why the result changed between the two dates is not established. The two other variants we measured never asked at all, and [Turnstile and AI agents](/blog/cloudflare-turnstile) has all three with their timings. Both runs drove the browser over direct CDP rather than through [Playwright](https://playwright.dev/), and they say nothing about an exit address with a poor reputation.

<ProductMention />

### How does DataDome differ?

DataDome decides on the server before the page is served and answers with its own captcha or block page instead of a widget, and in our runs one header decided it, as the case of [DataDome and Accept-Language](/blog/datadome-detection) shows. The [verification page of the documentation](/docs/agents/verification) lists which challenges an agent has solved and on which pages.
