How to bypass captcha in Google Chrome browser with solver
Captchas can interrupt browser automation, QA testing, data collection, and other authorized workflows in Google Chrome.
The correct integration depends on how much automation you need.
You can:
- Test SolveCaptcha requests manually through Postman.
- Use the SolveCaptcha browser extension directly in Chrome.
- Connect to the SolveCaptcha API from Python.
- Combine the API with Selenium or Puppeteer.
The general workflow is:
Open the protected page in Chrome
→ identify the captcha type
→ extract the required public parameters
→ submit them to SolveCaptcha
→ wait for the solution
→ apply the returned token or answer
→ continue the normal page workflow
This guide uses reCAPTCHA v2 as the main example because its token workflow is easy to demonstrate. Other captcha types require different parameters and may return a token, cookie, coordinates, or text answer.
Use these methods only on websites you own or are authorized to test and automate.
What you need
Before starting, prepare:
- Google Chrome;
- a SolveCaptcha account;
- your SolveCaptcha API key;
- Postman for manual API testing;
- Python 3.10 or later for Python automation;
- Selenium or Puppeteer for browser automation;
- the URL of the page containing the captcha.
Copy the API key from your SolveCaptcha account settings.
Store it in an environment variable rather than placing it directly in source code.
Linux or macOS:
export SOLVECAPTCHA_API_KEY="YOUR_API_KEY"
Windows PowerShell:
$env:SOLVECAPTCHA_API_KEY="YOUR_API_KEY"
Do not expose the API key in:
- browser-console scripts;
- public repositories;
- screenshots;
- application logs;
- client-side JavaScript;
- shared Postman collections.
Captcha types supported by SolveCaptcha
SolveCaptcha supports common visual, interactive, and token-based challenges, including:
- image and letter captchas;
- text questions;
- reCAPTCHA v2;
- Invisible reCAPTCHA v2;
- reCAPTCHA v3;
- reCAPTCHA Enterprise;
- Cloudflare Turnstile;
- Arkose Labs FunCaptcha;
- GeeTest v3 and v4;
- Friendly Captcha;
- DataDome;
- Amazon AWS WAF CAPTCHA;
- audio captchas;
- coordinate and grid challenges.
Each captcha type has its own required parameters and result format.
For example:
| Captcha type | Typical input | Typical result |
|---|---|---|
| Image captcha | Image file or Base64 data | Recognized text |
| reCAPTCHA v2 | Site key and page URL | Response token |
| reCAPTCHA v3 | Site key, page URL, action, score | Response token |
| FunCaptcha | Public key, page URL, optional blob | Session token |
| DataDome | Captcha URL, proxy, User-Agent | datadome cookie |
| Amazon WAF | Site key, context, IV | Voucher and token |
| Coordinate captcha | Image and instruction | Click coordinates |
Do not use one generic request body for every captcha provider.
Check the SolveCaptcha API documentation and select the method that matches the captcha detected in Chrome.
Three ways to solve captchas in Chrome
The three main integration options are:
| Method | Coding required | Automation level | Best use case |
|---|---|---|---|
| Postman | No | Manual | API testing and debugging |
| Browser extension | Minimal | Semi-automatic or automatic | Interactive Chrome workflows |
| Direct API | Yes | Full | Production automation |
Postman is the easiest way to understand the API.
The extension is convenient when you want the solution applied inside Chrome.
Direct API integration provides the most control over parameters, polling, proxy configuration, and error handling.
Method 1: Test captcha solving with Postman
Postman does not modify the Chrome page automatically.
It allows you to:
- create the SolveCaptcha task;
- retrieve the completed token;
- copy the result;
- apply it manually in Chrome.
This is useful before implementing a complete automation script.
SolveCaptcha API endpoints
Create a task through:
POST https://api.solvecaptcha.com/in.php
Retrieve the result through:
GET https://api.solvecaptcha.com/res.php
Do not use unrelated API structures such as:
/createTask
/getTaskResult
clientKey
websiteKey
websiteURL
RecaptchaV2TaskProxyless
For reCAPTCHA v2, the documented parameters are:
key
method=userrecaptcha
googlekey
pageurl
json=1
Create a Postman request
Create a new POST request in Postman:
https://api.solvecaptcha.com/in.php
Open the Body tab and select:
x-www-form-urlencoded
Add these fields:
| Key | Value |
|---|---|
key |
Your SolveCaptcha API key |
method |
userrecaptcha |
googlekey |
The reCAPTCHA site key |
pageurl |
Full URL containing the captcha |
json |
1 |
Example:
key=YOUR_API_KEY
method=userrecaptcha
googlekey=6LcExampleSiteKey
pageurl=https://example.com/login
json=1
A successful response contains a task ID:
{
"status": 1,
"request": "2122988149"
}
Save the value returned in:
request
Import the request from cURL
Postman can also import this cURL request:
curl --request POST \
--url https://api.solvecaptcha.com/in.php \
--data-urlencode "key=YOUR_API_KEY" \
--data-urlencode "method=userrecaptcha" \
--data-urlencode "googlekey=6LcExampleSiteKey" \
--data-urlencode "pageurl=https://example.com/login" \
--data-urlencode "json=1"
In Postman:
- Click Import.
- Select Raw text.
- Paste the cURL command.
- Confirm the import.
- Replace the example values.
- Send the request.
Retrieve the result in Postman
Create a GET request:
https://api.solvecaptcha.com/res.php
Add these query parameters:
| Key | Value |
|---|---|
key |
Your SolveCaptcha API key |
action |
get |
id |
Task ID returned by in.php |
json |
1 |
Example URL:
https://api.solvecaptcha.com/res.php?key=YOUR_API_KEY&action=get&id=2122988149&json=1
If the task is still processing:
{
"status": 0,
"request": "CAPCHA_NOT_READY"
}
Wait five seconds and send the same request again.
Do not create another task while the first task is still processing.
A completed response looks like this:
{
"status": 1,
"request": "03AFcWeA5dCJ..."
}
The value in request is the reCAPTCHA response token.
Apply a reCAPTCHA v2 token in Chrome
Open Chrome DevTools and select the Console tab.
Use this script:
function applyRecaptchaToken(token) {
const fields = [
...document.querySelectorAll(
'[name="g-recaptcha-response"]'
)
];
for (const field of fields) {
field.value = token;
field.innerHTML = token;
field.dispatchEvent(
new Event("input", {
bubbles: true
})
);
field.dispatchEvent(
new Event("change", {
bubbles: true
})
);
}
return {
fieldsUpdated: fields.length
};
}
console.log(
applyRecaptchaToken(
"TOKEN_FROM_SOLVECAPTCHA"
)
);
Do not use only:
document.getElementById(
"g-recaptcha-response"
).textContent = "TOKEN";
The page may contain several response fields, and application code may read the value property rather than textContent.
Call the captcha callback when required
A reCAPTCHA widget may define:
<div
class="g-recaptcha"
data-sitekey="SITE_KEY"
data-callback="onCaptchaSolved">
</div>
After updating the response field, call:
window.onCaptchaSolved(
"TOKEN_FROM_SOLVECAPTCHA"
);
For a nested callback:
application.forms.onCaptchaSolved
use:
function resolveFunction(path) {
const value = path
.split(".")
.reduce(
(object, key) =>
object?.[key],
window
);
return typeof value === "function"
? value
: null;
}
const callback = resolveFunction(
"application.forms.onCaptchaSolved"
);
if (callback) {
callback(
"TOKEN_FROM_SOLVECAPTCHA"
);
}
Do not call an arbitrary function simply because its name contains captcha.
Use the callback configured by the current page.
Limitations of the Postman method
Postman is useful for testing, but it is not a complete Chrome automation solution.
Limitations include:
- task creation is manual;
- polling is manual unless you create a Postman script;
- the token must be copied into Chrome;
- session-dependent parameters may change;
- short-lived tokens must be used immediately;
- different captcha types require different result handling.
Move to the extension or direct API integration when the workflow becomes repetitive.
Method 2: Use the SolveCaptcha Chrome extension
The SolveCaptcha browser extension is the simplest way to solve supported captchas directly inside Chrome.
The extension can inspect the current page, detect supported widgets, send the required parameters to SolveCaptcha, and apply the returned result.
The exact controls and labels may vary between extension versions, but the basic setup remains the same.
Install and configure the extension
- Install the official SolveCaptcha extension for Chrome.
- Open the extension settings.
- Enter your SolveCaptcha API key.
- Enable only the captcha types you need.
- Choose manual or automatic solving.
- Open a supported page.
- Start the solve action.
- Wait for the result.
- Continue the normal page workflow.
Use manual mode while testing the integration.
Enable automatic solving only after confirming that the extension behaves correctly on the target page.
Manual and automatic modes
The extension can generally be used in two ways.
Manual solving
The extension detects the captcha and displays a solve control.
You decide when to submit the challenge.
This mode is better for:
- debugging;
- one-off tasks;
- login forms;
- pages with several captchas;
- workflows where the page must be completed before solving.
Automatic solving
The extension submits supported challenges as soon as they are detected.
This mode is useful for repeatable workflows but can cause problems when:
- the page reloads the captcha frequently;
- the form is incomplete;
- the captcha is connected to another button;
- automatic submission creates a loop;
- several widgets exist on the page.
Test automatic mode carefully before relying on it.
Image captchas
A basic image captcha usually has two separate elements:
- the image containing distorted text;
- the input where the answer must be entered.
When automatic detection is unavailable, the extension may require you to identify both elements manually.
The typical setup is:
- select the captcha image;
- mark it as the image to solve;
- select the corresponding answer field;
- mark it as the destination for the result;
- save the configuration for the domain.
Confirm that the selected image belongs to the current captcha and not to a logo, icon, or previous challenge.
Avoid automatic submission loops
Automatic form submission can cause repeated solving when:
- required fields are empty;
- the password is invalid;
- CSRF validation fails;
- the page regenerates the captcha;
- the website returns to the same form;
- the extension immediately detects the new challenge.
During setup:
Disable automatic submission
→ solve one challenge
→ verify that the answer is inserted correctly
→ submit the form manually
→ inspect the result
→ enable automatic submission only if necessary
Use a finite retry limit in automated workflows.
Token freshness
Captcha tokens are generally short-lived and often single-use.
After a token is returned:
- apply it immediately;
- do not reload the page;
- do not change the browser session;
- do not reuse it for another form submission;
- request a new token when the widget resets.
Do not rely on one fixed lifetime for every captcha provider.
Launch Chrome with an unpacked extension using Selenium
For controlled testing, Selenium can launch Chrome with an unpacked extension.
from pathlib import Path
from selenium import webdriver
extension_path = Path(
"/absolute/path/to/SolveCaptchaExtension"
).resolve()
if not extension_path.is_dir():
raise FileNotFoundError(
f"Extension directory not found: "
f"{extension_path}"
)
options = webdriver.ChromeOptions()
options.add_argument(
f"--disable-extensions-except={extension_path}"
)
options.add_argument(
f"--load-extension={extension_path}"
)
driver = webdriver.Chrome(
options=options
)
driver.get(
"https://example.com/login"
)
Configure the extension through its own settings before using it.
For persistent settings, launch Chrome with a dedicated user-data directory:
options.add_argument(
"--user-data-dir=/absolute/path/"
"to/chrome-profile"
)
Do not use your primary personal Chrome profile for automated testing.
Extension advantages
- minimal code;
- works inside the browser session;
- convenient for manual and semi-automatic workflows;
- can handle several supported captcha types;
- returned results can be applied directly to the page;
- useful for QA and interactive browser testing.
Extension limitations
- requires a Chrome session;
- detection may depend on the page implementation;
- dynamically loaded widgets may require additional time;
- custom callbacks may not be triggered automatically;
- extension behavior can vary between websites;
- complex application state may still require custom code.
Use direct API integration when you need predictable control over each step.
Method 3: Full automation through the SolveCaptcha API
Direct API integration gives you control over:
- captcha detection;
- parameter extraction;
- task creation;
- polling;
- proxy configuration;
- timeouts;
- token insertion;
- callback execution;
- error handling;
- logging.
The following example solves reCAPTCHA v2.
Complete Python API client
Install Requests:
python -m pip install requests
Create solve_recaptcha.py:
#!/usr/bin/env python3
from __future__ import annotations
import os
import time
from dataclasses import dataclass
from typing import Any
import requests
CREATE_TASK_URL = (
"https://api.solvecaptcha.com/in.php"
)
GET_RESULT_URL = (
"https://api.solvecaptcha.com/res.php"
)
INITIAL_WAIT_SECONDS = 20
POLL_INTERVAL_SECONDS = 5
MAX_WAIT_SECONDS = 180
class SolveCaptchaError(RuntimeError):
"""Raised when SolveCaptcha returns an error."""
@dataclass(frozen=True)
class CaptchaSolution:
task_id: str
token: str
def parse_response(
response: requests.Response,
) -> dict[str, Any]:
response.raise_for_status()
try:
result = response.json()
except ValueError as exc:
raise SolveCaptchaError(
"SolveCaptcha returned invalid JSON: "
f"{response.text[:500]}"
) from exc
if not isinstance(result, dict):
raise SolveCaptchaError(
f"Unexpected API response: {result!r}"
)
return result
def create_task(
*,
api_key: str,
site_key: str,
page_url: str,
invisible: bool = False,
user_agent: str | None = None,
proxy: str | None = None,
proxy_type: str | None = None,
) -> str:
payload: dict[str, Any] = {
"key": api_key,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"json": 1,
}
if invisible:
payload["invisible"] = 1
if user_agent:
payload["userAgent"] = (
user_agent
)
if proxy:
payload["proxy"] = proxy
if proxy_type:
payload["proxytype"] = (
proxy_type
)
response = requests.post(
CREATE_TASK_URL,
data=payload,
timeout=30,
)
result = parse_response(
response
)
if result.get("status") != 1:
raise SolveCaptchaError(
"Task creation failed: "
f"{result.get('request')}"
)
task_id = str(
result.get("request", "")
).strip()
if not task_id:
raise SolveCaptchaError(
"SolveCaptcha did not return "
"a task ID."
)
return task_id
def get_result(
*,
api_key: str,
task_id: str,
) -> str | None:
response = requests.get(
GET_RESULT_URL,
params={
"key": api_key,
"action": "get",
"id": task_id,
"json": 1,
},
timeout=30,
)
result = parse_response(
response
)
if result.get("status") == 1:
token = str(
result.get("request", "")
).strip()
if not token:
raise SolveCaptchaError(
"SolveCaptcha returned "
"an empty token."
)
return token
error_code = str(
result.get(
"request",
"UNKNOWN_ERROR",
)
)
if error_code == "CAPCHA_NOT_READY":
return None
raise SolveCaptchaError(
f"Task failed: {error_code}"
)
def solve_recaptcha(
*,
api_key: str,
site_key: str,
page_url: str,
invisible: bool = False,
user_agent: str | None = None,
proxy: str | None = None,
proxy_type: str | None = None,
) -> CaptchaSolution:
task_id = create_task(
api_key=api_key,
site_key=site_key,
page_url=page_url,
invisible=invisible,
user_agent=user_agent,
proxy=proxy,
proxy_type=proxy_type,
)
time.sleep(
INITIAL_WAIT_SECONDS
)
deadline = (
time.monotonic()
+ MAX_WAIT_SECONDS
)
while time.monotonic() < deadline:
token = get_result(
api_key=api_key,
task_id=task_id,
)
if token is not None:
return CaptchaSolution(
task_id=task_id,
token=token,
)
time.sleep(
POLL_INTERVAL_SECONDS
)
raise TimeoutError(
f"Task {task_id} was not completed "
f"within {MAX_WAIT_SECONDS} seconds."
)
def main() -> None:
api_key = os.environ.get(
"SOLVECAPTCHA_API_KEY",
"",
).strip()
if not api_key:
raise SystemExit(
"Set SOLVECAPTCHA_API_KEY."
)
solution = solve_recaptcha(
api_key=api_key,
site_key="6LcExampleSiteKey",
page_url=(
"https://example.com/login"
),
)
print(
"Task ID:",
solution.task_id,
)
print(
"Token:",
solution.token,
)
if __name__ == "__main__":
main()
Run it:
python solve_recaptcha.py
Use a proxy with the API
For captcha types that support or require a proxy, send:
proxy=login:password@host:port
proxytype=HTTP
Example:
solution = solve_recaptcha(
api_key=api_key,
site_key="6LcExampleSiteKey",
page_url=(
"https://example.com/login"
),
proxy=(
"user:password@"
"proxy.example.com:8000"
),
proxy_type="HTTP",
)
Supported proxy types can include:
HTTP
HTTPS
SOCKS4
SOCKS5
Do not split the proxy into unsupported fields such as:
proxyAddress
proxyPort
proxyLogin
proxyPassword
The documented format is:
proxy=login:password@host:port
Use the same proxy throughout a session when the captcha or target website connects the challenge to the source IP.
Integrate the API with Selenium
Install Selenium:
python -m pip install selenium
Example:
#!/usr/bin/env python3
from __future__ import annotations
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from solve_recaptcha import (
solve_recaptcha,
)
TARGET_URL = (
"https://example.com/login"
)
def detect_recaptcha(
driver,
) -> dict:
return driver.execute_script(
"""
const result = {
siteKey: null,
invisible: false,
callbackName: null,
domain: "google.com"
};
const widget = document.querySelector(
".g-recaptcha[data-sitekey],"
+ "[data-sitekey]"
);
if (widget) {
result.siteKey =
widget.getAttribute(
"data-sitekey"
);
result.invisible =
widget.getAttribute(
"data-size"
) === "invisible";
result.callbackName =
widget.getAttribute(
"data-callback"
);
}
const frame = document.querySelector(
'iframe[src*="/recaptcha/api2/anchor"]'
);
if (frame?.src) {
const url = new URL(
frame.src
);
result.siteKey =
result.siteKey
|| url.searchParams.get("k");
result.invisible =
result.invisible
|| url.searchParams.get("size")
=== "invisible";
result.domain =
url.hostname.includes(
"recaptcha.net"
)
? "recaptcha.net"
: "google.com";
}
return result;
"""
)
def apply_token(
driver,
*,
token: str,
callback_name: str | None,
) -> dict:
return driver.execute_script(
"""
const token = arguments[0];
const callbackName = arguments[1];
const fields = [
...document.querySelectorAll(
'[name="g-recaptcha-response"]'
)
];
for (const field of fields) {
field.value = token;
field.innerHTML = token;
field.dispatchEvent(
new Event("input", {
bubbles: true
})
);
field.dispatchEvent(
new Event("change", {
bubbles: true
})
);
}
let callbackCalled = false;
if (callbackName) {
const callback = callbackName
.split(".")
.reduce(
(object, key) =>
object?.[key],
window
);
if (
typeof callback
=== "function"
) {
callback(token);
callbackCalled = true;
}
}
return {
fieldsUpdated: fields.length,
callbackCalled
};
""",
token,
callback_name,
)
def main() -> None:
api_key = os.environ.get(
"SOLVECAPTCHA_API_KEY",
"",
).strip()
if not api_key:
raise SystemExit(
"Set SOLVECAPTCHA_API_KEY."
)
driver = webdriver.Chrome()
try:
driver.get(
TARGET_URL
)
parameters = detect_recaptcha(
driver
)
site_key = str(
parameters.get(
"siteKey"
)
or ""
).strip()
if not site_key:
raise RuntimeError(
"reCAPTCHA site key "
"was not found."
)
user_agent = (
driver.execute_script(
"return navigator.userAgent"
)
)
solution = solve_recaptcha(
api_key=api_key,
site_key=site_key,
page_url=driver.current_url,
invisible=bool(
parameters.get(
"invisible"
)
),
user_agent=user_agent,
)
result = apply_token(
driver,
token=solution.token,
callback_name=parameters.get(
"callbackName"
),
)
print(
"Task ID:",
solution.task_id,
)
print(
"Fields updated:",
result["fieldsUpdated"],
)
print(
"Callback called:",
result["callbackCalled"],
)
submit_button = (
driver.find_element(
By.CSS_SELECTOR,
"#submit-button"
)
)
submit_button.click()
finally:
driver.quit()
if __name__ == "__main__":
main()
Replace:
TARGET_URL
and:
#submit-button
with values from the application you are testing.
Pass tokens safely to JavaScript
Avoid inserting the token directly into a Python f-string:
driver.execute_script(
f"callback('{token}')"
)
The token may contain characters that break the generated JavaScript.
Pass the token through arguments:
driver.execute_script(
"""
const token = arguments[0];
window.callback(token);
""",
token,
)
This is safer and easier to debug.
How to find the reCAPTCHA site key in Chrome
Without the correct site key, SolveCaptcha cannot create the appropriate task.
Find data-sitekey
Open Chrome DevTools:
F12
or:
Ctrl+Shift+I
On macOS:
Command+Option+I
Open the Elements tab and search for:
data-sitekey
Example:
<div
class="g-recaptcha"
data-sitekey="6LcExampleSiteKey">
</div>
The value of data-sitekey is sent as:
googlekey
Find the site key in an iframe
A reCAPTCHA iframe may contain:
https://www.google.com/recaptcha/api2/anchor?k=SITE_KEY
The site key is the value of:
k
Search the Network panel for:
recaptcha/api2/anchor
Find a reCAPTCHA v3 site key
reCAPTCHA v3 may load:
<script
src="https://www.google.com/recaptcha/api.js?render=SITE_KEY">
</script>
The site key is the value of:
render
You must also identify the action:
grecaptcha.execute(
"SITE_KEY",
{
action: "login"
}
);
The action in this example is:
login
A reCAPTCHA v3 task requires additional parameters such as:
version=v3
action=login
min_score=0.3
Do not use a reCAPTCHA v2 request unchanged for v3.
Chrome console detector
Run this in DevTools:
function detectRecaptcha() {
const result = {
siteKey: null,
version: null,
invisible: false,
actions: [],
callbackName: null
};
const widget = document.querySelector(
".g-recaptcha[data-sitekey],"
+ "[data-sitekey]"
);
if (widget) {
result.siteKey =
widget.getAttribute(
"data-sitekey"
);
result.version = "v2";
result.invisible =
widget.getAttribute(
"data-size"
) === "invisible";
result.callbackName =
widget.getAttribute(
"data-callback"
);
}
for (const script of document.scripts) {
if (script.src) {
try {
const url = new URL(
script.src
);
const render =
url.searchParams.get(
"render"
);
if (
render
&& render !== "explicit"
) {
result.siteKey =
result.siteKey || render;
result.version = "v3";
}
} catch {
// Ignore malformed script URLs.
}
}
const source =
script.textContent || "";
const actionPattern =
/action\s*:\s*["'`]([^"'`]+)["'`]/g;
for (
const match of source.matchAll(
actionPattern
)
) {
result.actions.push(
match[1]
);
}
}
result.actions = [
...new Set(result.actions)
];
return result;
}
console.log(
detectRecaptcha()
);
Review the result manually. Bundled or dynamically generated scripts may require inspection through the Sources panel.
Bonus: Puppeteer with the SolveCaptcha extension
Puppeteer can launch Chrome with an unpacked extension.
For predictable behavior, use headed Chrome during extension testing.
Install Puppeteer:
npm install puppeteer
Create run-with-extension.js:
const path = require("node:path");
const puppeteer = require("puppeteer");
const extensionPath = path.resolve(
__dirname,
"SolveCaptchaExtension"
);
const profilePath = path.resolve(
__dirname,
"chrome-profile"
);
async function main() {
const browser =
await puppeteer.launch({
headless: false,
userDataDir: profilePath,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`
]
});
try {
const pages =
await browser.pages();
const page =
pages[0]
|| await browser.newPage();
await page.goto(
"https://example.com/login",
{
waitUntil: "domcontentloaded"
}
);
await page.waitForFunction(
() => {
const fields = [
...document.querySelectorAll(
'[name="g-recaptcha-response"]'
)
];
return fields.some(
(field) =>
typeof field.value === "string"
&& field.value.length > 20
);
},
{
timeout: 180000
}
);
await page.click(
"#submit-button"
);
await page.waitForNavigation({
waitUntil: "domcontentloaded",
timeout: 30000
}).catch(() => {
// Some forms update the page without navigation.
});
} finally {
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Update:
SolveCaptchaExtension
https://example.com/login
#submit-button
to match your environment.
Configure the extension profile
The userDataDir option preserves extension settings between runs.
A practical setup is:
- Run the Puppeteer script.
- Open the extension settings in the launched browser.
- Enter the SolveCaptcha API key.
- Configure the required captcha types.
- Close the browser.
- Run the script again using the same profile directory.
Keep the automated profile separate from your personal Chrome profile.
Do not depend on extension-specific page selectors
An extension version may change:
- injected button classes;
- status attributes;
- internal element names;
- UI structure.
Instead of waiting only for a selector such as:
.captcha-solver[data-state="solved"]
prefer waiting for the actual result expected by the page.
For reCAPTCHA v2, that can be a non-empty:
g-recaptcha-response
For other providers, wait for:
- a returned cookie;
- a completed callback;
- an enabled submit button;
- a page-specific success state;
- an expected network request.
Headless Chrome considerations
Extension behavior in headless Chrome depends on the Chrome and Puppeteer versions and the extension implementation.
For initial setup and debugging:
Use headed Chrome
→ confirm that the extension loads
→ configure the API key
→ confirm that the captcha is detected
→ verify that the solution is applied
Move to another environment only after the headed workflow works correctly.
Common API errors
ERROR_WRONG_USER_KEY
The API key is invalid.
Copy it again from the SolveCaptcha account settings and remove spaces or line breaks.
ERROR_ZERO_BALANCE
The account balance is insufficient.
Add funds before creating another task.
ERROR_CAPTCHA_UNSOLVABLE
The task could not be completed with the submitted parameters.
Check:
- captcha type;
- site key;
- page URL;
- challenge version;
- proxy configuration;
- optional provider-specific parameters;
- whether the page generated a new challenge.
Capture fresh parameters before retrying.
CAPCHA_NOT_READY
The task is still processing.
Wait five seconds and request the result again using the same task ID.
Do not create a duplicate task.
Chrome-side troubleshooting
The token is returned but the page rejects it
Check:
- whether the correct captcha type was selected;
- whether the site key is current;
- whether the page URL is exact;
- whether the token was applied to the correct field;
- whether a callback must be called;
- whether the page was reloaded;
- whether the session cookies changed;
- whether the token expired;
- whether another application check failed.
A valid captcha token does not replace CSRF validation, session cookies, account checks, or normal form validation.
No g-recaptcha-response field exists
The field may be created dynamically after reCAPTCHA initializes.
It may also be absent in a reCAPTCHA v3 integration that passes the token directly to a callback or Fetch request.
Inspect the Network panel to determine how the application submits the token.
The extension does not detect the captcha
Possible causes include:
- the captcha loads after a user action;
- the widget is inside an iframe;
- the page uses a custom integration;
- the captcha type is disabled in extension settings;
- the extension lacks access to the current site;
- another extension interferes with the page;
- the challenge is not supported by the current extension version.
Reload the page after confirming the extension permissions and settings.
The extension solves repeatedly
Disable automatic submission and retries.
Then determine why the form is returning to the captcha page.
The actual error may be:
- empty required field;
- invalid credentials;
- expired session;
- invalid CSRF token;
- another server-side validation failure.
Selenium applies the token but nothing happens
The page may require:
- a configured callback;
- a custom event;
- a specific submit button;
- a framework state update;
- an HTTP request rather than a hidden field.
Compare the automated flow with a successful manual submission.
Puppeteer waits indefinitely
Confirm that:
- the extension loaded;
- the API key is configured;
- the captcha type is enabled;
- the page actually contains reCAPTCHA v2;
- the response field exists;
- the selector matches the current page;
- the browser profile is writable.
Use a screenshot and DevTools during debugging.
Common implementation mistakes
Using createTask and getTaskResult
Incorrect:
createTask
getTaskResult
clientKey
taskId
Correct:
in.php
res.php
key
request
Sending JSON to the wrong API format
For the documented SolveCaptcha in.php workflow, send form parameters.
In Postman, use:
x-www-form-urlencoded
or:
form-data
depending on the captcha type.
Using websiteKey instead of googlekey
Incorrect:
websiteKey=SITE_KEY
Correct for reCAPTCHA:
googlekey=SITE_KEY
Using websiteURL instead of pageurl
Incorrect:
websiteURL=PAGE_URL
Correct:
pageurl=PAGE_URL
Updating only textContent
Set the response field’s value property and dispatch the appropriate events.
Inserting tokens through string interpolation
Pass the token as a JavaScript argument instead of building executable code with an f-string.
Assuming every captcha returns a token
Some captcha methods return:
- recognized text;
- coordinates;
- a cookie;
- several token values;
- structured JSON.
Read the documentation for the selected provider.
Reusing old tokens
Treat returned tokens as short-lived and specific to the current challenge.
Reloading while waiting
Reloading can replace the challenge and invalidate the pending result.
Changing the proxy mid-session
Keep the network path consistent when the provider connects the challenge with the source IP.
Enabling unlimited automatic retries
Set a maximum retry count and log the reason for each failure.
Recommended workflow
For a new Chrome integration:
- Open the page manually.
- Identify the captcha provider.
- Inspect the page parameters in DevTools.
- Test the task through Postman.
- Retrieve one valid result.
- determine how the page uses the result.
- Apply it manually in Chrome.
- Test the SolveCaptcha extension.
- Implement direct API automation if needed.
- Add explicit timeouts and retry limits.
- Preserve the browser session.
- Monitor whether the website accepted the result.
This sequence is easier to debug than starting with full automation.
Which method should you choose?
Choose Postman when:
- you are testing the API for the first time;
- you need to inspect request and response fields;
- you are debugging a site key or page URL;
- you need only one solution;
- you do not want to write code yet.
Choose the Chrome extension when:
- you want the captcha solved inside the browser;
- the workflow is interactive;
- minimal coding is preferred;
- the extension supports the detected provider;
- you need manual or semi-automatic solving.
Choose direct API integration when:
- the workflow must be fully automated;
- you need custom error handling;
- you process several sessions;
- you need proxy control;
- you need provider-specific parameters;
- you need reliable logging and monitoring.
Choose Puppeteer or Selenium when:
- the page requires JavaScript;
- the captcha is connected to browser state;
- the token must be applied to a callback;
- the protected workflow contains several interactive steps;
- the final request cannot be reproduced safely with a basic HTTP client.
Pre-launch checklist
Before deploying the integration, confirm:
- [ ] The website is within the authorized scope.
- [ ] The captcha provider was identified correctly.
- [ ] The current public parameters were extracted.
- [ ] The complete page URL is correct.
- [ ] The correct SolveCaptcha method is used.
- [ ] The API key is stored securely.
- [ ] Task creation uses
in.php. - [ ] Result retrieval uses
res.php. - [ ] The task ID is read from
request. - [ ] Polling uses five-second intervals.
- [ ] The result format matches the captcha provider.
- [ ] The token or answer is applied to the correct location.
- [ ] Required callbacks are called.
- [ ] The browser session remains unchanged.
- [ ] Automatic retries have a fixed limit.
- [ ] The final website response is validated.
Frequently asked questions
Can SolveCaptcha work directly in Chrome?
Yes.
Use the SolveCaptcha browser extension for interactive Chrome workflows or connect the API to Selenium or Puppeteer.
Can I test SolveCaptcha without writing code?
Yes.
Use Postman to submit the task and retrieve the result.
Which endpoint creates a task?
Use:
https://api.solvecaptcha.com/in.php
Which endpoint retrieves the result?
Use:
https://api.solvecaptcha.com/res.php
Which method is used for reCAPTCHA v2?
Use:
method=userrecaptcha
Where can I find the reCAPTCHA site key?
Look for:
data-sitekey
or the k parameter in the reCAPTCHA iframe URL.
Which API parameter receives the site key?
Use:
googlekey
Where is the task ID returned?
With json=1, the task ID is returned in:
request
Where is the completed token returned?
The completed token is also returned in:
request
During task creation, request contains the task ID. During result retrieval, it contains the final solution.
How often should I poll?
For reCAPTCHA, wait approximately 15–20 seconds before the first result request.
Then retry every five seconds while the API returns:
CAPCHA_NOT_READY
Where should I insert a reCAPTCHA token?
The standard field is:
g-recaptcha-response
Some pages also require a callback or submit the token through a custom request field.
Does every captcha use g-recaptcha-response?
No.
That field is specific to reCAPTCHA integrations.
Is a proxy required?
Not for every captcha type.
Some providers or workflows require a proxy, while others make it optional.
Can one token be reused?
No.
Treat captcha tokens as short-lived and single-use.
Does the extension work on every website?
No browser extension can guarantee compatibility with every custom implementation.
Use direct API integration when the page requires custom parameters or result handling.
Should I make the hidden token field visible?
No.
Update its value directly. Changing its CSS is unnecessary.
Can I use the extension with Puppeteer?
Yes.
Launch Chrome with the unpacked extension and a dedicated browser profile.
Conclusion
There are three practical ways to bypass captcha in Google Chrome with SolveCaptcha:
- Use Postman to test API requests manually.
- Use the SolveCaptcha browser extension for interactive solving.
- Connect directly to the API for complete automation.
The correct production workflow is:
Identify the captcha
→ extract current parameters
→ send them to in.php
→ save the task ID
→ poll res.php
→ retrieve the result
→ apply it through the expected field, callback, cookie, or request
→ validate the website response
Start with Postman when learning the API.
Use the extension when you want a low-code Chrome workflow.
Use Selenium, Puppeteer, or direct HTTP integration when you need precise control, repeatable execution, and provider-specific error handling.
Use the SolveCaptcha API documentation to verify the current parameters for each captcha type before deploying the integration.