Hyperbrowser can automatically detect and solve CAPTCHAs when you enable it during session creation.
CAPTCHA solving requires being on a paid plan.
Enable CAPTCHA Solving
Set the session creation parameter to enable solving:
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
config();
const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});
async function main() {
  const session = await client.sessions.create({
    solveCaptchas: true,
  });
  try {
    console.log("Session Live URL:", session.liveUrl);
    console.log("WS Endpoint:", session.wsEndpoint);
    // ... connect with Playwright/Puppeteer and automate
  } finally {
    await client.sessions.stop(session.id);
  }
}
main().catch(console.error);
Some sites require proxies to be enabled for CAPTCHA solving to work reliably.
Waiting for CAPTCHA Solve
Solving can take time. When navigating to pages that might contain CAPTCHAs, add appropriate waits:
const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
await page.goto("https://news.ycombinator.com/", { waitUntil: "networkidle0" });
await sleep(20_000);
import { Hyperbrowser } from "@hyperbrowser/sdk";
import { config } from "dotenv";
import { chromium } from "playwright";
config();
const client = new Hyperbrowser({
  apiKey: process.env.HYPERBROWSER_API_KEY,
});
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const MAX_DETECTION_TRIES = 10;
const MAX_SOLVED_TRIES = 30;
const waitForCaptcha = async (sessionId: string, startTimestamp: number) => {
  let solved = false;
  let detected = false;
  let detectionTries = 0;
  let solvedTries = 0;
  console.log("Waiting for captcha detection...");
  while (!detected && detectionTries < MAX_DETECTION_TRIES) {
    const resp = await client.sessions.eventLogs.list(sessionId, {
      startTimestamp,
      types: ["captcha_detected"],
    });
    const data = resp.data;
    detected = data.length > 0;
    detectionTries++;
    await sleep(1000);
  }
  if (detected) {
    console.log("Captcha detected!");
  } else {
    console.log("Captcha not detected!");
    return;
  }
  console.log("Waiting for captcha solving...");
  while (!solved && solvedTries < MAX_SOLVED_TRIES) {
    const resp = await client.sessions.eventLogs.list(sessionId, {
      startTimestamp,
      types: ["captcha_solved"],
    });
    const data = resp.data;
    solved = data.length > 0;
    solvedTries++;
    await sleep(1000);
  }
  if (solved) {
    console.log("Captcha solved!");
  } else {
    console.log("Captcha not solved!");
  }
};
const main = async () => {
  const session = await client.sessions.create({
    solveCaptchas: true,
  });
  console.log("Session Live URL:", session.liveUrl);
  try {
    const browser = await chromium.connectOverCDP(session.wsEndpoint);
    const context = browser.contexts()[0];
    const page = context.pages()[0];
    const startTimestamp = Date.now();
    await page.goto("https://2captcha.com/demo/cloudflare-turnstile");
    await waitForCaptcha(session.id, startTimestamp);
    await sleep(5_000);
  } catch (err) {
    console.error(`Error: ${err}`);
  } finally {
    await client.sessions.stop(session.id);
  }
};
main();
Next Steps