Tutorial

How to Solve Yandex Puzzle Captcha: Complete Guide

2026-05-21

Learn how to automatically solve Yandex SmartCaptcha (Puzzle/Slider type) using our API. This guide covers parameter extraction with regex, C# examples, and API integration.

1. What is Yandex Puzzle Captcha?

Yandex Puzzle Captcha (also known as Kaleidoscope or Slider captcha) requires users to drag a puzzle piece to complete an image. The challenge is to determine the correct horizontal position (step number) where the piece fits perfectly.

Our API solves Yandex Puzzle captchas in ~1.24 seconds with 99.8% accuracy.

2. Extracting Parameters from Page HTML

To solve a Yandex Puzzle captcha, you need to extract two key parameters from the page HTML:

  • imageSrc - URL of the puzzle background image
  • task - array of numbers representing the puzzle pattern, e.g. [6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]

2.1 Regex Patterns for Parameter Extraction

Use these proven regex patterns to extract captcha parameters from JavaScript/HTML:

C# Regex Patterns (Compiled)

Extract task array:

task:""\[(.*?)\]""

Extract imageSrc URL:

imageSrc:""(.*?)""

Full C# Example:

using System.Text.RegularExpressions;

// Compiled regex patterns for performance
private static readonly Regex _captchaTasks = new(
    @"task:""\[(.*?)\]""", 
    RegexOptions.IgnoreCase | RegexOptions.Compiled);

private static readonly Regex _captchaUrl = new(
    @"imageSrc:""(.*?)""", 
    RegexOptions.IgnoreCase | RegexOptions.Compiled);

public static (string? imageUrl, string? taskArray) ExtractPuzzleParams(string html)
{
    var taskMatch = _captchaTasks.Match(html);
    var urlMatch = _captchaUrl.Match(html);
    
    string? task = taskMatch.Success ? $"[{taskMatch.Groups[1].Value}]" : null;
    string? imageUrl = urlMatch.Success ? urlMatch.Groups[1].Value : null;
    
    return (imageUrl, task);
}

2.2 Downloading the Puzzle Image

public static async Task<byte[]> DownloadPuzzleImageAsync(string imageUrl)
{
    using var client = new HttpClient();
    return await client.GetByteArrayAsync(imageUrl);
}

// Usage
var (imageUrl, task) = ExtractPuzzleParams(htmlContent);
if (!string.IsNullOrEmpty(imageUrl) && !string.IsNullOrEmpty(task))
{
    var imageBytes = await DownloadPuzzleImageAsync(imageUrl);
    // Save to file if needed
    await File.WriteAllBytesAsync("puzzle.png", imageBytes);
}

3. Solving with noncaptcha API

Once you have the puzzle image and task array, send them to our API endpoint:

3.1 API Endpoint

POST /api/json/puzzle Content-Type: multipart/form-data
Parameter    Type      Description
captcha      file      Puzzle background image (PNG/JPG)
task         string    Task array as JSON string, e.g. "[6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]"

3.2 cURL Example

curl -X POST "http://api.noncaptcha.com/api/json/puzzle" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "captcha=@puzzle.png" \
  -F "task=[6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]"

3.3 C# Example (Complete)

using System.Net.Http;
using System.Text;
using System.Text.Json;

public async Task<int> SolveYandexPuzzleAsync(
    string apiKey, 
    string imagePath, 
    string taskArray)
{
    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
    
    var content = new MultipartFormDataContent();
    
    // Add puzzle image
    var imageBytes = await File.ReadAllBytesAsync(imagePath);
    var imageContent = new ByteArrayContent(imageBytes);
    imageContent.Headers.ContentType = 
        new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
    content.Add(imageContent, "captcha", Path.GetFileName(imagePath));
    
    // Add task array as string
    content.Add(new StringContent(taskArray, Encoding.UTF8), "task");
    
    // Send request
    var response = await client.PostAsync(
        "http://api.noncaptcha.com/api/json/puzzle", 
        content
    );
    
    response.EnsureSuccessStatusCode();
    
    // Parse response: {"step": 12}
    var jsonResponse = await response.Content.ReadAsStringAsync();
    using var doc = JsonDocument.Parse(jsonResponse);
    return doc.RootElement.GetProperty("step").GetInt32();
}

3.4 Full Integration: Extract + Solve

public class YandexPuzzleSolver
{
    private readonly HttpClient _client;
    private readonly string _apiKey;
    
    // Compiled regex patterns
    private static readonly Regex _captchaTasks = new(
        @"task:""\[(.*?)\]""", 
        RegexOptions.IgnoreCase | RegexOptions.Compiled);
    
    private static readonly Regex _captchaUrl = new(
        @"imageSrc:""(.*?)""", 
        RegexOptions.IgnoreCase | RegexOptions.Compiled);
    
    public YandexPuzzleSolver(string apiKey)
    {
        _apiKey = apiKey;
        _client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
        _client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
    }
    
    public async Task<int?> SolveFromHtmlAsync(string htmlContent)
    {
        // 1. Extract parameters using regex
        var taskMatch = _captchaTasks.Match(htmlContent);
        var urlMatch = _captchaUrl.Match(htmlContent);
        
        if (!taskMatch.Success || !urlMatch.Success)
            return null;
            
        string taskArray = $"[{taskMatch.Groups[1].Value}]";
        string imageUrl = urlMatch.Groups[1].Value;
        
        // 2. Download puzzle image
        var imageBytes = await _client.GetByteArrayAsync(imageUrl);
        
        // 3. Prepare multipart request
        var content = new MultipartFormDataContent();
        content.Add(new ByteArrayContent(imageBytes), "captcha", "puzzle.png");
        content.Add(new StringContent(taskArray, Encoding.UTF8), "task");
        
        // 4. Send to API
        var response = await _client.PostAsync(
            "http://api.noncaptcha.com/api/json/puzzle",
            content
        );
        
        // 5. Parse and return step number
        var json = await response.Content.ReadAsStringAsync();
        using var doc = JsonDocument.Parse(json);
        return doc.RootElement.GetProperty("step").GetInt32();
    }
    
    public void Dispose() => _client?.Dispose();
}

// Usage example:
using var solver = new YandexPuzzleSolver("YOUR_API_KEY");
var html = await httpClient.GetStringAsync("https://example.com/page-with-captcha");
var step = await solver.SolveFromHtmlAsync(html);

if (step.HasValue)
{
    Console.WriteLine($"✅ Move slider to step: {step.Value}");
    // Use step to click slider buttons or move slider element
}
else
{
    Console.WriteLine("❌ Failed to extract captcha parameters");
}

4. Using the Solution: Moving the Slider

After receiving the step number from the API, you need to simulate user interaction to move the puzzle slider to the correct position.

// Example using Playwright for browser automation
public async Task MoveSliderToStepAsync(IPage page, int step)
{
    // Wait for slider controls
    var nextBtn = await page.WaitForSelectorAsync(
        "button[aria-label*='Сдвинуть'], button[aria-label*='Move']",
        new() { Timeout = 10000 });
    
    var slider = await page.WaitForSelectorAsync("#captcha-slider");
    var submitBtn = await page.WaitForSelectorAsync("button[data-testid='submit']");
    
    // Click 'next' button 'step' times with human-like delays
    var random = new Random();
    for (int i = 0; i < step; i++)
    {
        await nextBtn.ClickAsync();
        await Task.Delay(random.Next(100, 400)); // Human-like delay
    }
    
    // Small random pause before submit
    await Task.Delay(random.Next(300, 900));
    
    // Click submit button
    await submitBtn.ClickAsync();
    
    // Wait for navigation or captcha disappearance
    await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
}

5. Error Handling & Best Practices

Retry logic: If the API returns an error or the captcha is not solved correctly, implement retry with exponential backoff (max 3 attempts).
Cache solutions: Hash the puzzle image URL + task array and cache the result. Identical captchas often repeat, saving costs.
Handle balance errors: Check for HTTP 402 (Insufficient Balance) and pause requests before retrying.

Retry Example (C# with Polly)

using Polly;

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => 
        r.StatusCode == System.Net.HttpStatusCode.RequestTimeout ||
        (int)r.StatusCode >= 500)
    .WaitAndRetryAsync(
        retryCount: 3,
        sleepDurationProvider: attempt => 
            TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (outcome, timespan, attempt, context) =>
        {
            Console.WriteLine($"Retry {attempt} after {timespan}s");
        });

// Usage:
var response = await retryPolicy.ExecuteAsync(async () =>
{
    return await client.PostAsync(url, content);
});

6. Troubleshooting

Issue Solution
Regex doesn't match Check if page uses dynamic JS rendering. Use Playwright/Puppeteer to get final HTML.
API returns 402 Insufficient balance. Add funds via dashboard or check billing settings.
Slider doesn't move correctly Ensure you're clicking the correct button selector. Yandex may update their DOM structure.
Step number seems wrong Some captchas require step-1 adjustment. Test with known examples first.

Need Help?

If you're having trouble with a specific captcha implementation, contact our support team with the page URL and HTML snippet.

Contact Support