Chat with us, powered by LiveChat
← Return to MyDisct Solver

GeeTest v4 Image Solving

Solve GeeTest v4 captcha challenges including slide puzzles, icon crush, gobang, click, and grid (nine) challenges. GeeTest v4 is the latest version with enhanced security features.

What is GeeTest v4 Image?

GeeTest v4 is an advanced anti-bot system that presents users with various interactive challenges. It includes slide puzzles, icon matching games, and other visual challenges that require image analysis and pattern recognition. Our API handles all GeeTest v4 challenge types with high accuracy.

Captcha Type

Use the following captcha type identifier in your API requests:

"type": "GEETEST_V4_IMAGE"

Challenge Types

Type Description
slide Slide puzzle piece to complete image
icon / iconcrush Match and eliminate icons
gobang Connect-five puzzle game
click Click matching icons in sequence
grid 3x3 grid image selection (nine captcha)

Request Format

POST /createTask

Request Parameters

Parameter Type Required Description
auth.token string required Your API key
captcha.type string required Must be "GEETEST_V4_IMAGE"
captcha.metadata.siteUrl string required The URL where the captcha appears
captcha.metadata.siteKey string optional GeeTest captcha ID (if available)
captcha.payload.images array required Array of base64-encoded images
captcha.payload.questionType string required Challenge type: "slide", "iconcrush", "gobang", "click", or "grid"
captcha.payload.question string optional Question text (recommended for grid challenges)
captcha.payload.referenceImages array optional Reference images (required for grid, required for click)
Grid QuestionType

Grid challenge requests must include questionType: "grid" and a single reference image in referenceImages.

Example Request

Slide Challenge

JavaScript
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_V4_IMAGE',
      metadata: {
        siteUrl: 'https://example.com',
        siteKey: 'captcha_id_here'
      },
      payload: {
        images: [
          'background_image_base64',
          'puzzle_piece_base64'
        ],
        questionType: 'slide',
        referenceImages: []
      }
    }
  })
});

Icon Crush Challenge

JavaScript
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_V4_IMAGE',
      metadata: {
        siteUrl: 'https://example.com'
      },
      payload: {
        images: ['game_board_base64'],
        questionType: 'iconcrush'
      }
    }
  })
});

Click Challenge

JavaScript
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_V4_IMAGE',
      metadata: {
        siteUrl: 'https://example.com'
      },
      payload: {
        images: ['main_image_base64'],
        referenceImages: [
          'reference_1_base64',
          'reference_2_base64',
          'reference_3_base64'
        ],
        questionType: 'click'
      }
    }
  })
});

Grid Challenge (Nine Captcha)

JavaScript
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_V4_IMAGE',
      metadata: {
        siteUrl: 'https://example.com'
      },
      payload: {
        images: ['grid_image_base64'],
        referenceImages: ['reference_image_base64'],
        questionType: 'grid',
        question: 'Click all images matching the reference'
      }
    }
  })
});

Response Format

Create Task Response (Processing)

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "message": "Captcha is being processed",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "processing"
  }
}

Fetch Result Response (Processing)

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "message": "Captcha is being processed",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "processing"
  }
}

Fetch Result Response (Completed)

Slide Response

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "completed",
    "result": {
      "answers": [145, 0],
      "timestamp": "2025-11-05T12:34:56.789Z"
    }
  }
}

Icon Crush / Gobang Response

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "completed",
    "result": {
      "answers": [3, 7],
      "timestamp": "2025-11-05T12:34:56.789Z"
    }
  }
}

Array contains indices of positions to swap/click.

Click Response

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "completed",
    "result": {
      "answers": [[120, 80], [240, 160]],
      "timestamp": "2025-11-05T12:34:56.789Z"
    }
  }
}

Array of [x, y] coordinates to click in sequence.

Grid Response (Nine Captcha)

JSON
{
  "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.

Understanding the Response

The answers array format depends on the challenge type:
• Slide: [x, y] coordinates for puzzle placement
• Icon/Gobang: Array of indices for swap positions
• Click: Array of [x, y] coordinates for sequential clicks
• Grid: Array of cell indices (1-9) to click in the 3x3 grid

Implementation Guide

Step 1: Extract Images from GeeTest v4

GeeTest v4 challenges vary by type. Here's how to extract data for each challenge type:

JavaScript
// Extract GeeTest v4 challenge data
function extractGeeTestData() {
  const iframe = document.querySelector('iframe[src*="geetest.com"]');
  if (!iframe) return null;

  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

  const challengeType = detectChallengeType(iframeDoc);

  let images = [];
  let referenceImages = [];

  switch (challengeType) {
    case 'slide':
      images = extractSlideImages(iframeDoc);
      break;
    case 'iconcrush':
    case 'gobang':
      images = [extractGameBoardImage(iframeDoc)];
      break;
    case 'click':
      images = extractClickImages(iframeDoc);
      referenceImages = extractReferenceImages(iframeDoc);
      break;
    case 'grid':
      images = extractGridImages(iframeDoc);
      referenceImages = extractReferenceImages(iframeDoc);
      break;
  }

  return { challengeType, images, referenceImages };
}

function detectChallengeType(iframeDoc) {
  if (iframeDoc.querySelector('.geetest_slide')) return 'slide';
  if (iframeDoc.querySelector('.geetest_iconcrush')) return 'iconcrush';
  if (iframeDoc.querySelector('.geetest_gobang')) return 'gobang';
  if (iframeDoc.querySelector('.geetest_click')) return 'click';
  if (iframeDoc.querySelector('.geetest_nine')) return 'grid';
  return 'unknown';
}

Step 2: Send to API and Poll for Result

JavaScript
async function solveGeeTestV4(challengeType, images, referenceImages, siteUrl, siteKey) {
  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_V4_IMAGE',
        metadata: { siteUrl, siteKey },
        payload: {
          images,
          questionType: challengeType,
          referenceImages: referenceImages || []
        }
      }
    })
  });

  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 { challengeType, images, referenceImages } = extractGeeTestData();
const solution = await solveGeeTestV4(
  challengeType,
  images,
  referenceImages,
  'https://example.com',
  'captcha_id_here'
);

console.log('Solution:', solution);

Step 3: Apply Solution to GeeTest v4

JavaScript
function applyGeeTestSolution(solution, challengeType) {
  const iframe = document.querySelector('iframe[src*="geetest.com"]');
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

  switch (challengeType) {
    case 'slide':
      const [x, y] = solution;
      const slider = iframeDoc.querySelector('.geetest_slider');
      break;

    case 'iconcrush':
    case 'gobang':
      solution.forEach(([fromIndex, toIndex]) => {
        const element1 = iframeDoc.querySelector(`[data-index="${fromIndex}"]`);
        const element2 = iframeDoc.querySelector(`[data-index="${toIndex}"]`);
      });
      break;

    case 'click':
      solution.forEach(([x, y]) => {
        const clickEvent = new MouseEvent('click', {
          clientX: x,
          clientY: y,
          bubbles: true
        });
        iframeDoc.dispatchEvent(clickEvent);
      });
      break;
  }

  const submitBtn = iframeDoc.querySelector('.geetest_commit');
  if (submitBtn) submitBtn.click();
}

applyGeeTestSolution(solution, challengeType);

Python Example

Python
import requests
import time

def solve_geetest_v4(images, question_type, site_url, api_key, 
                     question=None, reference_images=None):
    payload = {
        'images': images,
        'questionType': question_type
    }
    
    if question:
        payload['question'] = question
    if reference_images:
        payload['referenceImages'] = reference_images
    
    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_V4_IMAGE',
                'metadata': {'siteUrl': site_url},
                'payload': payload
            }
        }
    )
    
    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']['answers']
        elif result_data['task']['status'] == 'failed':
            raise Exception('Captcha solving failed')

# Slide example
solution = solve_geetest_v4(
    images=['background_base64', 'piece_base64'],
    question_type='slide',
    site_url='https://example.com',
    api_key='YOUR_API_KEY'
)
print(f'Solution: {solution}')

Best Practices

Recommendations
  • Include captcha_id (siteKey) when available for better accuracy
  • For click challenges, include all 3 reference images
  • For grid challenges, include a reference image and question text
  • Icon crush and gobang return swap positions (0-based indices)
  • Grid responses may return 1-indexed cell numbers (1-9) for a 3x3 grid
  • Ensure images are properly base64 encoded
  • Poll for results every 3 seconds to avoid rate limiting

Common Issues

Issue: Invalid questionType parameter

Solution: Ensure you use one of the supported questionType values: "slide", "icon", "iconcrush", "gobang", or "click". Check that the questionType matches the actual challenge presented by GeeTest.

Issue: Missing reference images for click challenges

Solution: Click challenges require reference images to be included. Make sure to extract and send all 3 reference images shown above the clickable area.

Issue: Grid challenge returns no solution

Solution: Grid challenges require a reference image showing what to match. Include the reference image in the referenceImages array.

Issue: Challenge type detection fails

Solution: GeeTest frequently updates their interface. Monitor for changes in CSS selectors and update your detection logic accordingly. Consider using multiple selectors for redundancy.

Issue: Invalid coordinates returned

Solution: Ensure coordinates are applied relative to the iframe's viewport. Use iframeDoc.elementFromPoint() or calculate absolute positions correctly.