You’ve sent a run, it came backDocumentation Index
Fetch the complete documentation index at: https://docs.tinyfish.ai/llms.txt
Use this file to discover all available pages before exploring further.
COMPLETED, but the result is empty or wrong. Or maybe it outright FAILED. Before you start rewriting your goal, check whether the site is blocking you — bot detection is the most common cause of silent failures, and the fix is usually two lines of code.
This guide walks through the full process: confirm the problem, apply the right configuration, and tune your goal to behave more like a human.
Examples use the Python SDK. The same parameters work across all SDKs and the REST API — see API Reference for TypeScript and cURL equivalents.
Installation
Step 1: Confirm Anti-Bot Is the Problem
Don’t assume. Sites can fail for lots of reasons — slow JavaScript, unexpected layout changes, ambiguous goals. Anti-bot has specific fingerprints. Look for them first.Get the streaming URL and watch the browser
Every run produces astreaming_url — a live browser preview you can open while the run is happening. This is the fastest way to see exactly what the agent encountered.
Use agent.stream() to capture it as soon as it’s available:
on_progress callback shows each step the agent took — if it got stuck on a challenge page, you’ll see it stop there.
If you already started a run with agent.queue(), retrieve the streaming URL from the run object:
What to look for in the browser preview
Openstreaming_url in your browser. What you see tells you what happened:
| What you see | Likely cause |
|---|---|
| Cloudflare challenge / “Checking your browser” | Cloudflare bot detection |
| DataDome popup or redirect | DataDome protection |
| Blank page or infinite spinner | IP-based block or JS fingerprinting |
| CAPTCHA (reCAPTCHA, hCaptcha) | CAPTCHA gate — cannot be solved automatically |
| ”Access Denied” or 403 page | IP or User-Agent block |
| Login page when you expected content | Session-based bot detection |
Check the result — COMPLETED doesn’t mean it worked
The result field is a better indicator of agentic success.
- Fields are all
nullor empty arrays AND the streaming view shows the target content was never loaded result.reasonmentions “access denied”, “blocked”, or “could not find”
Step 2: Enable Stealth Mode and Proxy
Apply both together. Stealth changes the browser fingerprint; the proxy changes the IP. Sites that use anti-bot services correlate both signals — changing only one often isn’t enough.Switch to stealth browser
BrowserProfile.STEALTH is a modified browser with anti-detection techniques. The default (BrowserProfile.LITE) is faster but doesn’t include these measures.
Add a proxy
| Enum | Country |
|---|---|
ProxyCountryCode.US | United States |
ProxyCountryCode.GB | United Kingdom |
ProxyCountryCode.CA | Canada |
ProxyCountryCode.DE | Germany |
ProxyCountryCode.FR | France |
ProxyCountryCode.JP | Japan |
ProxyCountryCode.AU | Australia |
Verify what proxy was actually used
After a run,browser_config on the run object confirms what was applied:
Full example with both applied
Step 3: Guide the Agent to Behave More Like a Human
Stealth and proxy get you past the door. But some sites layer behavioral analysis on top of fingerprinting — they watch for robotic patterns like instant form submissions, missing cookie consent dismissals, or zero mouse dwell time. Your goal controls a lot of this behavior.Handle cookie and consent banners
Bot detection systems often look at whether a user interacted with a consent banner before the main content. Always dismiss it explicitly:Add deliberate pauses at suspicious checkpoints
Sites with aggressive behavioral detection (checkout pages, login flows) flag runs that move too fast:Describe elements visually, not by selector
Automation-aware selectors are sometimes deliberately changed to trip scrapers. Visual descriptions are more resilient:Use numbered steps for multi-step flows
For login flows or multi-page workflows, numbered steps give the agent explicit decision points rather than leaving it to guess:Add explicit fallback instructions
Protected sites sometimes show intermediate pages (challenge passed, now redirecting). Tell the agent how to handle them:Putting It All Together
A complete hardened run for a protected site:Decision Tree
Creative Solutions and Iteration
When a site is actively defended, the most effective approach is often to rethink the workflow rather than force the original one. Watch yourself do it first. Before writing your goal, navigate to the target site yourself and think through what a human would actually do. Use that as your script. The streaming view is also useful here — watch a run or two to understand exactly what the agent encounters before committing to a final goal. Start at the front door. Linking directly to a filtered search results page or a deep URL can look robotic. Starting attarget.com and navigating to your destination — searching for a product, clicking through a category — often succeeds where a direct deep link fails.
Go to the source. If the formatted data you need lives behind anti-bot and paywalls, ask whether the underlying raw data is available elsewhere. Aggregator sites are often heavily protected; their primary sources may not be. Synthesizing from multiple simpler sources is frequently more reliable than fighting for one complex one.
Check for a public API or feed first. Some sites that actively block scraping also publish APIs, RSS feeds, or sitemaps. Five minutes checking saves a lot of iteration.
Keep dwell time low. The longer an agent stays on a site, the higher the likelihood of detection. Balancing human-like navigation with speed matters — break large workflows into focused, smaller tasks that can be handled by multiple agents running in parallel. You get both the human-like pacing and the throughput. Scale is one of TinyFish’s superpowers.
Time your runs intentionally. Anti-bot systems are sensitive to traffic volume. Running during off-peak hours for your target site (for US-based sites, late morning to early afternoon PST often works well) can reduce the likelihood of triggering rate-based challenges. If you’re testing a new workflow, start with a single run during a quiet period before scaling up.
Vary your entry points at scale. If you’re running hundreds of batch jobs against the same site, uniform traffic patterns can themselves become a fingerprint — even across different IPs. Mixing up how runs navigate to their destination (some via homepage search, some via category pages, some direct) makes the aggregate traffic look more organic. Runs have a 10-minute timeout, so this also naturally encourages breaking complex workflows into smaller, parallelizable pieces. Design goals to complete their core task well within that limit.
Manage concurrency intentionally. TinyFish does not throttle runs by domain — if you enqueue a large batch against the same site, they will fire in parallel up to your account’s concurrency limit. For sensitive sites, consider staggering your jobs in your own queuing logic rather than enqueuing everything at once.
What’s Coming
TinyFish continuously improves browser behavior and anti-detection performance across the web. If a site blocked you on a previous project, it’s worth trying again — the same run that failed before may work without any changes on your end. Authenticated sessions: Connect your password manager and useuse_vault: true to log into sites as part of a run. Beyond unlocking gated content, authenticated sessions naturally bypass many anti-bot measures — logged-in users are treated very differently by most protection systems. See Vault Credentials for details.
Need Help?
If you’re stuck on a specific site, share the URL and your current configuration with us — we can often diagnose the issue quickly.- Email: support@tinyfish.io
- Discord: discord.gg/tinyfish