Skip to main content
Are you experiencing issues obtaining the token?
Contact support

GeeTest

GeeTestCaptcha Example
GeeTestCaptcha Example

Your application should send the site address, public domain key (gt) and key (challenge).

The result of solving the task is three or five tokens for form submission.

Attention!

CapMonster Cloud uses built-in proxies by default — their cost is already included in the service. You only need to specify your own proxies in cases where the website does not accept the token or access to the built-in services is restricted.

Proxies with IP authorization are not yet supported.

info

For GeeTest V3:

  • The gt, challenge, and geetestApiServerSubdomain parameters can be passed in the JavaScript code used to initialize GeeTest, for example in the initGeetest function.

  • Some parameters may also be present in the page HTML or network requests. For GeeTest V3, the challenge value must be obtained before the CAPTCHA is initialized.

For GeeTest V4, the gt parameter contains the captcha_id value.


GeeTest V3

Task examples

Below are examples of GeeTest V3 task types currently supported by CapMonster Cloud:

Intelligent mode
Slide CAPTCHA
Icon CAPTCHA
Space CAPTCHA

Request parameters


IMPORTANT: the challenge parameter in GeeTest V3 is dynamic.
Obtain a new value immediately before creating each task and before the CAPTCHA is initialized on the page. Once the CAPTCHA is loaded, the previously obtained challenge becomes invalid.


type<string>required

GeeTestTask


websiteURL<string>required

The URL of the page where the CAPTCHA is initialized. The correct URL is usually passed in the Referer header when requesting https://api-na.geetest.com/gettype.php. For example, you may be on https://example.com#login, while the CAPTCHA is actually initialized on https://example.com.


gt<string>required

The GeeTest gt identifier key for the domain. This is a static value and is rarely changed.


challenge<string>required only for V3

Dynamic key. A new challenge value must be obtained before creating each task.

Important: obtain challenge before the CAPTCHA is initialized on the page.

If the CAPTCHA has already been loaded, the obtained value becomes invalid. Sending such a value to the CapMonster Cloud API will return the error ERROR_INVALID_TASK with a message indicating that the parameter is invalid.


version<integer>required

3


geetestApiServerSubdomain<string>optional

GeeTest API server subdomain (must be different from api.geetest.com).
Optional parameter. May be required for some websites.


geetestGetLib<string>optional

Path to the CAPTCHA script used to display it on the page.
Optional parameter. May be required for some websites.
Send JSON as a string.


userAgent<string>optional

Browser User-Agent. Use the current value supported by CapMonster Cloud: userAgentPlaceholder

You can get the latest value at: https://capmonster.cloud/api/useragent/actual.


proxyType<string>optional

http - regular http/https proxy;
https - try this option only if "http" doesn't work (required for some custom proxies);
socks4 - socks4 proxy;
socks5 - socks5 proxy.


proxyAddress<string>optional

IPv4/IPv6 proxy IP address. Not allowed:

  • using transparent proxies (where you can see the client's IP);
  • using proxies on local machines.


proxyPort<integer>optional

Proxy port.


proxyLogin<string>optional

Proxy-server login.


proxyPassword<string>optional

Proxy-server password.

Create task method

POST
https://api.capmonster.cloud/createTask

Request example

{
"clientKey": "API_KEY",
"task": {
"type": "GeeTestTask",
"websiteURL": "https://yourwebsite.com/page-with-geetest",
"gt": "gt-value",
"challenge": "challenge-value",
"version": 3,
"geetestApiServerSubdomain": "example.api.geetest.com"

}
}

Response example

{
"errorId":0,
"taskId":407533072
}

Use the getTaskResult method to get the result of GeeTest recognition. Depending on the system load, you will receive a response after a time in the range from 10 s to 30 s.

Get task result method

POST
https://api.capmonster.cloud/getTaskResult

Request example

{
"clientKey":"API_KEY",
"taskId": 407533072
}

Response example

{
"errorId": 0,
"status": "ready",
"solution": {
"challenge": "0f759dd1ea6c4wc76cedc2991039ca4f23",
"validate": "6275e26419211d1f526e674d97110e15",
"seccode": "510cd9735583edcb158601067195a5eb|jordan"
}
}

PropertyTypeDescription
challengeStringAll three parameters are required when submitting the form on the target site.
validateString
seccodeString

How to find all parameters required to create a task

Manually

  1. Open the website where GeeTest V3 is displayed in a browser.
  2. Open Developer Tools (DevTools) and go to the Network tab.
  3. Reload the page to capture network requests from the moment it starts loading.
  4. Find a request to the target website server whose response contains GeeTest parameters, including gt and challenge.

The challenge value must be obtained before the CAPTCHA is initialized, that is, before a GeeTest request such as the following is sent:

https://api.geetest.com/gettype.php?gt=...

Before initializing the CAPTCHA, the website may obtain GeeTest parameters from its own server. To find the current challenge value, check requests to the target website domain and their responses.

In some cases, the website encrypts data received from its server, so the challenge value may not be available in plain form in the response. In this case, you can obtain it from GeeTest request parameters, for example:

https://api.geetest.com/get.php?gt=...

and/or:

https://api.geevisit.com/ajax.php?gt=...

Important:

With this method, obtain the parameters from the request and block requests to the GeeTest API before they are sent. If the request is sent and the CAPTCHA loads, the challenge value used in that request becomes invalid.

After obtaining the current gt and challenge values, use them to create a GeeTest V3 task in CapMonster Cloud.


Automatically

GeeTest V3 parameter retrieval can be automated in two ways. Choose the appropriate option depending on how the target website is implemented.

Getting parameters from the website server response

If the website server returns gt and challenge in plain form, repeat the corresponding request before creating a task.

For example:

https://example.com/api/v1/captcha/gee-test/init-params
Show code (in browser)
async function getGeeTestV3Params() {
// Replace the URL with the request used by your website,
// whose response returns gt and challenge.
// If the request contains dynamic parameters,
// generate them before sending the request.
const timestamp = Date.now();

const response = await fetch(
`https://example.com/api/v1/captcha/gee-test/init-params?t=${timestamp}`
);

if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();

const gt = data.gt;
const challenge = data.challenge;

if (!gt || !challenge) {
throw new Error("Failed to get gt or challenge");
}

console.log({ gt, challenge });

return { gt, challenge };
}

getGeeTestV3Params().catch(console.error);
Show code (Node.js)
async function getGeeTestV3Params() {
// Replace the URL with the request used by your website,
// whose response returns gt and challenge.
// If the request contains dynamic parameters,
// generate them before sending the request.
const timestamp = Date.now();

const response = await fetch(
`https://example.com/api/v1/captcha/gee-test/init-params?t=${timestamp}`
);

if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();

const gt = data.gt;
const challenge = data.challenge;

if (!gt || !challenge) {
throw new Error("Missing gt or challenge");
}

console.log({ gt, challenge });

return { gt, challenge };
}

getGeeTestV3Params().catch(console.error);

Getting parameters from a GeeTest request

If the challenge value cannot be obtained from the website server response, use the corresponding GeeTest request:

https://api.geetest.com/get.php?gt=...&challenge=...

or:

https://api.geevisit.com/ajax.php?gt=...&challenge=...

Extract gt and challenge from the query parameters and block the request before it is sent.

Show code (Playwright)
import { chromium } from "playwright";

async function getGeeTestV3Params(pageUrl) {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();

let params = null;

await context.route("**/*", async (route) => {
const requestUrl = route.request().url();

if (
requestUrl.includes("api.geetest.com/get.php") ||
requestUrl.includes("api.geevisit.com/ajax.php")
) {
const url = new URL(requestUrl);

const gt = url.searchParams.get("gt");
const challenge = url.searchParams.get("challenge");

if (gt && challenge && !params) {
params = { gt, challenge };
console.log(params);
}

await route.abort();
return;
}

await route.continue();
});

const page = await context.newPage();
await page.goto(pageUrl);

await page.waitForTimeout(5000);
await browser.close();

if (!params) {
throw new Error("Failed to get gt and challenge");
}

return params;
}

getGeeTestV3Params(
"https://example.com/page-with-geetest"
).catch(console.error);

Use the SDK library

Show code (for browser)
// https://github.com/CapMonsterCloud/capmonster-nodejs-captcha-solver

import {
CapMonsterCloudClientFactory,
ClientOptions,
GeeTestRequest
} from "@zennolab_com/capmonstercloud-client";

document.addEventListener("DOMContentLoaded", async () => {

const API_KEY = "YOUR_API_KEY"; // Specify your CapMonster Cloud API key

const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);

// Basic example without proxy
// CapMonster Cloud automatically uses its own proxies
let geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
challenge: "your-challenge-value",
version: 3,
});

// Example using your proxy
// Uncomment this block if you want to use your own proxy
/*
const proxy = {
proxyType: "https",
proxyAddress: "123.45.67.89",
proxyPort: 8080,
proxyLogin: "username",
proxyPassword: "password",
};

geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
challenge: "your-challenge-value",
version: 3,
proxy,
userAgent: "userAgentPlaceholder",
});
*/

// You can check your balance if necessary
const balance = await client.getBalance();
console.log("Balance:", balance);

const result = await client.Solve(geetestRequest);
console.log("Solution:", result.solution);
});
Show code (Node.js)
// https://github.com/CapMonsterCloud/capmonster-nodejs-captcha-solver

const {
CapMonsterCloudClientFactory,
ClientOptions,
GeeTestRequest,
} = require("@zennolab_com/capmonstercloud-client");

const API_KEY = "YOUR_API_KEY"; // Specify your CapMonster Cloud API key

async function solveGeeTest() {
const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY }),
);

// Basic example without proxy
// CapMonster Cloud automatically uses its own proxies
let geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
challenge: "your-challenge-value",
version: 3,
});

// Example using your proxy
// Uncomment this block if you want to use your own proxy
/*
const proxy = {
proxyType: "https",
proxyAddress: "123.45.67.89",
proxyPort: 8080,
proxyLogin: "username",
proxyPassword: "password",
};

geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
challenge: "your-challenge-value",
version: 3,
proxy,
userAgent: "userAgentPlaceholder",
});
*/

// You can check your balance if necessary
const balance = await client.getBalance();
console.log("Balance:", balance);

const result = await client.Solve(geetestRequest);
console.log("Solution:", result.solution);
}

solveGeeTest().catch(console.error);

GeeTest V4

Possible captcha variant

Request parameters

type<string>required

GeeTestTask


websiteURL<string>required

Address of the page on which the captcha is solved.


gt<string>required

The GeeTest identifier key for the domain - the captcha_id parameter.


version<integer>required

4


geetestApiServerSubdomain<string>optional

Geetest API subdomain server (must be different from api.geetest.com).
Optional parameter. May be required for some sites.


geetestGetLib<string>optional

Path to the captcha script to display it on the page.
Optional parameter. May be required for some sites.
Send JSON as a string.


initParameters<object>optional

Additional parameters for version 4, used together with “riskType” (captcha type/characteristics of its verification).


userAgent<string>optional

Browser User-Agent. Pass only a valid UA from Windows OS. Currently it is: userAgentPlaceholder


proxyType<string>optional

http - regular http/https proxy;
https - try this option only if "http" doesn't work (required for some custom proxies);
socks4 - socks4 proxy;
socks5 - socks5 proxy.


proxyAddress<string>optional

IPv4/IPv6 proxy IP address. Not allowed:

  • using transparent proxies (where you can see the client's IP);
  • using proxies on local machines.


proxyPort<integer>optional

Proxy port.


proxyLogin<string>optional

Proxy-server login.


proxyPassword<string>optional

Proxy-server password.

Create task method

POST
https://api.capmonster.cloud/createTask

Request

{
"clientKey": "API_KEY",
"task": {
"type": "GeeTestTask",
"websiteURL": "https://yourwebsite.com/page-with-geetest",
"gt": "captcha-id-value",
"version": 4,
"initParameters": {
"riskType": "risk-type-value"
}
}
}

Response example

{
"errorId":0,
"taskId":407533072
}

Use the getTaskResult to get the result of GeeTest recognition. Depending on the system load, you will receive a response after a time in the range from 10 s to 30 s.

Get task result method

POST
https://api.capmonster.cloud/getTaskResult

Request example

{
"clientKey":"API_KEY",
"taskId": 407533072
}

Response example

{
"errorId": 0,
"status": "ready",
"solution": {
"captcha_id": "f5c2ad5a8a3cf37192d8b9c039950f79",
"lot_number": "bcb2c6ce2f8e4e9da74f2c1fa63bd713",
"pass_token": "edc7a17716535a5ae624ef4707cb6e7e478dc557608b068d202682c8297695cf",
"gen_time": "1683794919",
"captcha_output": "XwmTZEJCJEnRIJBlvtEAZ662T...[cut]...SQ3fX-MyoYOVDMDXWSRQig56"
}
}

PropertyTypeDescription
captcha_idString

All five parameters are required when submitting the form on the target site.


input[name=captcha_id]


input[name=lot_number]


input[name=pass_token]


input[name=gen_time]


input[name=captcha_output]

lot_numberString
pass_tokenString
gen_timeString
captcha_outputString

How to find all required parameters for task creation

Manually

  1. Open the website where the CAPTCHA is displayed in your browser.
  2. Open Developer Tools (DevTools) and go to the Network tab.
  3. Refresh the page (F5) to capture all network requests.
  4. In the search field (Filter), type load or captcha to quickly find the required request.
  5. Find a request like load?callback=... — it usually contains CAPTCHA parameters.
  6. Click on this request and open the Payload tab to view the required data.

paramsv4

Automatically

A convenient way to automate the search for all necessary parameters. Some parameters are regenerated every time the page loads, so you'll need to extract them through a browser — either regular or headless (e.g., using Playwright). Since the values of dynamic parameters are short-lived, the captcha must be solved immediately after retrieving them.

Important!

The code snippets provided are basic examples for familiarization with extracting the required parameters. The exact implementation will depend on your captcha page, its structure, and the HTML elements/selectors it uses.

Show code (in browser)
(function() {
function getQueryParams(url) {
const params = new URLSearchParams(new URL(url).search);
const captchaId = params.get('captcha_id');
const riskType = params.get('risk_type');
return { captchaId, riskType };
}

const observer = new PerformanceObserver((list) => {
const entries = list.getEntriesByType('resource');
entries.forEach((entry) => {
if (entry.name.includes('https://gcaptcha4.geetest.com/load?')) {
const { captchaId, riskType } = getQueryParams(entry.name);
if (captchaId) {
console.log('GeeTest v4 detected (via PerformanceObserver):');
console.log({ captchaId, riskType });
}
}
});
});

observer.observe({ type: 'resource', buffered: true });
})();
Show code (Node.js)
import { chromium } from "playwright";

async function detectGeeTestV4(pageUrl) {
const result = { version: null, data: {} };

const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();

page.on("response", async (response) => {
const url = response.url();

if (url.includes("https://gcaptcha4.geetest.com/load?")) {
const urlParams = new URLSearchParams(url.split("?")[1]);
const captchaId = urlParams.get("captcha_id");
const riskType = urlParams.get("risk_type");

if (captchaId && !result.version) {
result.version = "v4";
result.data = {
captchaId: captchaId,
riskType: riskType,
};

console.log("GeeTest v4 detected:");
console.log(result.data);
}
}
});

await page.goto(pageUrl, { waitUntil: "networkidle" });
await page.waitForTimeout(20000);

if (!result.version) {
console.log("error");
}

await browser.close();
return result;
}

detectGeeTestV4("https://example.com").then((result) => {
console.log(result);
});

Use the SDK library

Show code (for browser)
// https://github.com/CapMonsterCloud/capmonster-nodejs-captcha-solver

import {
CapMonsterCloudClientFactory,
ClientOptions,
GeeTestRequest
} from "@zennolab_com/capmonstercloud-client";

document.addEventListener("DOMContentLoaded", async () => {

const API_KEY = "YOUR_API_KEY"; // Specify your CapMonster Cloud API key

const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);

// Basic example without proxy
// CapMonster Cloud automatically uses its own proxies
let geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
version: "4",
initParameters: {
riskType: "your-risk-type",
},
});

// Example using your proxy
// Uncomment this block if you want to use your own proxy
/*
const proxy = {
proxyType: "https",
proxyAddress: "123.45.67.89",
proxyPort: 8080,
proxyLogin: "username",
proxyPassword: "password",
};

geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
version: "4",
initParameters: {
riskType: "your-risk-type",
},
proxy,
});
*/

// You can check your balance if necessary
const balance = await client.getBalance();
console.log("Balance:", balance);

const result = await client.Solve(geetestRequest);
console.log("Solution:", result.solution);
});
Show code (Node.js)
// https://github.com/CapMonsterCloud/capmonster-nodejs-captcha-solver

const {
CapMonsterCloudClientFactory,
ClientOptions,
GeeTestRequest,
} = require("@zennolab_com/capmonstercloud-client");

const API_KEY = "YOUR_API_KEY"; // Specify your CapMonster Cloud API key

async function solveGeeTest() {
const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY }),
);

// Basic example without proxy
// CapMonster Cloud automatically uses its own proxies
let geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
version: "4",
initParameters: {
riskType: "your-risk-type",
},
});

// Example using your proxy
// Uncomment this block if you want to use your own proxy
/*
const proxy = {
proxyType: "https",
proxyAddress: "123.45.67.89",
proxyPort: 8080,
proxyLogin: "username",
proxyPassword: "password",
};

geetestRequest = new GeeTestRequest({
websiteURL: "https://yourwebsite.com/page-with-geetest",
gt: "your-gt-value",
version: "4",
initParameters: {
riskType: "your-risk-type",
},
proxy,
});
*/

// You can check your balance if necessary
const balance = await client.getBalance();
console.log("Balance:", balance);

const result = await client.Solve(geetestRequest);
console.log("Solution:", result.solution);
}

solveGeeTest().catch(console.error);

Features of the GeeTest solution on app.gal**.com

Attention!

This section is relevant **only for the GeeTest captcha on the app.gal**.com site**. These values should not be used for other sites.

When to use the challenge field?

For the app.gal**.com site, you need to specify the value of the challenge field depending on the action being performed. If this field is not specified, the default value **AddTypedCredentialItems** is used, but this does not suit all scenarios.

List of possible challenge values:

Action on app.gal**.com sitechallenge Value
Sending an email codeSendEmailCode
Confirming an action (e.g., login)SendVerifyCode
Claiming a rewardClaimUserTask
Opening a mystery boxOpenMysteryBox
Purchasing in GGShopBuyGGShop
Preparing to buy raffle ticketsPrepareBuyGGRaffleTickets
Adding credentialsAddTypedCredentialItems
Creating a report ticketCreateReportTicket
Participating in an activityPrepareParticipate
Updating credential dataRefreshCredentialValue
Synchronizing dataSyncCredentialValue
Social loginGetSocialAuthUrl

The challenge value must match the operationName visible in the network requests (Network tab) via DevTools.

Task submission example
{
"type": "GeeTestTask",
"websiteURL": "https://app.gal**.com/accountSetting/social",
"gt": "244bcb8b9846215df5af4c624a750db4",
"challenge": "SendVerifyCode",
"version": 3
}

Note: The GT key for gal**.com is always 244bcb8b9846215df5af4c624a750db4. You can leave this value as the default.

Example response
{
"errorId": 0,
"errorCode": null,
"errorDescription": null,
"solution": {
"lot_number": "e0c84aab60867ad1316f8606d31ab58d2a54d8a4ca8e78b9339abd8ea62967cb",
"captcha_output": "7DlZW2dul...cbEA5uIbwg==",
"pass_token": "ce024389a0926e0d1081792c83e0c46f882084e45e95afa0e148fd03aed3ae10",
"gen_time": "1753158042",
"encryptedData": ""
},
"status": "ready"
}

The encryptedData field on the site side is usually empty, as the client logic ignores it. Although the value is returned via WebAssembly, in practice it is not used.