API Tutorials

How to Solve GeeTest v3 Using API

GeeTest v3 presents interactive challenges — slide puzzles, icon selections, or word matching. Unlike reCAPTCHA, GeeTest uses a custom verification flow with three parameters (gt, challenge, api_server) that you must extract from the page before solving.

This guide walks through the complete process of extracting GeeTest parameters and solving the challenge with the CaptchaAI API.


Requirements

Item Value
CaptchaAI API key From captchaai.com
GeeTest gt value Static per-site identifier
GeeTest challenge Dynamic per-session value
Page URL The URL where GeeTest appears
Language Python 3.7+ or Node.js 14+

Step 1: Extract GeeTest parameters

GeeTest requires three parameters. The gt is static (same for every request), while challenge changes per session.

Method 1: Network tab

  1. Open DevTools → Network tab
  2. Filter by register-slide or gettype.php or get.php
  3. Trigger the captcha and look for the initialization request
  4. The response contains gt, challenge, and sometimes api_server
{
  "success": 1,
  "gt": "019924a82c70bb123aae90d483087f94",
  "challenge": "12345678abc90def12345678abc90def",
  "new_captcha": true
}

Method 2: Page source

// Search page source for initGeetest or gt value
document.querySelectorAll('script').forEach(s => {
  if (s.textContent.includes('initGeetest')) {
    console.log(s.textContent);
  }
});

Method 3: API endpoint

Many sites fetch GeeTest parameters from their own API:

# The site's registration endpoint
params_response = requests.get("https://example.com/api/captcha/register")
data = params_response.json()
gt = data["gt"]
challenge = data["challenge"]

Step 2: Submit the task to CaptchaAI

Python

import requests
import time

API_KEY = "YOUR_API_KEY"

response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "geetest",
    "gt": "019924a82c70bb123aae90d483087f94",
    "challenge": "12345678abc90def12345678abc90def",
    "api_server": "api.geetest.com",  # Optional, use if site specifies
    "pageurl": "https://example.com/login",
    "json": 1
})

data = response.json()
if data.get("status") != 1:
    raise Exception(f"Submit error: {data.get('request')}")

task_id = data["request"]
print(f"Task submitted: {task_id}")

Node.js

const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';

async function submitGeeTest(gt, challenge, pageurl) {
  const { data } = await axios.get('https://ocr.captchaai.com/in.php', {
    params: {
      key: API_KEY,
      method: 'geetest',
      gt,
      challenge,
      api_server: 'api.geetest.com',
      pageurl,
      json: 1
    }
  });

  if (data.status !== 1) throw new Error(`Submit error: ${data.request}`);
  return data.request;
}

Step 3: Poll for the solution

GeeTest solving returns three values: challenge, validate, and seccode.

Python

def get_geetest_solution(task_id):
    for attempt in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1
        }).json()

        if result.get("status") == 1:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise Exception(f"Error: {result.get('request')}")

    raise Exception("Timeout")

solution = get_geetest_solution(task_id)
# solution = {
#   "geetest_challenge": "12345678abc90def12345678abc90def1a",
#   "geetest_validate": "abcdef1234567890abcdef1234567890",
#   "geetest_seccode": "abcdef1234567890abcdef1234567890|jordan"
# }

Node.js

async function getGeeTestSolution(taskId) {
  for (let i = 0; i < 30; i++) {
    await new Promise(r => setTimeout(r, 5000));
    const { data } = await axios.get('https://ocr.captchaai.com/res.php', {
      params: { key: API_KEY, action: 'get', id: taskId, json: 1 }
    });
    if (data.status === 1) return data.request;
    if (data.request !== 'CAPCHA_NOT_READY') throw new Error(data.request);
  }
  throw new Error('Timeout');
}

Step 4: Submit the solution to the target site

Send all three values to the site's verification endpoint:

# Submit the GeeTest solution with the form data
verify_response = requests.post("https://example.com/api/login", data={
    "username": "user@example.com",
    "password": "password123",
    "geetest_challenge": solution["geetest_challenge"],
    "geetest_validate": solution["geetest_validate"],
    "geetest_seccode": solution["geetest_seccode"]
})

print(f"Login status: {verify_response.status_code}")

Complete Python example

import requests
import time

API_KEY = "YOUR_API_KEY"
SITE_URL = "https://example.com/login"

# 1. Get GeeTest parameters from the site
params = requests.get("https://example.com/api/captcha/register").json()

# 2. Submit to CaptchaAI
submit = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "geetest",
    "gt": params["gt"],
    "challenge": params["challenge"],
    "pageurl": SITE_URL,
    "json": 1
}).json()
task_id = submit["request"]

# 3. Poll for solution
for _ in range(30):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        solution = result["request"]
        break

# 4. Submit to site
login = requests.post(SITE_URL, data={
    "username": "user@example.com",
    "password": "pass",
    "geetest_challenge": solution["geetest_challenge"],
    "geetest_validate": solution["geetest_validate"],
    "geetest_seccode": solution["geetest_seccode"]
})
print(f"Result: {login.status_code}")

Troubleshooting

Error Cause Fix
ERROR_BAD_PARAMETERS Missing gt or challenge Both are required — extract from the page
ERROR_CAPTCHA_UNSOLVABLE Challenge expired or invalid Re-fetch a fresh challenge from the site
Solution rejected by site Stale challenge value The challenge is single-use; get a new one for each attempt
geetest_validate is empty Solve failed internally Retry with a fresh challenge

FAQ

Why do I need to fetch a fresh challenge each time?

The challenge value is single-use. Once it is consumed (whether by a successful solve or an expiry), the site's backend will reject it. Always fetch a new challenge before each solve.

What is the api_server parameter?

It specifies which GeeTest server handles verification. Common values are api.geetest.com and api-na.geetest.com. If the site uses a custom server, include it in your request.

How long does GeeTest solving take?

Typically 15–30 seconds. Slide puzzles and icon challenges take similar times.

Can I solve GeeTest v4 with this method?

No. GeeTest v4 uses a different protocol. Check if CaptchaAI supports the specific GeeTest version on the site.

What is the difference between GeeTest slide and click challenges?

GeeTest v3 has multiple challenge types (slide, icon click, word match), but the API parameters and flow are identical. CaptchaAI handles all v3 types transparently.


Full Working Code

Complete runnable examples for this article in Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin & Bash.

View on GitHub →

Discussions (0)

No comments yet.