Stealth Mode
Bypass anti-bot protection on hard-to-scrape sites
What Stealth Mode Solves
Many websites actively block automated HTTP requests. Common defenses include:
- JavaScript rendering requirements — pages that return blank HTML without executing scripts
- Enterprise bot protection — services that fingerprint and block non-browser traffic
- Request fingerprinting — detection based on HTTP headers, TLS handshake characteristics, or behavioral signals
Standard extraction (stealth: false) sends a direct HTTP request. This works well for the vast majority of public websites and is both fast and cost-efficient.
Stealth mode routes the request through our premium unblocker, which handles rendering and bypasses bot-protection layers. Use it only when standard extraction returns incomplete content or fails.
When to Use Stealth vs Normal
| Situation | Recommendation |
|---|---|
| Public articles, blogs, documentation | Normal extraction (1 credit/URL) |
| E-commerce product pages | Try normal first; use stealth if blocked |
| Sites requiring JavaScript to render content | Stealth mode |
| Sites with heavy bot protection | Stealth mode |
| High-volume batch extraction | Normal mode; fall back to stealth on failure |
Example
curl -X POST https://api.serpex.dev/api/crawl \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"urls": ["https://example-protected-site.com/product/123"],
"stealth": true,
"format": "html"
}'import { SerpexClient } from "serpex";
const client = new SerpexClient("sk_your_api_key");
const result = await client.extract({
urls: ["https://example-protected-site.com/product/123"],
stealth: true,
format: "html",
});
if (result.results[0].success) {
// Parse structured data from HTML
console.log(result.results[0].html);
} else {
console.error(result.results[0].error);
}from serpex import SerpexClient
client = SerpexClient("sk_your_api_key")
result = client.extract({
"urls": ["https://example-protected-site.com/product/123"],
"stealth": True,
"format": "html",
})
if result.results[0].success:
# Parse structured data from HTML
print(result.results[0].html)
else:
print(result.results[0].error)Response
The response shape is identical to normal extraction. The stealth field in the metadata indicates stealth mode was active.
{
"results": [
{
"url": "https://example-protected-site.com/product/123",
"success": true,
"html": "<!DOCTYPE html><html>...",
"status_code": 200
}
],
"metadata": {
"total_urls": 1,
"processed_urls": 1,
"successful_crawls": 1,
"failed_crawls": 0,
"credits_used": 5,
"stealth": true,
"response_time": 11000,
"timestamp": "2025-06-21T10:30:00.000Z"
}
}Performance
Stealth requests are significantly slower than normal extraction — each one routes through a premium browser-rendering unblocker that executes JavaScript and clears anti-bot challenges.
| Mode | Typical time per URL |
|---|---|
| Normal extraction | ~1–5s |
| Stealth | ~7–15s (up to ~25s for JavaScript-heavy sites) |
Set your client timeout to at least 60 seconds for stealth requests. Batch requests (up to 10 URLs) are processed concurrently, so total time is bounded by the slowest URL — not the sum.
Cost
Stealth mode costs 5 credits per URL, compared to 1 credit per URL for normal extraction. Only use it when standard extraction is insufficient.
- Normal extraction: 1 credit/URL
- Stealth mode: 5 credits/URL
- Cache hits: 0 credits regardless of mode
Failed stealth requests are not charged.