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

hCaptcha Image Solving

Solve hCaptcha image challenges programmatically with our AI-powered API. hCaptcha presents users with a grid of images and asks them to select specific objects. Our service analyzes these images and returns the correct selections with 99.8% accuracy.

What is hCaptcha Image?

hCaptcha is a popular captcha service that displays a 3x3 grid of images and asks users to identify images containing specific objects (e.g., "Select all images with traffic lights"). Our API processes these images and returns the indices of correct selections.

Captcha Type

Use the following captcha type identifier in your API requests:

"type": "HCAPTCHA_IMAGE"

Request Format

POST /createTask

Request Parameters

Parameter Type Required Description
auth.token string required Your API key
captcha.type string required Must be "HCAPTCHA_IMAGE"
captcha.metadata.siteUrl string required The URL where the captcha appears
captcha.metadata.siteKey string optional hCaptcha site key (if available)
captcha.payload.images array required Array of base64-encoded images (9 images for 3x3 grid)
captcha.payload.question string required The question text (e.g., "Select all images with cars")
captcha.payload.referenceImages array optional Reference images shown above the grid (if any)
captcha.payload.questionType string optional Challenge type: "grid" (default), "multi", "click", or "drag"

Example Request

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: 'HCAPTCHA_IMAGE',
      metadata: {
        siteUrl: 'https://example.com',
        siteKey: 'a5f74b19-9e45-40e0-b45d-47ff91b7a6c2'
      },
      payload: {
        images: [
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 1
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 2
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 3
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 4
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 5
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 6
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 7
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Base64 image 8
          '/9j/4AAQSkZJRgABAQAAAQABAAD...'   // Base64 image 9
        ],
        question: 'Select all images with traffic lights',
        referenceImages: [],
        questionType: 'grid'  // or 'multi', 'click', 'drag'
      }
    }
  })
});

const data = await response.json();
console.log('Task ID:', data.task.id);

Response Format

Create Task Response (Processing)

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

Fetch Result Response (Processing)

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

Fetch Result Response (Completed)

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "message": "Captcha solved successfully",
  "task": {
    "id": "MyDisctSolver_abc123def456",
    "status": "completed",
    "result": {
      "answers": [0, 2, 5, 7],
      "timestamp": "2025-11-05T12:34:56.789Z"
    }
  }
}
Understanding the Response

The answers array contains the indices of images that should be selected. Indices start from 0 (top-left) and go to 8 (bottom-right) in a 3x3 grid. In the example above, images at positions 0, 2, 5, and 7 contain traffic lights.

Implementation Guide

Step 1: Extract Images from hCaptcha

First, you need to extract the images from the hCaptcha challenge. Here's how to do it using JavaScript:

JavaScript
// Extract images from hCaptcha iframe
function extractHCaptchaImages() {
  const iframe = document.querySelector('iframe[src*="hcaptcha.com"]');
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  
  const question = iframeDoc.querySelector('.prompt-text').textContent;
  
  const imageElements = iframeDoc.querySelectorAll('.task-image .image');
  const images = [];
  
  for (const img of imageElements) {
    const bgImage = img.style.backgroundImage;
    const imageUrl = bgImage.slice(5, -2); // Remove url(" and ")
    
    fetch(imageUrl)
      .then(res => res.blob())
      .then(blob => {
        const reader = new FileReader();
        reader.onloadend = () => {
          const base64 = reader.result.split(',')[1];
          images.push(base64);
        };
        reader.readAsDataURL(blob);
      });
  }
  
  return { question, images };
}

Step 2: Send to API and Poll for Result

JavaScript
async function solveHCaptcha(images, question, 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: 'HCAPTCHA_IMAGE',
        metadata: { siteUrl, siteKey },
        payload: { images, question, questionType: 'grid' }
      }
    })
  });
  
  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)); // Wait 3 seconds
    
    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 { images, question } = extractHCaptchaImages();
const solution = await solveHCaptcha(
  images, 
  question, 
  'https://example.com',
  'a5f74b19-9e45-40e0-b45d-47ff91b7a6c2'
);

console.log('Solution:', solution); // [0, 2, 5, 7]

Step 3: Apply Solution to hCaptcha

JavaScript
function applyHCaptchaSolution(solution) {
  const iframe = document.querySelector('iframe[src*="hcaptcha.com"]');
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  
  const imageElements = iframeDoc.querySelectorAll('.task-image .image');
  
  solution.forEach(index => {
    imageElements[index].click();
  });
  
  iframeDoc.querySelector('.button-submit').click();
}

applyHCaptchaSolution(solution);

Python Example

Python
import requests
import time
import base64

def solve_hcaptcha(images, question, site_url, site_key, api_key):
    """
    Solve hCaptcha image challenge
    
    Args:
        images: List of base64-encoded images
        question: Question text
        site_url: URL where captcha appears
        site_key: hCaptcha site key
        api_key: Your MyDisct Solver API key
    
    Returns:
        List of indices for correct images
    """
    
    # Step 1: Create task
    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': 'HCAPTCHA_IMAGE',
                'metadata': {
                    'siteUrl': site_url,
                    'siteKey': site_key
                },
                'payload': {
                    'images': images,
                    'question': question,
                    'questionType': 'grid'
                }
            }
        }
    )
    
    create_data = create_response.json()
    
    if not create_data['success']:
        raise Exception(create_data['error']['message'])
    
    task_id = create_data['task']['id']
    
    # Step 2: Poll for result
    while True:
        time.sleep(3)  # Wait 3 seconds
        
        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')

# Example usage
images = [
    'base64_image_1',
    'base64_image_2',
    # ... 9 images total
]

solution = solve_hcaptcha(
    images=images,
    question='Select all images with traffic lights',
    site_url='https://example.com',
    site_key='a5f74b19-9e45-40e0-b45d-47ff91b7a6c2',
    api_key='YOUR_API_KEY'
)

print(f'Solution: {solution}')  # [0, 2, 5, 7]

Best Practices

Recommendations
  • Always include the exact question text as it appears in the captcha
  • Ensure images are properly base64-encoded without data URI prefix
  • Poll for results every 3-5 seconds to avoid rate limiting
  • Implement proper error handling for failed tasks
  • Cache the site key if it doesn't change frequently
  • Use reference images when available for better accuracy

Common Issues

Issue: Images not being recognized

Solution: Ensure images are properly base64-encoded and in the correct order (left-to-right, top-to-bottom).

Issue: Wrong selections returned

Solution: Verify the question text matches exactly what's shown in the captcha. Even small differences can affect accuracy.

Issue: Task timeout

Solution: Increase polling interval or check if images are too large. Consider compressing images before sending.