Captcha types
reCAPTCHA v2#
Types RecaptchaV2TaskProxyless and RecaptchaV2Task.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the captcha is located |
websiteKey |
yes | string | Value of the data-sitekey attribute of the reCAPTCHA widget |
isInvisible |
no | bool | true for invisible reCAPTCHA. Default is false |
recaptchaDataSValue |
no | string | Value of the data-s parameter, which may be required on Google services |
userAgent |
no | string | User-Agent of the browser used to load the captcha |
cookies |
no | string | Cookies in the format name1=value1; name2=value2, if the session is important for solving |
apiDomain |
no | string | Domain used to load reCAPTCHA: google.com or recaptcha.net. Default is google.com |
Only for RecaptchaV2Task (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// RecaptchaV2TaskProxyless
{
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"isInvisible": false
}
// RecaptchaV2Task (your proxy)
{
"type": "RecaptchaV2Task",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "password",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "03AGdBq..."
}
}
You need to pass the solution.gRecaptchaResponse value to the reCAPTCHA widget or the g-recaptcha-response form parameter.
reCAPTCHA v2 Enterprise#
Types RecaptchaV2EnterpriseTaskProxyless and RecaptchaV2EnterpriseTask.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the captcha is placed |
websiteKey |
yes | string | Value of the data-sitekey attribute of the reCAPTCHA Enterprise widget |
enterprisePayload |
no | object | Additional parameters of the grecaptcha.enterprise.render call, if the site passes them, for example the s value |
isInvisible |
no | bool | true for invisible reCAPTCHA. Default is false |
apiDomain |
no | string | Domain from which reCAPTCHA is loaded: google.com or recaptcha.net. Default is google.com |
userAgent |
no | string | User-Agent of the browser used to load the captcha |
cookies |
no | string | Cookies in the format name1=value1; name2=value2, if the session is important for solving |
Only for RecaptchaV2EnterpriseTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Examples of the task object
// RecaptchaV2EnterpriseTaskProxyless
{
"type": "RecaptchaV2EnterpriseTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"isInvisible": false
}
// RecaptchaV2EnterpriseTask (your proxy)
{
"type": "RecaptchaV2EnterpriseTask",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"isInvisible": false,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
"cookies": "foo=bar; baz=1",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "password"
}
Example of getTaskResult response
While the task is being processed:
{
"errorId": 0,
"status": "processing"
}
After successful solving:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "03AGdBq2kX9Lm...QpZr8vN3sT"
}
}
The solution.gRecaptchaResponse value is passed in the same way as a regular reCAPTCHA v2 token, to the widget or to the g-recaptcha-response parameter of the form.
The Enterprise method uses the reCAPTCHA Enterprise API. If the site passes additional parameters through enterprisePayload, include them in the request.
reCAPTCHA v3#
Type RecaptchaV3TaskProxyless. A proxy is not required for v3. Tasks are solved from the service IP addresses.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page with the captcha |
websiteKey |
yes | string | Site key of the reCAPTCHA v3 widget |
minScore |
yes | float | Required score. Supported values are 0.3, 0.7, and 0.9 |
pageAction |
no | string | Value of the action parameter that the site sets when calling grecaptcha.execute() |
isEnterprise |
no | bool | true if the site uses reCAPTCHA v3 Enterprise |
apiDomain |
no | string | Domain from which the reCAPTCHA script is loaded: google.com or recaptcha.net. Default is google.com |
Task object example
// RecaptchaV3TaskProxyless
{
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"minScore": 0.3,
"pageAction": "login",
"isEnterprise": false
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "03AGdBq..."
}
}
You use the received token (solution.gRecaptchaResponse) just like a regular reCAPTCHA v3 token.
Finding the reCAPTCHA sitekey and callback function on the page#
If there are multiple reCAPTCHA widgets on the page or the callback is not directly visible in the markup, you can find the sitekey and callback function via the ___grecaptcha_cfg object, where Google stores the configuration of rendered widgets. Run the following code in the developer console or embed it in your automation script. It will return an array with the found reCAPTCHA clients along with their sitekey, pageurl, and callback reference.
function findRecaptchaClients() {
// eslint-disable-next-line camelcase
if (typeof (___grecaptcha_cfg) !== 'undefined') {
// eslint-disable-next-line camelcase, no-undef
return Object.entries(___grecaptcha_cfg.clients).map(([cid, client]) => {
const data = { id: cid, version: cid >= 10000 ? 'V3' : 'V2' };
const objects = Object.entries(client).filter(([_, value]) => value && typeof value === 'object');
objects.forEach(([toplevelKey, toplevel]) => {
const found = Object.entries(toplevel).find(([_, value]) => (
value && typeof value === 'object' && 'sitekey' in value && 'size' in value
));
if (typeof toplevel === 'object' && toplevel instanceof HTMLElement && toplevel['tagName'] === 'DIV') {
data.pageurl = toplevel.baseURI;
}
if (found) {
const [sublevelKey, sublevel] = found;
data.sitekey = sublevel.sitekey;
const callbackKey = data.version === 'V2' ? 'callback' : 'promise-callback';
const callback = sublevel[callbackKey];
if (!callback) {
data.callback = null;
data.function = null;
} else {
data.function = callback;
const keys = [cid, toplevelKey, sublevelKey, callbackKey]
.map((key) => `['${key}']`)
.join('');
data.callback = `___grecaptcha_cfg.clients${keys}`;
}
}
});
return data;
});
}
return [];
}
Usage:
let res = findRecaptchaClients()
console.log(res)
For each found client, data.version indicates whether it is v2 or v3. data.sitekey is the value for the websiteKey field in the createTask request. data.callback is the path to the callback function that needs to be executed with the token after receiving the solution.
Cloudflare Turnstile#
Types TurnstileTaskProxyless and TurnstileTask.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the Turnstile widget is located |
websiteKey |
yes | string | Value of the data-sitekey attribute of the Turnstile widget |
action |
no* | string | Value of the action parameter from the turnstile.render call. Required for Cloudflare Challenge pages |
data |
no* | string | Value of the cData parameter from the turnstile.render call. Required for Cloudflare Challenge pages |
pagedata |
no* | string | Value of the chlPageData parameter from the turnstile.render call. Required for Cloudflare Challenge pages |
Only for TurnstileTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// TurnstileTaskProxyless
{
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx"
}
// TurnstileTask (your proxy)
{
"type": "TurnstileTask",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "0.zxcv..."
}
}
You need to pass the received token (solution.token) to the widget callback function or the cf-turnstile-response field, depending on how you integrate Turnstile on your site.
Complex case: Cloudflare Challenge page#
A separate and more complex situation is the Cloudflare Challenge page. Besides websiteKey, additional parameters cData, chlPageData, and action are passed to the widget. In this case, you need to intercept the turnstile.render call to extract these values. You also need to intercept the callback function definition.
To intercept the parameters, embed the following JavaScript on the page before the Cloudflare Turnstile widget itself loads:
const i = setInterval(() => {
if (window.turnstile) {
clearInterval(i)
window.turnstile.render = (a, b) => {
let p = {
type: "TurnstileTaskProxyless",
websiteKey: b.sitekey,
websiteURL: window.location.href,
data: b.cData,
pagedata: b.chlPageData,
action: b.action
}
console.log(JSON.stringify(p))
window.tsCallback = b.callback
return 'foo'
}
}
}, 10)
The script replaces turnstile.render with a custom function. It intercepts the configuration object b, in which Cloudflare passes sitekey, cData, chlPageData, action, and callback. It logs the task object for createTask and saves a reference to the original callback function in window.tsCallback to call it later with the token.
An alternative approach is to intercept the network request to the api.js script and replace it with your own script. This script returns the required parameters and makes the callback function globally accessible.
When the solution is received from getTaskResult, execute the saved callback function by passing the token as an argument:
window.tsCallback('TOKEN_FROM_SOLUTION');
Yandex SmartCaptcha#
There are two methods for solving Yandex SmartCaptcha: token-based and image-based.
YandexSmartCaptchaTaskProxyless— token-based solving using our proxiesYandexSmartCaptchaTask— token-based solving using your proxiesCoordinatesTask— image-based solving, returns click coordinates
Token-based solving#
Types YandexSmartCaptchaTaskProxyless and YandexSmartCaptchaTask.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the captcha is loaded |
websiteKey |
yes | string | The sitekey value from the page code or captcha iframe |
userAgent |
no | string | User-Agent under which the captcha is solved |
cookies |
no | string | Cookies in the format name1=value1;name2=value2 |
Only for YandexSmartCaptchaTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, https, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// YandexSmartCaptchaTaskProxyless
{
"type": "YandexSmartCaptchaTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "Y5Lh0ti..."
}
// YandexSmartCaptchaTask (your proxy)
{
"type": "YandexSmartCaptchaTask",
"websiteURL": "https://example.com/login",
"websiteKey": "Y5Lh0ti...",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "dV9xNjYyNTU3NjkxO4k9OTQuNVMuMjkuMjM9..."
}
}
solution.token should be used in the smart-token field or passed to your site's backend, the same way as a manually solved captcha.
Image-based Yandex SmartCaptcha#
The image-based variant is solved with CoordinatesTask and returns click coordinates.
| Parameter | Required | Type | Description |
|---|---|---|---|
body |
yes | string | The captcha image, Base64-encoded. Data-URI format is also supported |
imgType |
yes | string | Captcha mode: smart_captcha |
imgInstructions |
no* | string | Instruction image, Base64-encoded. Required for imgType=smart_captcha |
comment |
no* | string | Text hint for the worker. Recommended for imgType=smart_captcha, for example select objects in the order of the instruction |
Task object example
{
"type": "CoordinatesTask",
"body": "BASE64_IMAGE",
"imgType": "smart_captcha",
"imgInstructions": "BASE64_INSTRUCTION_IMAGE",
"comment": "select objects in the order of the instruction"
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"coordinates": [
{ "x": 57, "y": 82 },
{ "x": 239, "y": 75 },
{ "x": 138, "y": 113 }
]
}
}
For smart_captcha, provide imgInstructions with the visual instruction and use comment to clarify the required action when needed.
Other optional CoordinatesTask fields, such as minClicks and maxClicks, are described in the Coordinates section below.
Image to Text#
Type ImageToTextTask. No proxy is required. The captcha image itself is submitted directly.
| Parameter | Required | Type | Description |
|---|---|---|---|
body |
yes | string | The captcha image, Base64-encoded. Data-URI format is also supported |
phrase |
no | bool | true if the answer should contain at least two words separated by a space. Default is false |
case |
no | bool | true if the result is case-sensitive. Default is false |
numeric |
no | int | Character set hint: 0 — no preference, 1 — numbers only, 2 — letters only, 3 — numbers or letters only, 4 — must contain both numbers and letters |
math |
no | bool | true if the captcha requires a calculation. Default is false |
minLength |
no | int | Minimum answer length. 0 means no minimum |
maxLength |
no | int | Maximum answer length. 0 means no maximum |
comment |
no | string | A hint for the worker solving the image |
imgInstructions |
no | string | An optional instruction image, Base64-encoded, shown to the worker alongside the captcha image |
Task object example
{
"type": "ImageToTextTask",
"body": "iVBORw0KGgoAAAANSUhEUgAA...",
"numeric": 1,
"minLength": 4,
"maxLength": 6
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"text": "aB3fX9"
}
}
solution.text is the recognized text. Submit it to the target form field the same way you would a manually entered answer.
Coordinates#
Type CoordinatesTask. No proxy is required. The captcha image itself is submitted directly. The worker identifies specific points on the image and the API returns their coordinates.
| Parameter | Required | Type | Description |
|---|---|---|---|
body |
yes | string | The captcha image, Base64-encoded. Data-URI format is also supported |
comment |
no | string | A hint for the worker solving the image, e.g. click on the green apple |
imgInstructions |
no | string | An optional instruction image, Base64-encoded, shown to the worker alongside the captcha image |
minClicks |
no | int | Minimum number of clicks to perform on the image. Default is 1 |
maxClicks |
no | int | Maximum number of clicks that can be performed on the image |
Task object example
{
"type": "CoordinatesTask",
"body": "iVBORw0KGgoAAAANSUhEUgAA...",
"comment": "click on the green apple"
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"coordinates": [
{
"x": 358,
"y": 268
}
]
}
}
solution.coordinates is an array of {x, y} pixel positions. Click on each position in the returned order, or use the coordinates according to your integration.
CoordinatesTask is also used for the image-based variant of Yandex SmartCaptcha. See Image-based Yandex SmartCaptcha above.
GeeTest v3#
Types GeeTestTaskProxyless and GeeTestTask. The same task types are used for GeeTest v4. The version is selected with the version field. The default version is 3.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the GeeTest widget is located |
version |
no | int | GeeTest version: 3 or 4. Default is 3 |
gt |
yes | string | Public gt value of the GeeTest widget |
challenge |
yes | string | Session-specific challenge value found on the page. Get a new value for each task |
geetestApiServerSubdomain |
no | string | Custom GeeTest API server subdomain, if the page uses one |
initParameters |
no | object | Additional parameters passed to the GeeTest initialization call |
userAgent |
no | string | User-Agent of the browser used to load the captcha |
risk_type |
no | string | Dynamic risk_type value included in the captcha loading request |
Only for GeeTestTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// GeeTestTaskProxyless
{
"type": "GeeTestTaskProxyless",
"websiteURL": "https://example.com/login",
"gt": "f2ae6cadcf7886856696c46d84d109d1",
"challenge": "12345678abc90123d45678e90123f45g6"
}
// GeeTestTask (your proxy)
{
"type": "GeeTestTask",
"websiteURL": "https://example.com/login",
"gt": "f2ae6cadcf7886856696c46d84d109d1",
"challenge": "12345678abc90123d45678e90123f45g6",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"challenge": "12345678abc90123d45678e90123f45g6",
"validate": "0a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p",
"seccode": "0a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p|jordan"
}
}
Pass solution.validate and solution.seccode into the page's GeeTest callback according to the integration used by the target site.
GeeTest v4#
Same types as GeeTest v3, GeeTestTaskProxyless and GeeTestTask. Set version to 4 to use GeeTest v4.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the GeeTest v4 widget is located |
version |
yes | int | Must be 4 |
initParameters |
yes | object | Must contain captcha_id, the widget's static captcha identifier |
userAgent |
no | string | User-Agent of the browser used to load the captcha |
risk_type |
no | string | Dynamic risk_type value included in the captcha loading request |
Only for GeeTestTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// GeeTestTaskProxyless (v4)
{
"type": "GeeTestTaskProxyless",
"websiteURL": "https://example.com/login",
"version": 4,
"initParameters": {
"captcha_id": "e392e65f912c780f2c3ebac7702651de"
}
}
// GeeTestTask (v4, your proxy)
{
"type": "GeeTestTask",
"websiteURL": "https://example.com/login",
"version": 4,
"initParameters": {
"captcha_id": "e392e65f912c780f2c3ebac7702651de"
},
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"captcha_id": "e392e65f912c780f2c3ebac7702651de",
"lot_number": "...",
"pass_token": "...",
"gen_time": "...",
"captcha_output": "..."
}
}
solution.lot_number, pass_token, gen_time, and captcha_output together form the GeeTest v4 result object. Pass them into the page's GeeTest callback as-is.
Tencent#
Types TencentTaskProxyless and TencentTask.
| Parameter | Required | Type | Description |
|---|---|---|---|
websiteURL |
yes | string | Full URL of the page where the captcha is loaded |
appId |
yes | string | The value of the appId parameter found in the page source code |
captchaScript |
no | string | Captcha script URL from the page source code. Default: https://turing.captcha.qcloud.com/TCaptcha.js |
Only for TencentTask (solving via your proxy), additionally:
| Parameter | Required | Type | Description |
|---|---|---|---|
proxyType |
yes | string | http, socks4, or socks5 |
proxyAddress |
yes | string | Proxy IP address or hostname |
proxyPort |
yes | int | Proxy port |
proxyLogin |
no | string | Login for proxy authorization |
proxyPassword |
no | string | Password for proxy authorization |
Task object examples
// TencentTaskProxyless
{
"type": "TencentTaskProxyless",
"websiteURL": "https://example.com/login",
"appId": "190014885"
}
// TencentTask (your proxy)
{
"type": "TencentTask",
"websiteURL": "https://example.com/login",
"appId": "190014885",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
getTaskResult response example
While the task is processing:
{
"errorId": 0,
"status": "processing"
}
Once solved:
{
"errorId": 0,
"status": "ready",
"solution": {
"appid": "190014885",
"ret": 0,
"ticket": "tr0344YjJASGmJGtohyWS_y6tJKiqVPIdFgl87vWlVaQoueR8D6DH28go-i-VjeassM31SXO7D0*",
"randstr": "@KVN"
}
}
solution.appid, ret, ticket, and randstr together form the Tencent result object. Pass them into the page's captcha callback as-is.