GeeTest v3 Image Solving
Solve GeeTest v3 captcha challenges including slide puzzles, click challenges, icon selection, and phrase matching. GeeTest v3 is widely used in China and international platforms with advanced AI-powered image recognition.
GeeTest v3 is a popular Chinese captcha service that presents users with various image-based challenges including slide puzzles, object selection, icon matching, and text-based tasks. Our API supports all GeeTest v3 challenge types with 99.5% accuracy and handles both Chinese and international content.
Captcha Type
Use the following captcha type identifier in your API requests:
"type": "GEETEST_V3_IMAGE"
Challenge Types
| Type | Description |
|---|---|
| slide | Slide puzzle piece to complete image |
| click | Click matching icons in sequence |
| icon | Select matching icons |
| iconcrush | Match and eliminate icons |
| gobang | Connect-five puzzle game |
| grid | 3x3 grid image selection (nine captcha) |
You only need to provide the questionType parameter (e.g., "slide", "click").
The API automatically formats the question internally. Do not add prefixes like "geetest_click:" to your
question text.
Request Format
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
auth.token |
string | required | Your API key |
captcha.type |
string | required | Must be "GEETEST_V3_IMAGE" |
captcha.metadata.siteUrl |
string | required | URL where captcha appears |
captcha.metadata.siteKey |
string | optional | GeeTest gt parameter |
captcha.metadata.challenge |
string | optional | GeeTest challenge parameter |
captcha.payload.images |
array | required | Array of base64-encoded images |
captcha.payload.questionType |
string | required | slide, click, icon, iconcrush, gobang, or grid |
captcha.payload.question |
string | optional | Question text (recommended for click and grid challenges) |
captcha.payload.referenceImages |
array | optional | Reference images (required for grid, required for click) |
Example Request
const response = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'GEETEST_V3_IMAGE',
metadata: {
siteUrl: 'https://example.com',
siteKey: 'gt_key_here',
challenge: 'challenge_string'
},
payload: {
images: [
'background_image_base64',
'puzzle_piece_base64'
],
question: 'Slide the puzzle piece',
questionType: 'slide',
referenceImages: []
}
}
})
});
Click Challenge Example
const response = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'GEETEST_V3_IMAGE',
metadata: {
siteUrl: 'https://example.com'
},
payload: {
images: ['main_image_base64'],
question: 'Click in order: Elephant, Tiger, Lion',
questionType: 'click',
referenceImages: []
}
}
})
});
Grid Challenge Example (Nine Captcha)
const response = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'GEETEST_V3_IMAGE',
metadata: {
siteUrl: 'https://example.com'
},
payload: {
images: ['grid_image_base64'],
question: 'Click all images matching the reference',
questionType: 'grid',
referenceImages: ['reference_image_base64']
}
}
})
});
Grid challenge requests must include questionType: "grid" and a single
reference image in referenceImages.
Response Format
Create Task Response (Processing)
{
"success": true,
"service": "MyDisct Solver",
"message": "Captcha is being processed",
"task": {
"id": "MyDisctSolver_abc123",
"status": "processing"
}
}
Fetch Result Response (Processing)
{
"success": true,
"service": "MyDisct Solver",
"message": "Captcha is being processed",
"task": {
"id": "MyDisctSolver_abc123",
"status": "processing"
}
}
Fetch Result Response (Completed)
Slide Response
{
"success": true,
"service": "MyDisct Solver",
"task": {
"id": "MyDisctSolver_abc123",
"status": "completed",
"result": {
"answers": [123, 0],
"timestamp": "2025-11-05T12:34:56.789Z"
}
}
}
For slide: [x_position, y_position]. X is horizontal distance to slide.
Click Response
{
"success": true,
"service": "MyDisct Solver",
"task": {
"id": "MyDisctSolver_abc123",
"status": "completed",
"result": {
"answers": [[120, 80], [240, 160], [360, 240]],
"size": [400, 300],
"timestamp": "2025-11-05T12:34:56.789Z"
}
}
}
For click: Array of [x, y] coordinates. Size indicates image dimensions.
Grid Response (Nine Captcha)
{
"success": true,
"service": "MyDisct Solver",
"task": {
"id": "MyDisctSolver_abc123",
"status": "completed",
"result": {
"answers": [1, 4, 7],
"timestamp": "2025-11-05T12:34:56.789Z"
}
}
}
For grid: Array of cell indices (1-9) to click in the 3x3 grid. Cells are numbered 1-9 from left to right, top to bottom.
The answers format depends on challenge type:
• Slide: [x_position, y_position] coordinates for puzzle placement
• Click: Array of [x, y] coordinates for sequential clicking
• Icon/Phrase: Array of indices for image selection
• Space: Array of indices for spatial relationship selection
• Grid: Array of cell indices (1-9) to click in the 3x3 grid
Implementation Guide
Step 1: Extract Images from GeeTest v3
GeeTest v3 challenges vary by type. Extract the appropriate data based on the challenge type:
// Extract GeeTest v3 challenge data
function extractGeeTestV3Data() {
const iframe = document.querySelector('iframe[src*="geetest.com"]');
if (!iframe) return null;
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
const questionElement = iframeDoc.querySelector('.geetest_radar_tip_content');
const question = questionElement ? questionElement.textContent : '';
let questionType = 'unknown';
if (question.includes('拖动滑块')) {
questionType = 'slide';
} else if (question.includes('请点击') || question.includes('依次点击')) {
questionType = 'click';
} else if (question.includes('请选出') || question.includes('选择')) {
questionType = 'icon';
}
let images = [];
if (questionType === 'slide') {
images = extractSlideImages(iframeDoc);
} else {
images = extractGridImages(iframeDoc);
}
return { question, questionType, images };
}
function extractSlideImages(iframeDoc) {
const bgImage = iframeDoc.querySelector('.geetest_canvas_bg');
const pieceImage = iframeDoc.querySelector('.geetest_canvas_slice');
return [bgImageBase64, pieceImageBase64];
}
function extractGridImages(iframeDoc) {
const imageElements = iframeDoc.querySelectorAll('.geetest_item_img');
const images = [];
imageElements.forEach(img => {
images.push(imgBase64);
});
return images;
}
Step 2: Send to API and Poll for Result
async function solveGeeTestV3(images, question, questionType, siteUrl) {
const createResponse = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'GEETEST_V3_IMAGE',
metadata: { siteUrl },
payload: { images, question, questionType }
}
})
});
const createData = await createResponse.json();
if (!createData.success) {
throw new Error(createData.error.message);
}
const taskId = createData.task.id;
while (true) {
await new Promise(resolve => setTimeout(resolve, 3000));
const resultResponse = await fetch('https://solver-api.mydisct.com/fetchResult', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({ taskId })
});
const resultData = await resultResponse.json();
if (resultData.task.status === 'completed') {
return resultData.task.result.answers;
} else if (resultData.task.status === 'failed') {
throw new Error('Captcha solving failed');
}
}
}
const { question, questionType, images } = extractGeeTestV3Data();
const solution = await solveGeeTestV3(images, question, questionType, 'https://example.com');
console.log('Solution:', solution);
Python Example
import requests
import time
def solve_geetest_v3(images, question, question_type, site_url, api_key, reference_images=None):
create_response = requests.post(
'https://solver-api.mydisct.com/createTask',
headers={'Content-Type': 'application/json', 'apikey': api_key},
json={
'auth': {'token': api_key},
'context': {'source': 'api', 'version': '1.0.0'},
'captcha': {
'type': 'GEETEST_V3_IMAGE',
'metadata': {'siteUrl': site_url},
'payload': {
'images': images,
'question': question,
'questionType': question_type,
'referenceImages': reference_images or []
}
}
}
)
create_data = create_response.json()
if not create_data['success']:
raise Exception(create_data['error']['message'])
task_id = create_data['task']['id']
while True:
time.sleep(3)
result_response = requests.post(
'https://solver-api.mydisct.com/fetchResult',
headers={'Content-Type': 'application/json', 'apikey': api_key},
json={'taskId': task_id}
)
result_data = result_response.json()
if result_data['task']['status'] == 'completed':
return result_data['task']['result']
elif result_data['task']['status'] == 'failed':
raise Exception('Captcha solving failed')
# Slide example
solution = solve_geetest_v3(
images=['background_base64', 'piece_base64'],
question='Slide the puzzle piece',
question_type='slide',
site_url='https://example.com',
api_key='YOUR_API_KEY'
)
print(f'Slide to X: {solution["answers"][0]}')
Best Practices
- Include gt and challenge parameters when available
- Provide questionType parameter - the API handles formatting automatically
- For click challenges, include reference images if shown
- For grid challenges, include the reference image showing what to match
- Grid responses return 1-indexed cell numbers (1-9) for a 3x3 grid
- Handle Chinese text in questions properly
- Slide challenges return X coordinate only (Y is usually 0)
- Implement proper error handling for failed tasks
- Monitor for interface changes as GeeTest updates frequently
Common Issues
Solution: Ensure your application properly handles UTF-8 encoding for Chinese characters in questions and responses.
Solution: Use reliable CSS selectors to detect challenge types. GeeTest frequently updates their interface, so monitor for changes.
Solution: For slide challenges, only the X coordinate is typically needed (Y is usually 0). Ensure you're applying coordinates relative to the slider's container.
Solution: GeeTest uses canvas elements for images. Ensure you're extracting images after they fully load and handling canvas-to-base64 conversion properly.
Solution: Include gt and challenge parameters from the GeeTest initialization when available. These help with more accurate solving.
Solution: Grid (nine) challenges require a reference image showing what to match. Include the reference image in the referenceImages array.