DEV Community

luisgustvo
luisgustvo

Posted on

How to Bypass CAPTCHA in Vibium Without Extensions (reCAPTCHA, Turnstile, AWS WAF)

Bypass CAPTCHA in Vibium

When artificial intelligence agents are employed to automate browser interactions for real-world tasks, CAPTCHAs frequently present a significant impediment. These protective measures can block agent access to secured pages, prevent form submissions, and halt entire automated workflows, necessitating human intervention.

Vibium represents a new generation of browser automation tools, designed for both AI agents and human users. Utilizing the WebDriver BiDi protocol, developed by the creators of Selenium and Appium, Vibium offers agents a rapid and standardized method for browser control. However, like other automation tools, it encounters challenges when confronted with CAPTCHAs.

A critical aspect to note is that Vibium's Go launcher hardcodes --disable-extensions, which means custom Chrome flags cannot be passed. Consequently, the Chrome extension-based approaches commonly used by tools such as Playwright and Puppeteer are incompatible with Vibium.

CapSolver addresses this limitation through an alternative methodology. Instead of relying on a browser extension, CapSolver's REST API is directly invoked to bypass the CAPTCHA. The resulting token is then injected into the web page using Vibium's JavaScript evaluation capabilities. This API-centric strategy provides comprehensive control and integrates seamlessly with Vibium's architectural design.


Understanding Vibium

Vibium is a browser automation platform tailored for AI agents and human operators. It is distributed as a standalone Go binary, offering a zero-configuration installation, and leverages the modern WebDriver BiDi protocol for efficient, bidirectional communication with web browsers.

Core Capabilities

  • WebDriver BiDi protocol: A standards-based, bidirectional communication method for browsers, distinct from the Chrome DevTools Protocol (CDP).
  • MCP server: Features an integrated Model Context Protocol server, enabling AI agents to control browsers natively.
  • Semantic element identification: Allows for locating web elements based on their meaning rather than solely on CSS selectors.
  • Multi-language SDKs: Provides client libraries for JavaScript/TypeScript, Python, and Java.
  • Single Go binary: Ensures zero dependencies and configuration, requiring only download and execution.
  • Developed by Selenium/Appium creators: Benefits from extensive expertise in browser automation standards.

AI Agent Application

Vibium's MCP server facilitates AI agents in issuing browser commands through a standardized protocol. Agents can perform actions such as:

  • Navigating to URLs and interacting with page elements.
  • Semantically identifying elements (e.g., "the login button" instead of #btn-login).
  • Executing arbitrary JavaScript on the page via browser_evaluate.
  • Completing forms, clicking buttons, and extracting content.
  • Managing multiple browser sessions.

This functionality essentially provides AI agents with a browser interface that can be controlled using natural language commands.


Understanding CapSolver

CapSolver is a prominent CAPTCHA bypassing service that offers AI-driven solutions for overcoming various CAPTCHA challenges. With support for numerous CAPTCHA types and rapid response times, CapSolver integrates effectively into automated workflows.

Supported CAPTCHA Categories


Distinctive Integration Approach

Most browser automation tools, including Playwright, Puppeteer, OpenClaw, and NanoClaw, typically bypass CAPTCHAs by directly loading the CapSolver Chrome extension into the browser. This extension automatically detects CAPTCHAs, bypasses them in the background, and injects tokens without visible interaction.

Vibium, however, cannot employ this method. Its Go launcher explicitly hardcodes --disable-extensions when launching Chrome, precluding any configuration or workaround for loading extensions.

Instead, this integration directly utilizes the CapSolver REST API:

Feature Extension-Based Approach (e.g., Playwright) API-Based Approach (Vibium)
Mechanism Extension autonomously detects and bypasses CAPTCHAs Your code initiates API calls, retrieves a token, and injects it
Extension Requirement Yes (Chrome extension loaded via --load-extension) No (relies purely on HTTP API calls)
Agent Awareness Agent operates without explicit knowledge of CAPTCHA handling Agent or script actively manages the bypassing process
Chrome Flags Requires --load-extension support Compatible with any Chrome flags, including --disable-extensions
Control Level Automated, opaque Explicit, offering granular control over each step
Flexibility Limited to extension's predefined capabilities Allows customization of detection, retry logic, and token injection per site
Optimal Use Case Tools that permit custom Chrome arguments Tools like Vibium that impose restrictions on Chrome arguments

Key takeaway: The API-based approach offers enhanced capabilities. It provides control over when to detect, when to bypass, and precisely how to inject the token. This method is compatible with any browser automation tool, irrespective of its Chrome flag limitations.


Prerequisites

Before configuring this integration, ensure the following are in place:

  1. Vibium is installed (download from GitHub)
  2. A CapSolver account with an active API key (sign up here)
  3. One of the following environments: Node.js 18+ / Python 3.8+ / Java 17+

Vibium Installation

# For macOS / Linux — single binary, no dependencies
curl -fsSL https://vibium.dev/install.sh | bash

# Alternatively, download directly from GitHub releases
# https://github.com/VibiumDev/vibium/releases
Enter fullscreen mode Exit fullscreen mode

Verify the installation by running:

vibium --version
Enter fullscreen mode Exit fullscreen mode

No Dedicated Chrome Installation Required

Vibium independently manages its browser lifecycle. There is no need to install Chrome for Testing, Playwright's bundled Chromium, or any specific browser variant. Vibium handles the internal download and management of browsers.


Step-by-Step Configuration

Step 1: Obtain Your CapSolver API Key

  1. Register at capsolver.com
  2. Access your dashboard
  3. Copy your API key (it typically begins with CAP-)

Set this key as an environment variable:

export CAPSOLVER_API_KEY="CAP-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Enter fullscreen mode Exit fullscreen mode

Step 2: Install the Vibium SDK and HTTP Client

JavaScript:

npm install vibium
Enter fullscreen mode Exit fullscreen mode

Python:

pip install vibium requests
Enter fullscreen mode Exit fullscreen mode

Java (Gradle):

implementation 'com.vibium:vibium:26.3.18'
Enter fullscreen mode Exit fullscreen mode

Step 3: Develop a CAPTCHA Detection Utility

Prior to bypassing a CAPTCHA, it is necessary to identify its type and extract the site key. This can be achieved by inspecting the page using Vibium's browser_evaluate function.

The JavaScript code for detection remains consistent across all three programming languages; only the host call varies:

JavaScript:

const { browser } = require('vibium/sync')

function detectCaptcha(page) {
  return page.evaluate(`(() => {
    const v2 = document.querySelector('.g-recaptcha');
    if (v2) return { type: 'recaptcha-v2', siteKey: v2.getAttribute('data-sitekey') };

    for (const s of document.querySelectorAll('script[src*="recaptcha/api.js"]')) {
      const m = s.src.match(/render=([^&]+)/);
      if (m && m[1] !== 'explicit') return { type: 'recaptcha-v3', siteKey: m[1] };
    }

    const t = document.querySelector('.cf-turnstile');
    if (t) return { type: 'turnstile', siteKey: t.getAttribute('data-sitekey') };

    return { type: 'none', siteKey: null };
  })()`)
}
Enter fullscreen mode Exit fullscreen mode

Python:

from vibium import browser

def detect_captcha(page) -> dict:
    return page.evaluate("""(() => {
        const v2 = document.querySelector('.g-recaptcha');
        if (v2) return { type: 'recaptcha-v2', siteKey: v2.getAttribute('data-sitekey') };

        for (const s of document.querySelectorAll('script[src*="recaptcha/api.js"]')) {
            const m = s.src.match(/render=([^&]+)/);
            if (m && m[1] !== 'explicit') return { type: 'recaptcha-v3', siteKey: m[1] };
        }

        const t = document.querySelector('.cf-turnstile');
        if (t) return { type: 'turnstile', siteKey: t.getAttribute('data-sitekey') };

        return { type: 'none', siteKey: null };
    })()""")
Enter fullscreen mode Exit fullscreen mode

Java:

var result = page.evaluate("""
    (() => {
        const v2 = document.querySelector('.g-recaptcha');
        if (v2) return { type: 'recaptcha-v2', siteKey: v2.getAttribute('data-sitekey') };

        for (const s of document.querySelectorAll('script[src*="recaptcha/api.js"]')) {
            const m = s.src.match(/render=([^&]+)/);
            if (m && m[1] !== 'explicit') return { type: 'recaptcha-v3', siteKey: m[1] };
        }

        const t = document.querySelector('.cf-turnstile');
        if (t) return { type: 'turnstile', siteKey: t.getAttribute('data-sitekey') };

        return { type: 'none', siteKey: null };
    })()
    """);
String captchaType = (String) ((Map) result).get("type");
String siteKey = (String) ((Map) result).get("siteKey");
Enter fullscreen mode Exit fullscreen mode

Step 4: Implement the CAPTCHA Bypassing Function

Initiate a task with the CapSolver API, then continuously query for the outcome.

JavaScript:

const CAPSOLVER_API = 'https://api.capsolver.com'
const API_KEY = process.env.CAPSOLVER_API_KEY

async function createTask(taskData) {
  const res = await fetch(`${CAPSOLVER_API}/createTask`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ clientKey: API_KEY, task: taskData }),
  })
  const data = await res.json()
  if (data.errorId !== 0) throw new Error(`CapSolver: ${data.errorDescription}`)
  return data.taskId
}

async function getTaskResult(taskId, maxAttempts = 60) {
  for (let i = 0; i < maxAttempts; i++) {
    await new Promise(r => setTimeout(r, 2000))
    const res = await fetch(`${CAPSOLVER_API}/getTaskResult`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clientKey: API_KEY, taskId }),
    })
    const data = await res.json()
    if (data.status === 'ready') return data
    if (data.status === 'failed') throw new Error(`Failed: ${data.errorDescription}`)
  }
  throw new Error('CapSolver: Task timed out')
}

async function bypassCaptcha(info, url) {
  let taskType;
  switch (info.type) {
    case 'recaptcha-v2':
      taskType = 'ReCaptchaV2TaskProxyLess';
      break;
    case 'recaptcha-v3':
      taskType = 'ReCaptchaV3TaskProxyLess';
      break;
    case 'turnstile':
      taskType = 'AntiTurnstileTaskProxyLess';
      break;
    default:
      throw new Error(`Unsupported CAPTCHA type: ${info.type}`);
  }

  const taskId = await createTask({
    type: taskType,
    websiteURL: url,
    websiteKey: info.siteKey,
  });
  const result = await getTaskResult(taskId);
  return result.solution.gRecaptchaResponse || result.solution.token;
}

// Example Usage (JavaScript)
async function main() {
  const bro = await browser.start();
  const page = await bro.page();

  // 1. Navigate
  const targetUrl = "https://www.google.com/recaptcha/api2/demo";
  await page.go(targetUrl);

  // 2. Detect
  const info = await detectCaptcha(page);

  if (info.type === 'none') {
    console.log('No CAPTCHA detected.');
    return;
  }

  console.log(`Detected ${info.type} — key ${info.siteKey}`);

  // 3. Bypass
  const token = await bypassCaptcha(info, targetUrl);
  console.log('Bypassed!');

  // 4. Inject + submit
  await page.evaluate(`
    document.querySelector('textarea[name="g-recaptcha-response"]').value = "${token}";
    try { const c = ___grecaptcha_cfg.clients; for (const id in c) {
      const f = (o) => { for (const k in o) { if (typeof o[k]==='object'&&o[k]!==null) {
        if (typeof o[k].callback==='function'){o[k].callback("${token}");return true}
        if(f(o[k]))return true}} return false}; f(c[id]) }} catch(e){}
  `);
  await page.evaluate(`document.querySelector('#recaptcha-demo-form').submit()`);

  // 5. Verify
  setTimeout(async () => {
    console.log('Result:', await page.evaluate('document.body.innerText'));
    await bro.stop();
  }, 2000);
}

main();
Enter fullscreen mode Exit fullscreen mode

Python:

from vibium import browser
import os, time, requests

CAPSOLVER_API = "https://api.capsolver.com"
API_KEY = os.environ["CAPSOLVER_API_KEY"]

def create_task(task_data):
    res = requests.post(f"{CAPSOLVER_API}/createTask", json={"clientKey": API_KEY, "task": task_data})
    data = res.json()
    if data["errorId"] != 0: raise Exception(f"CapSolver: {data["errorDescription"]}")
    return data["taskId"]

def get_task_result(task_id, max_attempts=60):
    for i in range(max_attempts):
        time.sleep(2)
        res = requests.post(f"{CAPSOLVER_API}/getTaskResult", json={"clientKey": API_KEY, "taskId": task_id})
        data = res.json()
        if data["status"] == 'ready': return data
        if data["status"] == 'failed': raise Exception(f"Failed: {data["errorDescription"]}")
    raise Exception('CapSolver: Task timed out')

def bypass_captcha(info, url):
    task_type = None
    if info["type"] == 'recaptcha-v2':
        task_type = 'ReCaptchaV2TaskProxyLess'
    elif info["type"] == 'recaptcha-v3':
        task_type = 'ReCaptchaV3TaskProxyLess'
    elif info["type"] == 'turnstile':
        task_type = 'AntiTurnstileTaskProxyLess'
    else:
        raise Exception(f"Unsupported CAPTCHA type: {info['type']}")

    task_id = create_task({
        "type": task_type,
        "websiteURL": url,
        "websiteKey": info["siteKey"],
    })
    result = get_task_result(task_id)
    return result["solution"].get("gRecaptchaResponse") or result["solution"].get("token")

def main():
    bro = browser.start()
    page = bro.page()

    # 1. Navigate
    target_url = "https://www.google.com/recaptcha/api2/demo"
    page.go(target_url)

    # 2. Detect
    info = page.evaluate("""(() => {
        const el = document.querySelector('.g-recaptcha');
        return el ? { type: 'recaptcha-v2', siteKey: el.getAttribute('data-sitekey') }
                   : { type: 'none', siteKey: null };
    })()""")

    if info["type"] == "none":
        print("No CAPTCHA detected.")
        return

    print(f"Detected {info['type']} — key {info['siteKey']}")

    # 3. Bypass
    token = bypass_captcha(info, target_url)
    print("Bypassed!")

    # 4. Inject + submit
    page.evaluate(f"""
        document.querySelector('textarea[name="g-recaptcha-response"]').value = "{token}";
        try {{ const c = ___grecaptcha_cfg.clients; for (const id in c) {{
            const f = (o) => {{ for (const k in o) {{ if (typeof o[k]==='object'&&o[k]!==null) {{
                if (typeof o[k].callback==='function'){{o[k].callback("{token}");return true}}
                if(f(o[k]))return true}}}} return false}}; f(c[id]) }}}} catch(e){{}}
        """)
    page.evaluate('document.querySelector("#recaptcha-demo-form").submit()')

    # 5. Verify
    time.sleep(2)
    print("Result:", page.evaluate("document.body.innerText"))
    bro.stop()

main()
Enter fullscreen mode Exit fullscreen mode

Java:

import com.vibium.Vibium;
import org.json.JSONObject;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;

public class CapSolverIntegration {

    private static final String CAPSOLVER_API = "https://api.capsolver.com";
    private static final String API_KEY = System.getenv("CAPSOLVER_API_KEY");

    private static String createTask(JSONObject taskData) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(CAPSOLVER_API + "/createTask"))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(new JSONObject()
                        .put("clientKey", API_KEY)
                        .put("task", taskData).toString()))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        JSONObject data = new JSONObject(response.body());
        if (data.getInt("errorId") != 0) {
            throw new Exception("CapSolver: " + data.getString("errorDescription"));
        }
        return data.getString("taskId");
    }

    private static JSONObject getTaskResult(String taskId, int maxAttempts) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        for (int i = 0; i < maxAttempts; i++) {
            Thread.sleep(2000);
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(CAPSOLVER_API + "/getTaskResult"))
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(new JSONObject()
                            .put("clientKey", API_KEY)
                            .put("taskId", taskId).toString()))
                    .build();
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            JSONObject data = new JSONObject(response.body());
            if (data.getString("status").equals("ready")) return data;
            if (data.getString("status").equals("failed")) throw new Exception("Failed: " + data.getString("errorDescription"));
        }
        throw new Exception("CapSolver: Task timed out");
    }

    private static String bypassCaptcha(Map<String, Object> info, String url) throws Exception {
        String taskType;
        switch ((String) info.get("type")) {
            case "recaptcha-v2":
                taskType = "ReCaptchaV2TaskProxyLess";
                break;
            case "recaptcha-v3":
                taskType = "ReCaptchaV3TaskProxyLess";
                break;
            case "turnstile":
                taskType = "AntiTurnstileTaskProxyLess";
                break;
            default:
                throw new Exception("Unsupported CAPTCHA type: " + info.get("type"));
        }

        JSONObject taskData = new JSONObject()
                .put("type", taskType)
                .put("websiteURL", url)
                .put("websiteKey", info.get("siteKey"));
        String taskId = createTask(taskData);
        JSONObject result = getTaskResult(taskId, 60);
        return result.getJSONObject("solution").optString("gRecaptchaResponse", result.getJSONObject("solution").getString("token"));
    }

    public static void main(String[] args) throws Exception {
        var bro = Vibium.start();
        var page = bro.page();

        // 1. Navigate
        var targetUrl = "https://www.google.com/recaptcha/api2/demo";
        page.go(targetUrl);

        // 2. Detect
        var info = (Map<String, Object>) page.evaluate("""
            (() => {
                const el = document.querySelector('.g-recaptcha');
                return el ? { type: 'recaptcha-v2', siteKey: el.getAttribute('data-sitekey') }
                           : { type: 'none', siteKey: null };
            })()""");

        if ("none".equals(info.get("type"))) {
            System.out.println("No CAPTCHA detected.");
            return;
        }

        System.out.printf("Detected %s — key %s%n", info.get("type"), info.get("siteKey"));

        // 3. Bypass
        var token = bypassCaptcha(info, targetUrl);
        System.out.println("Bypassed!");

        // 4. Inject + submit
        page.evaluate(String.format("""
            document.querySelector('textarea[name="g-recaptcha-response"]').value = "%s";
            try { const c = ___grecaptcha_cfg.clients; for (const id in c) {
                const f = (o) => { for (const k in o) { if (typeof o[k]==='object'&&o[k]!==null) {
                    if (typeof o[k].callback==='function'){o[k].callback("%s");return true}
                    if(f(o[k]))return true}}}} return false}; f(c[id]) }}}} catch(e){}
            """, token, token));
        page.evaluate("document.querySelector('#recaptcha-demo-form').submit()");

        // 5. Verify
        Thread.sleep(2000);
        System.out.println("Result: " + page.evaluate("document.body.innerText"));
        bro.stop();
    }
}
Enter fullscreen mode Exit fullscreen mode

Supported CAPTCHA Task Categories

CAPTCHA Type CapSolver Task Type Token Field Estimated Bypass Time
reCAPTCHA v2 ReCaptchaV2TaskProxyLess textarea[name="g-recaptcha-response"] 5-15 seconds
reCAPTCHA v2 (invisible) ReCaptchaV2TaskProxyLess textarea[name="g-recaptcha-response"] 5-15 seconds
reCAPTCHA v3 ReCaptchaV3TaskProxyLess input[name="g-recaptcha-response"] 3-10 seconds
reCAPTCHA Enterprise ReCaptchaV2EnterpriseTaskProxyLess textarea[name="g-recaptcha-response"] 10-20 seconds
Cloudflare Turnstile AntiTurnstileTaskProxyLess input[name="cf-turnstile-response"] 3-10 seconds
AWS WAF AntiAwsWafTaskProxyLess Custom (site-dependent) 5-15 seconds
GeeTest v3/v4 GeeTestTaskProxyLess Custom (site-dependent) 5-15 seconds

Troubleshooting Guide

Token Expiration Before Form Submission

Symptom: The form is submitted, but the server rejects the CAPTCHA response.

Cause: CAPTCHA tokens possess a limited validity period (typically 90-120 seconds for reCAPTCHA, 300 seconds for Turnstile). If there is an excessive delay between bypassing the CAPTCHA and submitting the form, the token may expire.

Resolution: Inject and submit the token immediately upon receipt. Avoid introducing unnecessary delays between the bypassing and submission steps.

CAPTCHA Not Detected on Page

Symptom: The detection script reports { type: 'none' } even when a CAPTCHA is visibly present.

Potential Causes:

  1. Incomplete page loading — Introduce a waiting period after navigation (e.g., time.sleep(3)).
  2. CAPTCHA within an iframe — Some reCAPTCHA implementations load inside an iframe. It may be necessary to detect the iframe and extract the site key from the page source or network requests.
  3. Dynamic loading — The CAPTCHA widget might load asynchronously. Wait for the element to appear before attempting detection.

CapSolver API Errors

Common Error Scenarios:

Error Code Underlying Cause Corrective Action
ERROR_KEY_DOES_NOT_EXIST Invalid API key provided Verify your CAPSOLVER_API_KEY setting
ERROR_ZERO_BALANCE Insufficient credits in your account Recharge your account at capsolver.com
ERROR_WRONG_CAPTCHA_TYPE Incorrect task type specified for the CAPTCHA Confirm the CAPTCHA type using the detection utility
ERROR_CAPTCHA_UNSOLVABLE The CAPTCHA could not be bypassed Attempt a retry, as transient failures can occur

CORS Issues During CapSolver API Calls

Symptom: API requests originating from the browser fail due to Cross-Origin Resource Sharing (CORS) policies.

Cause: This occurs when attempting to invoke the CapSolver API from within browser_evaluate (i.e., from the browser's context). The CapSolver API does not permit cross-origin requests from arbitrary websites.

Resolution: Always make CapSolver API calls from your script's environment (Node.js, Python, or Java process), not from within the browser. browser_evaluate should be reserved for detection (reading the DOM) and injection (setting form values). API interactions must be handled server-side.

Form Submission Failure

Symptom: The token is injected, but the form either fails to submit or the server does not accept it.

Potential Causes:

  1. Missing callback trigger — Many reCAPTCHA implementations require the callback function to be invoked with the token, not merely setting the textarea value. Refer to the injectToken function example above, which traverses ___grecaptcha_cfg.clients to locate and trigger the callback.
  2. Custom form validation — The website may incorporate additional JavaScript validation. Inspect the form's submit handler in developer tools.
  3. Token format discrepancy — Ensure that gRecaptchaResponse is used for reCAPTCHA and token for Turnstile, as provided by the CapSolver result.

Best Practices

1. Implement a Sensible Polling Interval

Query /getTaskResult every 2 seconds. More frequent polling can lead to wasted API calls and potential rate limiting. Less frequent polling introduces unnecessary latency.

// JavaScript: Optimal — 2-second interval
await new Promise(r => setTimeout(r, 2000))
Enter fullscreen mode Exit fullscreen mode
# Python: Optimal — 2-second interval
time.sleep(2)
Enter fullscreen mode Exit fullscreen mode
// Java: Optimal — 2-second interval
Thread.sleep(2000);
Enter fullscreen mode Exit fullscreen mode

2. Incorporate Retry Logic with Exponential Backoff

CAPTCHA bypassing can occasionally encounter failures. Encapsulate your bypassing function with retry mechanisms:

JavaScript:

async function bypassWithRetry(info, url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try { return await bypassCaptcha(info, url) }
    catch (e) {
      if (i === retries - 1) throw e
      await new Promise(r => setTimeout(r, 2 ** i * 1000))
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Python:

def bypass_with_retry(info, url, retries=3):
    for i in range(retries):
        try: return bypass_captcha(info, url)
        except Exception:
            if i == retries - 1: raise
            time.sleep(2 ** i)
Enter fullscreen mode Exit fullscreen mode

3. Utilize the Appropriate Task Type for Each CAPTCHA

Employing an incorrect task type will result in bypassing failure. Always detect the CAPTCHA type initially, then map it to the corresponding CapSolver task:

CAPTCHA Type CapSolver Task Type
reCAPTCHA v2 (checkbox) ReCaptchaV2TaskProxyLess
reCAPTCHA v2 (invisible) ReCaptchaV2TaskProxyLess
reCAPTCHA v3 ReCaptchaV3TaskProxyLess
reCAPTCHA v2 Enterprise ReCaptchaV2EnterpriseTaskProxyLess
reCAPTCHA v3 Enterprise ReCaptchaV3EnterpriseTaskProxyLess
Cloudflare Turnstile AntiTurnstileTaskProxyLess
AWS WAF AntiAwsWafTaskProxyLess

4. Immediate Injection and Submission

CAPTCHA tokens have a limited lifespan. Once the token is received from CapSolver, inject it and submit the form as swiftly as possible. Avoid introducing artificial delays between the bypassing and submission phases.

5. Monitor Balance Before Extended Operations

JavaScript:

const res = await fetch(`${CAPSOLVER_API}/getBalance`, {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ clientKey: API_KEY }),
})
const { balance } = await res.json()
if (balance < 1) console.warn('Low CapSolver balance!')
Enter fullscreen mode Exit fullscreen mode

Python:

balance = requests.post(f"{CAPSOLVER_API}/getBalance",
    json={"clientKey": API_KEY}).json().get("balance", 0)
if balance < 1:
    print("Low CapSolver balance!")
Enter fullscreen mode Exit fullscreen mode

6. Maintain Server-Side API Calls

Never invoke the CapSolver API from within browser_evaluate. HTTP requests made from the browser context will fail due to CORS restrictions, and exposing your API key in browser-side JavaScript poses a security risk. All API calls must originate from your application's process (Node.js, Python, or Java).


Conclusion

The integration of Vibium with the CapSolver API demonstrates that browser extensions are not a prerequisite for bypassing CAPTCHAs in automated workflows. When a tool like Vibium imposes restrictions on Chrome flags, the API-based approach offers enhanced control, rather than diminished capabilities:

  1. Detect the CAPTCHA type and site key using browser_evaluate.
  2. Bypass the CAPTCHA by invoking the CapSolver REST API from your script.
  3. Inject the obtained token back into the page via browser_evaluate.
  4. Submit the form.

This methodology is applicable to any browser automation tool that supports JavaScript evaluation, extending beyond just Vibium. Regardless of whether you are utilizing WebDriver BiDi, CDP, or another protocol, the CapSolver API approach provides a universal solution.

By combining Vibium's standards-compliant browser automation with CapSolver's efficient and dependable CAPTCHA bypassing API, a robust pipeline is established for seamless automated operations.

Top comments (0)