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.
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
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
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)
{
"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)
{
"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"
}
}
}
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
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:
// 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
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
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)
4x4 Grid (16 images)
Best Practices
- 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
Solution: Ensure images are properly base64-encoded and in the correct order (left-to-right, top-to-bottom).
Solution: Verify the question text matches exactly what's shown in the captcha. Even small differences can affect accuracy.
Solution: Increase polling interval or check if images are too large. Consider compressing images before sending.
Solution: Some reCAPTCHA challenges change images after the first solve. Handle this by extracting images again and making a new API request.