«2Captcha»のロゴホームページに戻る
Captchaバイパスのチュートリアル

この記事は役に立ちましたか?

How to use Browser API with captcha solving

Jerry Slimane
Jerry Slimane

Technical engineer

Browser API is a browser that runs on the service side. You don't start Chrome yourself — you connect to a ready one and drive it from your own code: the same navigation, clicks and waits for selectors. Proxies, the browser fingerprint and sessions are handled by the service, and captchas are solved there too — behaviour you can configure.

In the usual setup you started the browser yourself and called a solving method for every captcha: found the parameters on the page, sent the task, waited for the answer, put the token in. Here some of the checks are passed without a single call, and the script simply carries on.

Which captchas the browser solves on its own

Captcha solving is on by default, you don't need to switch it on. The browser passes these checks in the background:

  • reCAPTCHA v2
  • reCAPTCHA v2 Invisible
  • reCAPTCHA v2 Callback
  • reCAPTCHA v2 Enterprise
  • MTCaptcha
  • Cloudflare Turnstile
  • Cloudflare Challenge

The last two are different cases. Turnstile is a widget on the site's own page, while Challenge is a separate verification page that opens instead of the whole site. By hand the second case is harder; the browser passes both the same way.

The list keeps growing: the service adds new checks.

If your captcha is not on the list

Browser API is still a browser, and everything else works as before. A captcha that is not on the list you solve the usual way: find the parameters, send the task through the SDK or straight to the API, get the token and put it into the page. The code does not change — it runs in the cloud browser exactly as it would run in a browser on your own machine.

So Browser API does not replace the solving methods, it takes over part of the work.

What You Will Need

  • Python 3.7 or higher
  • A 2Captcha account with a topped-up balance
  • A browser account created in the Browser API dashboard
  • Paid proxy traffic

Install the libraries like this:

bash Copy
pip install playwright requests
playwright install chromium

Chromium is needed by Playwright itself; the work will be done by the browser on the server.

Step 1. Creating a browser account

A browser account is a separate set of credentials, not your API key. It is created in the Browser API dashboard on the Accounts tab: you give it a name, optionally set your own password, and choose a proxy mode. If you don't set a password, one is generated and shown in the account card.

There are three proxy modes:

  • Proxy in connection URL — your own proxy is passed in the URL itself;
  • 2Captcha paid proxy — you choose a proxy account, a country and an IP lifetime from 0 to 120 minutes, where 0 means a new IP for every request;
  • Custom proxy — the details are stored in the account settings.

Once created, the card shows the login, the password, the proxy details and an API key. The login and password are for connecting; the API key is for the captcha solving methods and for managing accounts from code.

One account holds up to 1000 profiles, and you can have up to 10 accounts.

Step 2. Getting the connection URL

There are two ways to get the URL.

The first is to copy it in the dashboard: the Profiles tab, the "Connection URL (CDP/WebSocket)" line. Good for trying things once.

The second is to request it from the API. That suits a script better: the login, the password and the profile are not stored in the code, an API key and an account number are enough. The number is in the account card, in the "Account ID" line.

python Copy
import os
import requests

API_KEY = os.getenv("APIKEY_2CAPTCHA", "YOUR_API_KEY")
ACCOUNT_ID = 8953

response = requests.post(
    "https://api.2captcha.com/browser/connection",
    json={"key": API_KEY, "accountId": ACCOUNT_ID},
)
cdp_url = response.json()["connectionUri"]

print("Connection URL received")

The answer holds a ready string that looks like this:

Copy
ws://LOGIN-zone-scraping_browser-country-us-pid-PROFILE:PASSWORD@cb.2captcha.com:9222

The server address is the same for both versions of the service — cb.2captcha.com.

You can add profileId to the request and point at a specific profile. If no profile with that identifier exists, it is created right away and counts toward the limit.

If you change profile settings, the changes take effect within ten minutes. A script started right away may still work with the old ones.

Step 3. Connecting from Playwright

Instead of starting a browser, you connect to a ready one using the URL from the previous step. You have to work in the context that already exists on the server.

python Copy
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(cdp_url)
    context = browser.contexts[0]
    page = context.new_page()

    page.goto("https://mysite.com/protected-page")
    page.wait_for_load_state("networkidle")

    print("Title:", page.title())
    browser.close()

There are three differences from ordinary Playwright. Instead of launch() you call connect_over_cdp(). The context is not created anew but taken through browser.contexts[0]. And browser.close() ends not a process on your machine but a session on the server.

Selectors, waits and form filling stay the same.

Step 4. Controlling captcha solving

Solving is on by default, but you can switch it off or change the mode. The settings are passed not as a separate parameter but inside the URL — in the part that comes before the colon and the password. This is the only case where you have to assemble the URL yourself: the method from Step 2 does not accept these fields.

  • -nocaptcha — switches captcha solving off. Written without a value.
  • -clickcaptcha — switches on solving reCAPTCHA by clicking. Also without a value, and not used together with -nocaptcha.
  • -dt-DEVICE — the device type. Defaults to windows, you can pass -dt-android.

The order of the parts is fixed. All three go right after -pid-PROFILE, and -proxy- comes last, before the password:

Copy
LOGIN-zone-scraping_browser-country-COUNTRY-pid-PROFILE-dt-DEVICE-clickcaptcha-proxy-PROXY

Switching captcha solving off looks like this:

python Copy
LOGIN = "YOUR_LOGIN"
PASSWORD = "YOUR_PASSWORD"
PROFILE = "YOUR_PROFILE"

username = f"{LOGIN}-zone-scraping_browser-country-us-pid-{PROFILE}-nocaptcha"
CDP_URL = f"ws://{username}:{PASSWORD}@cb.2captcha.com:9222"

One important limitation: these three settings only work when you assemble the URL yourself. The ready URL from the dashboard does not carry them, and the POST /browser/connection method does not accept such fields. If you want to control captcha solving, assemble the URL by hand.

Step 5. Passing your own proxy in the URL

If the account uses the Proxy in connection URL mode, the proxy address is encoded in base64url and placed after -proxy-.

python Copy
import base64

proxy_url = "http://LOGIN:PASSWORD@proxy.example.com:3128"
encoded = base64.urlsafe_b64encode(proxy_url.encode()).decode().rstrip("=")

username = f"{LOGIN}-zone-scraping_browser-country-us-pid-{PROFILE}-proxy-{encoded}"
CDP_URL = f"ws://{username}:{PASSWORD}@cb.2captcha.com:9222"

In the other two modes the proxy comes from the account settings and must not be in the URL.

Managing accounts and profiles from code

Accounts and profiles can be created not only by hand. Browser API has its own methods at https://api.2captcha.com, with the usual API key in the key parameter. GET requests take parameters in the query string; POST, PUT and DELETE take a JSON body.

Method What it does
GET /browser Account state: available and used traffic, the number of logins and profiles, proxy availability
GET /browser/accounts List of browser logins
POST /browser/accounts Create a login, including one with your own proxy
PUT /browser/accounts Update a login
DELETE /browser/accounts Delete a login
GET /browser/profiles List of profiles for the selected account
POST /browser/profiles Create or update a profile
DELETE /browser/profiles Delete a profile
GET /browser/proxy_accounts List of proxy accounts
POST /browser/connection A ready connection URL for a login or a profile
bash Copy
curl "https://api.2captcha.com/browser?key=YOUR_API_KEY"

The POST /browser/connection method returns a ready connectionUri string. If you name a new profile identifier, the profile is created right away and counts toward the limit.

When the account limit is exceeded, creating a new one is rejected with the ERROR_MAX_ACCOUNTS error.

Complete Working Example (Python)

python Copy
import os

import requests
from playwright.sync_api import sync_playwright

API_KEY = os.getenv("APIKEY_2CAPTCHA", "YOUR_API_KEY")
ACCOUNT_ID = int(os.getenv("BROWSER_ACCOUNT_ID", "8953"))

TARGET_URL = "https://mysite.com/protected-page"


def get_cdp_url():
    response = requests.post(
        "https://api.2captcha.com/browser/connection",
        json={"key": API_KEY, "accountId": ACCOUNT_ID},
        timeout=30,
    )
    data = response.json()

    if "connectionUri" not in data:
        raise RuntimeError(f"No connection URL received: {data}")

    return data["connectionUri"]


def open_protected_page():
    cdp_url = get_cdp_url()

    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(cdp_url)

        try:
            context = browser.contexts[0]
            page = context.new_page()

            page.goto(TARGET_URL)
            page.wait_for_load_state("networkidle")

            print("Title:", page.title())
            print("URL after load:", page.url)

        except Exception as e:
            print(f"Error: {e}")
        finally:
            browser.close()


if __name__ == "__main__":
    open_protected_page()

Troubleshooting Common Issues

  • The connection is not established. Take the login and the password from the browser account card: this is not the API key but a separate pair. And check that the profile named in the URL exists.
  • The captcha settings have no effect. The ready URL from the dashboard does not carry them — assemble the URL yourself, as shown in Step 4.
  • The changes did not apply right away. New profile settings take effect within ten minutes.
  • The script stops at browser.new_context(). The context on the server already exists, take it through browser.contexts[0].
  • The page did not open the first time. When a page is blocked, the service repeats the request itself with a clean IP and a new browser fingerprint before returning an error. If the error still arrives, change the country or the proxy mode.

Conclusion

Browser API takes over part of the work: the checks listed above are passed by the browser itself, and you don't call solving methods for them. The list keeps growing.

The behaviour is configurable. Solving is on by default, -nocaptcha switches it off, -clickcaptcha puts reCAPTCHA into click-solving mode. But these settings only work when the URL is assembled by hand — the ready URL from the dashboard does not carry them.

Moving over from your own Playwright costs one line: launch() becomes connect_over_cdp(), and the context is taken ready. Selectors and script logic are left alone.