Antibot detection: know who blocked your request — and why
The API detects antibot and CAPTCHA challenges from 30+ providers in every HTTP response — reading headers, cookies, HTML, URL, and status code — then routes the request through the resolution path that specific provider requires. No configuration, no retry loops to write.
Every scraper is fighting defenses built to stop it
When your infrastructure takes a URL as input, you are constantly interacting with systems designed to keep automation out. A request can experience — followed by a challenge page. A CAPTCHA. A JavaScript puzzle.
Modern antibot systems operate at multiple layers, often before the request even reaches the application code, fingerprinting every hop along the way:
Detection does something fundamental: it tells you when a non-success resolution happens and who triggered it, so the next decision — retry, reroute, escalate — is made with real information instead of a blind retry loop.
How detection works
Every response is inspected across five signals — headers, cookies, HTML, URL, and status code. Each provider leaves a distinct combination of fingerprints; checks run in priority order and the first match wins. The result is deterministic and fast — designed to run on every request without becoming the bottleneck.
999 and Reddit can return 403 on challenge flows. The status code alone is often enough to classify the block.cf-mitigated: challenge, while other providers rely on provider-specific header combinations.30+ providers detected out of the box
Detection covers antibot systems, CAPTCHA vendors, and platform-specific protection flows. Use this table as a coverage map when building retry logic, escalation rules, or provider-specific analytics in your scraping pipeline.
| Provider | Category | Signals | Detection methods |
|---|---|---|---|
| Akamai | Antibot | 3 | HeadersCookiesHTML |
| AliExpress CAPTCHA | CAPTCHA | 2 | HTMLURL |
| Amazon | Platform-specific | 2 | HeadersHTML |
| Anubis | Antibot | 1 | HTML |
| AWS WAF | Antibot | 3 | HeadersCookiesHTML |
| Captcha.eu | CAPTCHA | 2 | HTMLURL |
| Cheq | Antibot | 2 | HTMLURL |
| Cloudflare | Antibot | 2 | HeadersCookies |
| Cloudflare Turnstile | CAPTCHA | 2 | HTMLURL |
| DataDome | Antibot | 2 | HeadersCookies |
| Douban | Platform-specific | 1 | Status Code |
| Dribbble | Platform-specific | 1 | Status Code |
| Friendly Captcha | CAPTCHA | 2 | HTMLURL |
| FullStory Challenge | Antibot | 2 | CookiesHTML |
| FunCaptcha (Arkose Labs) | CAPTCHA | 2 | HTMLURL |
| GeeTest | CAPTCHA | 2 | HTMLURL |
| Platform-specific | 1 | URL | |
| hCaptcha | CAPTCHA | 2 | HTMLURL |
| Houzz | Platform-specific | 1 | Status Code |
| Imperva / Incapsula | Antibot | 3 | HeadersCookiesHTML |
| Platform-specific | 1 | HTML | |
| Kasada | Antibot | 2 | HeadersHTML |
| Platform-specific | 1 | Status Code | |
| Meetrics | Antibot | 2 | HTMLURL |
| Ocule | Antibot | 2 | HTMLURL |
| PerimeterX | Antibot | 3 | HeadersCookiesHTML |
| QCloud Captcha | CAPTCHA | 2 | HTMLURL |
| reCAPTCHA | CAPTCHA | 2 | HTMLURL |
| Reblaze | Antibot | 2 | CookiesHTML |
| Platform-specific | 2 | HTMLStatus Code | |
| Shape Security | Antibot | 2 | HeadersHTML |
| Sucuri | Antibot | 1 | HTML |
| ThreatMetrix | Antibot | 2 | HTMLURL |
| Vercel | Antibot | 1 | Headers |
| Platform-specific | 1 | HTML | |
| YouTube | Platform-specific | 1 | HTML |
Missing a provider or a signal?
Audit the detection layer yourself
The detection logic that powers Pro is open source as fetch, got, axios, or undici.
import isAntibot from 'is-antibot'
const response = await fetch('https://example.com')
const { detected, provider, detection } = isAntibot({
headers: response.headers,
statusCode: response.status,
html: await response.text(),
url: response.url
})
if (detected) {
console.log(`Blocked by ${provider} (via ${detection})`)
// => "Blocked by CloudFlare (via headers)"
}Knowing who blocked you is half the job
On Pro plans, detection is wired straight into resolution: once the provider is identified, the request is routed through the resolution path that protection layer requires — rotating residential IPs, full browser rendering, retries — well-tested across the Top 500 most popular sites worldwide.
A response served through the proxy layer carries x-fetch-mode prefixed with proxy-; when a target requires it and the plan does not include it, the API returns EPROXYNEEDED — so a block is never silent. Available on metadata, HTML, and markdown requests.
Detect the block, resolve it automatically.
Every Pro plan bundles antibot detection with automatic proxy resolution — no proxy pool to manage, no CAPTCHA solver to integrate, no retry loops to write.
How does Microlink detect an antibot challenge?
cf-mitigated: challenge for Cloudflare or status code 999 for LinkedIn.Which providers can be detected?
Is the detection logic open source?
fetch, got, axios, and undici.What happens after a block is detected?
proxy-.