Most scrapers fail before a single header gets read.
The server looks at the connection-level signature your client puts on the wire and decides whether you're a browser or a client library pretending to be one. Python requests, Go's net/http, plain curl: all of them hand over a distinctive fingerprint the moment they say hello. Sites that care (Datadome, Akamai, Imperva, the managed side of Cloudflare) drop the connection or serve you a challenge page before your User-Agent string even matters.
That's what unblocker: true solves on FourA. In the last month, we pinned down the pieces that make it work reliably.
What's New
unblocker: true is a single flag on any /api/single call. Flip it on and we do three things: inject the browser header set, send the request through a transport that matches what a real browser puts on the wire, and decompress whatever the server returns (gzip, brotli, deflate). The first two have been available since beta. The third one (brotli auto-decompression) shipped March 25, and the version-pinning work landed the next day to keep headers and transport in lockstep.
How It Works
Here's what a request looks like:
curl -X POST "https://api.foura.ai/api/single" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true
}'
Three layers run underneath.
Header injection. We set the full browser header bundle: User-Agent, Sec-Ch-Ua, Sec-Ch-Ua-Platform, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Accept, Accept-Language, and Accept-Encoding. Order matters. Real browsers emit these in a specific sequence, and detection libraries check for it.
Connection signature. Our transport matches the byte-level shape of an up-to-date browser session: the same extension ordering, the same cipher preferences, the same handshake quirks. Standard curl, Python requests, and Go's net/http produce signatures that are machine-flagged within milliseconds on protected infrastructure.
Auto-decompression. When unblocker is on, we set Accept-Encoding to gzip, deflate, br and the transport unwraps the body. You get a decoded string back (or a Buffer if you pass returnBuffer: true). No manual brotli handling, no headers-vs-body mismatches when a site picks deflate over gzip.
Why Version Pinning Matters
Connection signatures are version-locked. A browser's wire-level details this month aren't last month's, and a site that fingerprints carefully will notice the drift. We pin the moving pieces together so headers, navigator objects, and the connection signature all report the same browser version.
If that sounds fiddly, it is. We got bitten by a mismatch during the March monorepo migration when one piece auto-updated and the rest drifted out of sync. The fix was two commits: pin the moving piece, and never trust the package manager to keep things aligned for you.
Impact
On internal tests against heavily fingerprinted targets (finance, travel, protected e-commerce), the difference between unblocker: false and unblocker: true is the difference between a challenge page and a 200. Plain curl hitting managed Cloudflare lands on a 403 the first time out. The same URL with unblocker: true gets through because the connection looks like a browser session at the wire level.
But for sites that don't fingerprint (most public APIs, older CMS templates, anything gated only on IP rate limits), leaving unblocker off is fine and saves a few milliseconds of negotiation. Use it where you need it.
For Power Users
A few patterns worth knowing.
Pair unblocker with a residential proxy when the target also checks IP reputation. Datacenter IPs plus a perfect connection signature still flag on ASNs the site has blacklisted. Our proxy endpoint (/api/proxy) rotates by target domain, so adding "proxy": "residential" to the request is usually enough.
Skip unblocker when calling JSON APIs that don't care about browsers. The extra headers can actually look suspicious to an API that expects a programmatic client, for example a backend calling its own microservice.
If the site runs JavaScript anti-bot (Turnstile interactive challenges, PerimeterX at its strictest, Akamai Bot Manager with heuristics turned up), unblocker alone won't be enough. You need the browser endpoint, which executes the challenge in a full browser. That's a different product with different credit pricing, and we wrote it up in Browser Tasks: How to Scrape JavaScript-Heavy Sites.
And you can combine unblocker with the validate block to reject responses that technically return 200 but contain a challenge page:
{
"url": "https://example.com/products",
"method": "GET",
"unblocker": true,
"validate": {
"data": { "fail": ["captcha", "Access Denied"] }
}
}
That turns silent failures into classified failures, which matters for your success-rate tracking in the dashboard.
What's Next
Browsers ship a new stable every four weeks. We bump our stack to match. You don't need to touch anything on your side: unblocker: true keeps pointing at whatever browser version we've verified end-to-end.
The harder work is ahead. HTTP/3 fingerprinting is already showing up on managed anti-bot, QUIC transport is trickier to match than the older transport, and the migration away from static header bundles toward truly dynamic emulation is starting. Protected sites have moved to checking HTTP/2 frame ordering, and the gap between "library that looks like a browser" and "a browser" is going to shrink from both ends. We'll write about it when we ship it.