Browserless Screenshot Shows a CAPTCHA or Bot Check: What to Do
A CAPTCHA, blank image, or 403 can mean the site challenged your Browserless session. Diagnose the capture, choose the right documented option, and verify the result.
A CAPTCHA or bot-check in a Browserless screenshot usually means the target site presented a challenge to that browser session. A blank or white capture, a 403 or access-denied page, or missing page elements can be other signs that automation is being blocked. These symptoms point to a challenge; they do not establish why a specific site challenged a specific session.
First inspect the response and screenshot, then confirm the URL and page state. If you are authorized to automate the target, Browserless documents several next steps: review screenshot waits, try its /unblock API for screenshot-only work, or use stealth and CAPTCHA-solving options in a browser session. These options are not guarantees of access. Respect the target site’s terms and access controls.
Browserless describes blank images, CAPTCHA pages, and content that differs from a regular browser as signs that a site is likely blocking automation in its Screenshot API documentation.
1. Diagnose what Browserless captured
Open the image and check the HTTP result before changing your automation. Look for:
- A CAPTCHA, verification, or bot-check page in place of the expected content.
- A blank or white image.
- An access-denied or 403 page.
- Missing or broken elements that normally appear in the page.
Compare the capture with the same URL in a normal browser session you are permitted to use. Check whether a redirect occurred, whether the expected page loaded, and whether the screenshot was taken before the content appeared. This comparison can narrow down the issue, but cannot identify the site’s exact blocking mechanism by itself.
Also rule out ordinary capture mistakes: a typo or redirect in the URL, an incorrect viewport or selector, a screenshot taken before client-rendered content appeared, or a page that needs an explicit wait. Browserless’s screenshot endpoint supports wait configuration; see the endpoint documentation for its current options.
2. Choose the right Browserless path
| Your task | Documented route | What to verify |
|---|---|---|
| Capture a page without managing browser interaction | Review the Screenshot API request and wait conditions. | Confirm the response and captured page are the expected result. |
| Return a screenshot after an attempt to handle bot detection | Use /unblock with screenshot: true. |
Check the returned screenshot and page; do not infer success solely from a successful HTTP response. |
| Continue interacting with the page or submit a form | Use a Browserless browser session with documented stealth/CAPTCHA options, or BrowserQL. | Check whether a challenge was found and solved, then perform any required submission and verify the destination page. |
The Unblock API can return content, cookies, a screenshot, or a browser WebSocket endpoint after attempting to handle bot detection. It is a better fit than a screenshot-only request when you need that handling step. Browserless notes that its screenshot output is base64-encoded; follow the current endpoint docs for the response format.
3. Use the Unblock API for screenshot-only work
Get a Browserless API token from your account dashboard and keep it private. This example asks the endpoint for a screenshot and disables outputs the request does not need:
curl --request POST \
--url 'https://production-sfo.browserless.io/unblock?token=YOUR_API_TOKEN_HERE&proxy=residential' \
--header 'Content-Type: application/json' \
--data '{"url":"https://example.com/","content":false,"cookies":false,"screenshot":true,"browserWSEndpoint":false}'
The response contains a base64 screenshot field. Decode that field to a JPEG file using a JSON-aware script or tool. Do not save the JSON response itself with a .jpg extension. The current docs describe the response and options, including the choice to request content, cookies, screenshot, or a browser endpoint, at Unblock API.
Residential proxy routing is optional in the example. Browserless recommends considering it when blocks persist; its residential proxy traffic is billed by bandwidth. Only use it when it is appropriate for the task and budget. The vendor’s documentation does not promise that this or any other option will clear every challenge.
4. For browser automation, try stealth before solving
If the workflow needs page interaction, use a browser session rather than treating the screenshot as the whole task. Browserless recommends its /stealth route as an initial option. Its guide cautions that stealth changes browser behavior and can affect scripts that rely on stock Chrome internals, so check your automation after switching.
For a Puppeteer session that needs to detect and solve a challenge automatically, Browserless documents solveCaptchas=true. The following is a connection configuration pattern; substitute your token and the exact Browserless regional endpoint and Puppeteer setup used by your account:
import puppeteer from "puppeteer-core";
const token = process.env.BROWSERLESS_API_TOKEN;
if (!token) throw new Error("Set BROWSERLESS_API_TOKEN");
const endpoint = new URL("wss://production-sfo.browserless.io/stealth");
endpoint.searchParams.set("token", token);
endpoint.searchParams.set("solveCaptchas", "true");
endpoint.searchParams.set("timeout", "300000");
const browser = await puppeteer.connect({ browserWSEndpoint: endpoint.toString() });
try {
const page = await browser.newPage();
await page.goto("https://example.com/", { waitUntil: "domcontentloaded" });
// Wait for the page state your task needs, then verify it before capture.
await page.screenshot({ path: "capture.png", fullPage: true });
} finally {
await browser.close();
}
This pattern shows how to configure the connection and capture a page; it does not assert that a challenge will be solved. Browserless says solving may take seconds to minutes, so a longer timeout may be needed. In flows where the next action depends on the solve, wait for the documented CAPTCHA event with a bounded timeout; do not await an event indefinitely because no event fires when there is no CAPTCHA. If the flow requires a form submission, submit it after the solve and verify that the destination page loaded.
Browserless also documents BrowserQL’s solve mutation. Its CAPTCHA guide says to check the returned found and solved fields. For reCAPTCHA, the checkbox may not look ticked after solving; the documented example proceeds by submitting the form. See BrowserQL CAPTCHA solving and session CAPTCHA solving.
5. Add a proxy only when it addresses the problem
If the evidence suggests an IP-based block and the workflow is authorized, Browserless documents residential proxies as another option. Its guide suggests matching the proxy country to the site’s expected audience. Residential traffic is billed by bandwidth, so account for that usage. A proxy does not grant permission to access a site and does not guarantee the challenge will disappear.
Use the least complex path that fits the job: inspect and correct capture waits first; for screenshot output after a bot-detection attempt, evaluate /unblock; for a session that must interact with the page, consider stealth and then CAPTCHA-solving features. Check the current Browserless documentation for supported options and billing before changing production jobs.
6. Verify the page before accepting the screenshot
- Check that navigation reached the intended URL and did not end on an access-denied or challenge page.
- Check that the expected content or selector exists before capture.
- When using solving tools, inspect their result fields, including whether a CAPTCHA was found and solved.
- If the site requires a submit action after solving, submit only as part of the authorized workflow and check the resulting page.
- Save or deliver the screenshot only after confirming it shows the intended content.
A successful API call can still return a screenshot of a challenge. Judge the result by the page content, not merely by the transport status.
7. Troubleshooting common failures
| Symptom | Likely cause | What to try |
|---|---|---|
| CAPTCHA appears in the image | The site presented a challenge to the session. | Confirm the challenge in the capture. For screenshot-only work, review /unblock; for an authorized interactive session, review stealth and CAPTCHA-solving options. |
| Blank or white screenshot | Possible blocking, but also possibly a premature capture or page/load problem. | Check navigation outcome and waits, then compare with a permitted browser session. Browserless lists blank images as a possible blocking sign. |
| Screenshot shows 403 or access denied | The site returned an access-denied page. | Confirm the response and target-site permissions. Do not assume retries, stealth, or a proxy will make access permitted. |
| Expected elements are missing | Content may still be loading, or the site may be serving a different page to automation. | Wait for the required selector or page state and inspect the actual result before capture. |
| CAPTCHA event never arrives | No challenge may have appeared, or the listener may have been attached too late. | Install listeners before navigation. Bound event waits with a timeout so a no-challenge session cannot hang. |
Solver reports found: false |
The challenge may not yet be present when solving begins. | Wait for the challenge/page state, then check the solver result again. |
| Solver reports not solved or page remains blocked | The challenge was not cleared, or another detection condition remains. | Do not treat an attempted solve as success. Verify the page; consider the documented options only if authorized, and stop if access is denied or disallowed. |
| Checkbox still looks unchecked | Browserless notes that a reCAPTCHA checkbox may not appear ticked after solving. | Follow the site’s intended form flow if authorized, then verify the resulting page. |
| Stealth breaks an existing script | Stealth changes browser behavior and may affect assumptions about stock Chrome. | Check the script’s browser-specific dependencies and test its expected page interactions after switching. |
8. Performance, reliability, and cost
Screenshot-only requests avoid the extra interaction work of a full browser workflow, but they still depend on page load and capture waits. Request only the outputs you need from /unblock; Browserless says this can reduce execution time and resource usage. Use bounded timeouts and verify output so slow or challenged pages do not silently become accepted results.
CAPTCHA solving can add seconds to minutes to a session. Browserless’s current guide says successful solves cost 10 units, while unsuccessful attempts are not charged; residential proxy traffic is charged separately by bandwidth. Check the current unit consumption documentation and your plan before estimating production cost, since vendor pricing and product behavior can change.
For reliability, record the requested URL, final navigation result, whether a challenge was detected or solved, and whether the expected page content appeared. Retry only transient failures with a limit; repeated retries against an access-denied or prohibited flow can waste time and incur usage. The research for this guide does not include independent reproduction against any specific target site, and no solve rate or success benchmark is implied.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. Its API takes one GET request with a URL and returns an image or PDF. For example, this saves a screenshot of the target page:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Python and Node.js versions:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write("shot.webp", res);
ScreenshotNeo accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
FAQ
Does a CAPTCHA screenshot prove Browserless failed?
It proves the captured page showed a challenge, not why it appeared or whether the request itself failed. Decide whether the result meets your task by verifying the intended page content.
Should I use stealth or solveCaptchas=true?
Browserless recommends trying its stealth route to reduce challenges, then enabling solving when a challenge still appears and the workflow is authorized. Solving can take longer and may incur usage charges.
Can /unblock return an image?
Yes. Its screenshot option returns a base64-encoded screenshot in the response; request only the output fields you need and decode the screenshot value.
Will a residential proxy guarantee access?
No. It is a documented option for some IP-based blocks, has a bandwidth cost, and does not establish permission or guarantee that the site will serve the requested page.


