Tier escalation
How auto-promotion works and when to override it.
The default route
Every URL starts at Tier 0. If the response is clean (2xx, no challenge markers, body looks real), we stop. Otherwise the block detector reports a reason and the router promotes to the next tier.
Promotion table
| Block reason | Promotes to |
|---|---|
challenge_page | Tier 1 (browser) |
captcha_required | Tier 2 (CAPTCHA solver) |
empty_body | Tier 1 (browser) |
rate_limited | Tier 3 (unblock API) |
status_4xx / status_5xx | Tier 3 (unblock API) |
Capping max tier
You can cap promotion per job to control cost. max_tier=0 means "fail rather than escalate to a browser." This is useful for cheap, high-volume crawls of friendly targets.
Forcing a starting tier
If you know a target needs a browser, set the request's tier field to skip the wasted Tier 0 attempt. The router still escalates if the browser tier itself blocks.
Choosing a Tier-3 unblock provider
Tier 3 is the last-resort fallback when Tier 0–2 can't get through. Three providers ship under the same UnblockProvider protocol; pick the one that matches your targets.
| Provider | Cost | Beats | Doesn't beat |
|---|---|---|---|
flaresolverr | Free, self-hosted (Docker) | Plain Cloudflare JS challenges (Managed Challenge, "Just a moment") | Behavioral scoring (PerimeterX, advanced Akamai, Kasada) |
brightdata | ~$3 per 1,000 successful requests | CF, Akamai, PerimeterX, Kasada — runs a real-browser farm | Sites that explicitly block Bright Data IP ranges |
scrapfly | ~$0.001–$0.025 per request (credits) | CF, Akamai, PerimeterX with ASP enabled | Same gaps as Bright Data; pricing scales with render mode |
Set the provider via UNBLOCK_PROVIDER=flaresolverr|brightdata|scrapfly. Commercial providers refuse to start without their API key (BRIGHTDATA_API_KEY / SCRAPFLY_API_KEY); the orchestrator logs unblock.brightdata_missing_key and falls back to no Tier 3 rather than silently swallow the request.
Honest limits
Some block patterns can't be solved by any tier we ship today:
- WAF outright blocks (no challenge served, just 403 + a 2 KB explanation page) — typically need a different IP range; Tier 3 commercial unblockers help here.
- Site-specific JS interstitials with no public sitekey — our regex auto-detector misses these; use the per-target solver hint.
- Fingerprint-pinned APIs that require a paid app token — out of scope; integrate the official API instead.