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

reCAPTCHA Image Solving

Solve Google reCAPTCHA v2 image challenges programmatically. reCAPTCHA displays a 3x3 or 4x4 grid of images asking users to identify specific objects. Our AI processes these images and returns correct selections with 99.8% accuracy.

What is reCAPTCHA Image?

Google reCAPTCHA v2 is one of the most widely used captcha services on the internet. It presents users with a grid of images (typically 3x3 or 4x4) and asks them to select specific objects (e.g., "Select all images with traffic lights"). Our API analyzes these images and returns the indices of correct selections, allowing you to automate the solving process.

Captcha Type

Use the following captcha type identifier in your API requests:

"type": "RECAPTCHA_IMAGE"

Request Format

POST /createTask

Request Parameters

Parameter Type Required Description
auth.token string required Your API key
captcha.type string required Must be "RECAPTCHA_IMAGE"
captcha.metadata.siteUrl string required URL where captcha appears
captcha.payload.images array required Array of base64-encoded images (9 or 16 images)
captcha.payload.question string required Question text (e.g., "Select all images with cars")
captcha.payload.questionType string required Grid type: "grid_3x3" (9 images), "grid_4x4" (16 images), or "grid_3x3_dynamic" (dynamic refresh)

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: 'RECAPTCHA_IMAGE',
      metadata: {
        siteUrl: 'https://example.com'
      },
      payload: {
        images: [
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Image 1
          '/9j/4AAQSkZJRgABAQAAAQABAAD...',  // Image 2
        ],
        question: 'Select all images with traffic lights',
        questionType: 'grid_3x3'  // or 'grid_4x4' for 16 images
      }
    }
  })
});

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_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)

JSON
{
  "success": true,
  "service": "MyDisct Solver",
  "message": "Captcha solved successfully",
  "task": {
    "id": "MyDisctSolver_abc123",
    "status": "completed",
    "result": {
      "answers": [0, 3, 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) for 3x3 grids, or 0-15 for 4x4 grids. Images are ordered left-to-right, top-to-bottom.

Python Example

Python
import requests
import time

def solve_recaptcha_image(images, question, site_url, api_key):
    # 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': 'RECAPTCHA_IMAGE',
                'metadata': {'siteUrl': site_url},
                'payload': {
                    'images': images,
                    'question': question,
                    'questionType': 'grid_3x3'  # or 'grid_4x4' for 16 images
                }
            }
        }
    )
    
    create_data = create_response.json()
    if not create_data['success']:
        raise Exception(create_data['error']['message'])
    
    task_id = create_data['task']['id']
    
    # Poll for result
    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')

# Usage
solution = solve_recaptcha_image(
    images=['base64_1', 'base64_2', '...'],
    question='Select all images with traffic lights',
    site_url='https://example.com',
    api_key='YOUR_API_KEY'
)
print(f'Solution: {solution}')

Implementation Guide

Step 1: Extract Images from reCAPTCHA

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

JavaScript
// Extract images from reCAPTCHA iframe
function extractRecaptchaImages() {
  const iframe = document.querySelector('iframe[src*="recaptcha"]');
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

  const question = iframeDoc.querySelector('.rc-imageselect-desc').textContent ||
                   iframeDoc.querySelector('.rc-imageselect-instructions').textContent;

  const imageElements = iframeDoc.querySelectorAll('.rc-image-tile-wrapper img');
  const images = [];

  for (const img of imageElements) {
    const imageUrl = img.src;

    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 solveRecaptcha(images, question, 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: 'RECAPTCHA_IMAGE',
        metadata: { siteUrl },
        payload: { images, question }
      }
    })
  });

  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 } = extractRecaptchaImages();
const solution = await solveRecaptcha(images, question, 'https://example.com');

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

Step 3: Apply Solution to reCAPTCHA

JavaScript
function applyRecaptchaSolution(solution) {
  const iframe = document.querySelector('iframe[src*="recaptcha"]');
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

  const imageTiles = iframeDoc.querySelectorAll('.rc-image-tile-wrapper');

  solution.forEach(index => {
    imageTiles[index].click();
  });

  setTimeout(() => {
    const verifyButton = iframeDoc.querySelector('#recaptcha-verify-button');
    if (verifyButton) {
      verifyButton.click();
    }
  }, 1000);
}

applyRecaptchaSolution(solution);

Grid Format

reCAPTCHA uses either 3x3 (9 images) or 4x4 (16 images) grids. Images are indexed from 0 starting at top-left, moving left-to-right, top-to-bottom.

3x3 Grid (9 images)

0
1
2
3
4
5
6
7
8

4x4 Grid (16 images)

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Best Practices

Recommendations
  • Include exact question text as displayed
  • Ensure images are in correct order (left-to-right, top-to-bottom)
  • Use base64 encoding without data URI prefix
  • Poll every 3 seconds for results
  • Handle dynamic captchas (new images after first solve)
  • Implement proper error handling for failed tasks
  • Support both 3x3 and 4x4 grid formats

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.

Issue: Dynamic captcha changes

Solution: Some reCAPTCHA challenges change images after the first solve. Handle this by extracting images again and making a new API request.