stealth_ mode
Bypass bot detection systems with advanced anti-detection techniques including fingerprint randomization, human behavior simulation, and stealth browser configurations.
Use Cases
Protected E-commerce Sites
Scrape product data from sites with Cloudflare, DataDome, or PerimeterX protection
Social Media Platforms
Extract public data from platforms with sophisticated bot detection
Financial Data Sites
Access market data, stock prices, and financial information from protected sources
Rate-Limited APIs
Bypass aggressive rate limiting with fingerprint rotation
Geo-Blocked Content
Access region-restricted content through a proxy you supply
High-Security Testing
Test your own anti-bot systems with advanced evasion techniques
Endpoint
/api/v1/tools/stealth_modeParameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
operation | string | Optional | configure | Stealth operation to perform: scrape, configure, create_context, create_page, get_stats, or cleanup. `scrape` is the one-shot path — it creates a stealth context, navigates to `url`, returns the requested `formats`, and tears the context down, all in one billed call. The create_context → create_page → cleanup sequence remains for multi-step work that has to reuse a context. `configure` only validates `stealthConfig` and returns it with the defaults filled in, plus a `note` — it stores nothing, so pass `stealthConfig` on each `scrape` or `create_context` call that should use it. Example: create_context |
stealthConfig | object | Optional | - | Fine-grained stealth options. Keys: level (basic | medium | advanced, default medium), randomizeFingerprint, hideWebDriver, blockWebRTC, spoofTimezone, randomizeHeaders, useRandomUserAgent, simulateHumanBehavior (all booleans, default true), customUserAgent, customViewport ({ width 800-1920, height 600-1080 }), locale (default "en-US"), and timezone. The config applies to the call it is passed on and is not remembered between calls. On the `camoufox` engine `customUserAgent` and `customViewport` are not applied, `locale` is fixed when the browser launches, and behind a proxy `locale` and `timezone` follow the exit IP; `scrape` and `create_context` report each of these in `warnings`. Example: {"level": "advanced", "blockWebRTC": true} |
engine | string | Optional | playwright | Browser engine: "playwright" (default) or "camoufox" (Firefox-based, stronger anti-detection; available only where installed on the backend). Example: camoufox |
contextId | string | Optional | - | Browser context ID returned by a create_context call. Pass it to create_page to open a page in that stealth context. Example: ctx_ab12cd34ef56 |
urlToTest | string | Optional | - | URL to navigate to when creating a page with create_page. Example: https://protected-site.com |
url | string | Optional | - | URL to scrape. Required for `operation: "scrape"` and ignored by the other operations, which take `urlToTest` instead. Example: https://protected-site.com/product/42 |
formats | array | Optional | ["markdown"] | Formats `operation: "scrape"` returns: `markdown`, `html`, `text`, `links`, `metadata`, or `screenshot`. A screenshot comes back as a `crawlforge://screenshot/{id}` resource URI rather than inline base64, and this REST endpoint passes that URI through without resolving it — so for now `screenshot` is usable only from the CrawlForge MCP server, which can read the resource. Example: ["markdown", "links"] |
wait_for | number | Optional | - | Extra wait after page load, in milliseconds (0-30000). Use it for content that renders after DOMContentLoaded — a stealth run already pauses for human-like delays, so start small. Example: 2000 |
verbose | boolean | Optional | false | Return the full generated fingerprint from create_context instead of a summary. Useful when debugging why a target still detects the browser. Example: false |
respect_robots | boolean | Optional | true | Respect the target site's robots.txt. Omit it and the compliant default (`true`) applies: a URL disallowed for `CrawlForge` is refused before any browser is launched and this endpoint charges nothing for it, and every navigation is checked the same way. The rule is matched against the `CrawlForge` product token even though the stealth browser presents a randomized User-Agent, so a site owner's `User-agent: CrawlForge` directive binds stealth traffic too. Set it to `false` only for a target you have your own agreement with — the response then carries a `warnings` entry and the override is recorded against your API key. Example: true |
max_inline_chars | number | Optional | 40000 | Largest result to return inline, in characters of its JSON (1,000-10,000,000). Over it the response carries `preview` (the first `max_inline_chars` characters of the result's main text field), `result_handle`, `total_chars`, `truncated: true` and `expires_at`, and [read_result](/docs/api-reference/tools/read-result) reads the rest for 1 credit per call. Stored results are kept for 1 hour. Applies to operation `scrape`. Example: 40000 |
redact_pii | boolean | object | Optional | false | Remove personal data from the text this call returns, before the result is stored or sent back. Applies to `operation: "scrape"`, the only operation that returns a page; the bookkeeping operations have no text to redact. `true` is shorthand for `{ mode: "fast" }` — all four regex classes, tagged. Whenever you ask for redaction the response carries `redaction: { entities, count, mode }` inside `data`, even when nothing matched (`count: 0`), so "found nothing" is never mistaken for "the parameter was ignored"; a class with no hits is left out rather than reported as `0`. Redaction runs **before** the result is stored, so an oversized result read back later with [read_result](/docs/api-reference/tools/read-result) is already redacted. Two deliberate limits: addresses (`url`, `link`, `href`, `canonical_url`) are never redacted, and counters derived from the text (`content_length`, `word_count`, `character_count`) describe it as extracted, before redaction. Example: true |
Operations and what they cost
5 credits buy browser work; the bookkeeping operations cost 1 credit each. A one-call scrape is therefore 5 credits, where the create_context → create_page → cleanup route costs 11.
url, returns the requested formats with the page title and final URL, and tears the context down. Start here.contextId. Use it when several pages must share one fingerprint and cookie jar.urlToTest inside an existing contextId. The page is closed when the call returns; the context stays.stealthConfig and returns it with the defaults filled in, with a note saying so. Nothing is stored and no later call picks it up — pass stealthConfig on each scrape or create_context call. No browsing happens, so it is billed as bookkeeping.activeContexts, totalFingerprintsSaved, browserRunning, humanBehaviorActive and proxyStatus (enabled, currentProxy, totalProxies) for the backend. No browsing.What stealth mode does not do
Stealth mode renders JavaScript with a randomized browser fingerprint. It does not solve CAPTCHAs, forge challenge tokens, or work around a login or a paywall, and it is not a way past a block aimed specifically at CrawlForge. robots.txt still applies on every navigation, matched against the CrawlForge product token. If a target still refuses, the answer is a documented API or the site owner's permission, not a higher stealth level.
Where stealth traffic exits
The hosted API runs stealth_mode from a datacenter address. CrawlForge operates no residential proxy pool, and sites that score the network before running any JavaScript (Cloudflare, DataDome) may still challenge a hosted render. Pass your own residential or mobile proxy in stealthConfig.proxyRotation and every stealth context uses it. Proxies run per context on the Chromium (playwright) engine only: a per-call proxyRotation is refused on camoufox, which applies its proxy at browser launch and shares that browser across calls — self-hosters give Camoufox an exit through CRAWLFORGE_STEALTH_PROXIES. If you self-host the MCP server, CRAWLFORGE_STEALTH_PROXIES sets a server-wide exit, and CRAWLFORGE_BROWSER_BACKEND=browserbase hands stealth sessions to a Browserbase account, which brings its own residential exits and CAPTCHA solving under that account's terms.
Engine selection
stealth_mode supports two underlying browser engines. Choose based on your target site's detection difficulty.
Engine example
curl -X POST https://crawlforge.dev/api/v1/tools/stealth_mode \
-H "X-API-Key: cf_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation": "create_context",
"engine": "camoufox",
"stealthConfig": {
"level": "advanced"
}
}'Stealth Levels
Request Examples
# 1. Create a stealth browser context
curl -X POST https://crawlforge.dev/api/v1/tools/stealth_mode \
-H "X-API-Key: cf_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation": "create_context",
"engine": "playwright",
"stealthConfig": {
"level": "advanced",
"randomizeFingerprint": true,
"blockWebRTC": true
}
}'
# 2. Open a page in that context (use the contextId from step 1)
curl -X POST https://crawlforge.dev/api/v1/tools/stealth_mode \
-H "X-API-Key: cf_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation": "create_page",
"contextId": "ctx_ab12cd34ef56",
"urlToTest": "https://protected-site.com"
}'Response Example
{ "success": true, "data": { "operation": "create_context", "contextId": "ctx_ab12cd34ef56", "engine": "playwright", "stealthConfig": { "level": "advanced", "randomizeFingerprint": true, "hideWebDriver": true, "blockWebRTC": true, "spoofTimezone": true, "locale": "en-US" }, "message": "Stealth context created" }, "credits_used": 5, "credits_remaining": 995, "processing_time": 1200}data.contextIdPass this to create_page to open a page inside this stealth contextdata.operationThe stealth operation that was performeddata.stealthConfigThe resolved stealth configuration applied to the contextcredits_used5 credits for browser work (scrape, create_context, create_page); 1 credit for a bookkeeping operationprocessing_timeTime to spin up the stealth context (ms)Error Handling
Browser runtime not configured (503 TOOL_NOT_AVAILABLE)
Stealth mode needs a browser runtime. When the hosted execution backend is not configured the call returns 503 immediately and no credits are charged.
Rate limit exceeded (429 Too Many Requests)
You've exceeded your plan's rate limit. Wait a moment or upgrade your plan for higher limits.
Invalid Operation (400 Bad Request)
Operation must be one of: scrape, configure, create_context, create_page, get_stats, or cleanup.
Blocked by robots.txt (502 TOOL_ERROR)
The target's robots.txt disallows this URL for CrawlForge, so no browser was launched and nothing was charged. Set respect_robots: false to override if you have your own agreement with the target — the override is recorded against your API key. The override does not reach a host on CrawlForge's permanent opt-out list, which is refused whatever respect_robots is set to.
Execution backend timed out (504 MCP_UPSTREAM_TIMEOUT)
The target did not finish loading within the execution backend's budget. Heavily protected sites are the usual cause. Failures are not charged.
Start with "medium" stealth level. Only use "advanced" for sites that block medium level. Reuse one context across several create_page calls to amortize setup time—plan accordingly for batch operations.
Credit Cost
scrape, create_context, or create_page — whatever the stealth level. The bookkeeping operations configure, get_stats and cleanup do no browsing and cost 1 credit each, so a one-call scrape costs 5 credits end to end.What's Included:
Fingerprint randomization (all levels)
Human behavior simulation
Anti-detection techniques
WebDriver detection evasion (medium+)
Canvas/WebGL masking (medium+)
Advanced TLS fingerprinting (advanced)
Plan Recommendations:
Free Plan: 1,000 one-time trial credits = 200 stealth requests
Hobby Plan: 5,000 credits = 1,000 stealth requests ($19/mo)
Professional Plan: 100,000 credits = 20,000 stealth requests ($99/mo)
Related Tools
Ready to try stealth_mode? Sign up for free and get 1,000 credits to start building.