logo
bars

CAPTCHA with Images (ComplexImage)
and CapMonster Cloud

Captcha solving, website integration, and testing.
Inherited a site with a captcha or another protection layer but no access to the source code? In that case you naturally ask: which solution is installed, is it configured correctly, and how can the workflow be tested?

In this article, we have tried to answer all the key questions. The first step in solving the task is to determine which protection system is being used. To do this, you can refer to the list of popular captchas and anti-bot protection systems, where you will find visual examples and key indicators that help you quickly understand what you are dealing with.

If you discover that your site uses ComplexImage, the next step is to study its properties and operation in more detail. In this article, you can also review the instructions on how to integrate ComplexImage so that you fully understand how it functions on your site. This will help you not only understand the current protection, but also properly plan its maintenance.

What is an image CAPTCHA
What is an image CAPTCHA
An image CAPTCHA is a type of visual CAPTCHA where the user needs to perform a task related to image analysis. Typically, the system asks the user to select images that meet a certain condition, count objects, identify the correct position of an item, or perform another visual action. Unlike text-based CAPTCHAs, where users only enter characters from an image, image CAPTCHAs test the ability to interpret visual information and perform logical actions. This makes them harder to automatically recognize and more effective at protecting registration, login, and other critical forms from bots.

How to solve image CAPTCHA using CapMonster Cloud

When testing forms with Tencent CAPTCHA, it is often necessary to check the CAPTCHA functionality and ensure it is correctly integrated.
You can manually test the CAPTCHA implemented on your website:
  • Open the page with the form and make sure the CAPTCHA is displayed.
  • Try submitting the form without solving the CAPTCHA — the server should return an error.
  • After successfully solving the CAPTCHA, the form should submit without errors.
For automatic CAPTCHA solving, you can use specialized services such as CapMonster Cloud — a tool that receives CAPTCHA parameters, processes them on its servers, and returns a ready solution — e.g., numbers or click coordinates that can be used to pass verification without user involvement.

Working with CapMonster Cloud via API typically involves the following steps:

Creating a taskCreating a task
arrow
Sending an API requestSending an API request
arrow
Receiving the resultReceiving the result
arrow
Placing the token on the pagePlacing the token on the page
arrow
Image CAPTCHA recognition using ready-made libraries
CapMonster Cloud provides ready-made libraries for easy usage in Python, JavaScript (Node.js), and C#.
Python
JavaScript
C#
Insert solution and submit form
Node.js example for a complete cycle of CAPTCHA recognition on your webpage. Possible approaches: use HTTP requests to retrieve HTML and protection parameters, send the solution, and process the result. Or, as in the example, use automation tools (like Playwright) — open the page, wait for the check, submit parameters via CapMonster Cloud client, receive the result, insert it into the proper field (for testing you can use correct or incorrect data) and observe the outcome.

// npm install playwright @zennolab_com/capmonstercloud-client
// npx playwright install chromium

import { chromium } from 'playwright';
import { CapMonsterCloudClientFactory, ClientOptions, ComplexImageTaskRecognitionRequest } from '@zennolab_com/capmonstercloud-client';

const API_KEY = "YOUR_API_KEY";
const TARGET_URL = "https://example.com/captcha-page";

async function solveComplexImageTaskPlaywright() {
    const browser = await chromium.launch({ headless: false });
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto(TARGET_URL);

    // Find the CAPTCHA image
    const captchaHandle = await page.$('#captcha'); // replace with the real selector
    const captchaBase64 = await captchaHandle.evaluate(img => {
        const canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
        return canvas.toDataURL('image/png').split(',')[1];
    });

    console.log("Captcha base64:", captchaBase64.substring(0, 50) + "...");

    const cmcClient = CapMonsterCloudClientFactory.Create(
        new ClientOptions({ clientKey: API_KEY })
    );

    // Send CAPTCHA for recognition
    const citRecognitionRequest = new ComplexImageTaskRecognitionRequest({
        imagesBase64: [captchaBase64],
        metaData: { Task: 'oocl_rotate' } // replace with your CAPTCHA type
    });

    const result = await cmcClient.Solve(citRecognitionRequest);
    console.log("Solution received:", result);

    // Process the solution
    const solution = result.solution;

    if (!solution) {
        console.error("No solution received");
        return;
    }

    if (solution.metadata?.AnswerType === "Coordinate") {
        // CAPTCHA with coordinates
        const box = await captchaHandle.boundingBox();
        for (const point of solution.answer) {
            const clickX = box.x + point.X;
            const clickY = box.y + point.Y;
            console.log(`Clicking at: (${clickX}, ${clickY})`);
            await page.mouse.click(clickX, clickY);
        }
    } else if (solution.metadata?.AnswerType === "Grid") {
        // Grid CAPTCHA (true/false array)
        const box = await captchaHandle.boundingBox();
        const gridItems = await page.$$('#captcha_grid div'); // replace with grid element selectors
        const answers = solution.answer;

        for (let i = 0; i < answers.length; i++) {
            if (answers[i] && gridItems[i]) {
                const itemBox = await gridItems[i].boundingBox();
                const clickX = itemBox.x + itemBox.width / 2;
                const clickY = itemBox.y + itemBox.height / 2;
                console.log(`Clicking grid item ${i} at: (${clickX}, ${clickY})`);
                await page.mouse.click(clickX, clickY);
            }
        }
    } else {
        console.warn("Unknown captcha solution type:", solution.metadata?.AnswerType);
    }

    // Click confirmation button (if any)
    await page.click('#submit_button'); // replace with the real button selector

    console.log("Captcha solved.");
}

solveComplexImageTaskPlaywright().catch(console.error);
  
How to integrate image CAPTCHA into your website
To understand how CAPTCHA works on your site, check its logic, or reconfigure it, we recommend this section. It describes the general process of protection integration — this helps quickly grasp all the nuances.

1. Generate CAPTCHA on the server.

  • A CAPTCHA image is created: single image or image grid.
  • Noise, distortions, and random elements are added to prevent bots.
  • A unique captchaId is generated and the correct solution is stored (in memory, database, or cache).

2. Send CAPTCHA to client

  • Server sends captchaId and image (Base64 or URL) to client.
  • Client displays the CAPTCHA, e.g., with <img> or grid <div> with instructions.
Example client part (HTML + JS)Example client part (HTML + JS)
arrow

3. User enters the answer

  • User enters text, clicks on images, or rotates objects.
  • Client formats the answer in the proper structure:
    • Text CAPTCHA → string
    • Grid → true/false array
    • Coordinates → array of {X, Y}

4. Submit answer to server:

  • Client sends POST request with captchaId and answer.
  • Optionally, session token can be sent to prevent repeated solving.

5. Server validation

  • Server looks up CAPTCHA session by captchaId.
  • Compares user answer with correct solution.
  • Returns success: true/false.
  • If failed, CAPTCHA can be refreshed.
Server-side exampleServer-side example
arrow

6. Next steps

  • Successful CAPTCHA → protected process (form, registration, etc.) is allowed.
  • Failed CAPTCHA → issue a new one, optionally limit attempts.

Additionally

  • Use TTL (time-to-live) for CAPTCHA sessions to expire automatically.
  • Cache images and use temporary URLs to save resources.
  • Ensure correct click and touch behavior on mobile devices.
  • Log and analyze to improve UX and bot protection.
Background
Possible errors and debugging
Bug Icon
Image CAPTCHA does not load
(Empty grid, broken images, 404/500 errors, base64 issues) — check that the server correctly generates images, the base64 data is not corrupted, the image format is supported by the browser, and the client receives a valid captchaId.
Bug Icon
User clicks are not processed
(Cells are not highlighted or the response is empty) — make sure click coordinates or indices are sent to the server, the data is properly serialized, and touch events are supported on mobile devices.
Bug Icon
Captcha fails despite correct clicks
Verify that the captcha is not regenerated before validation, the correct answer is stored separately per session, the response format matches the expected one, and the captcha TTL has not expired.
Bug Icon
CAPTCHA expired
If the user takes too long, increase TTL, refresh CAPTCHA on retry, and notify user to reload images.
Protection resilience checks
After integration, make sure the system really protects the site from automated actions.
Security and optimization tips
Store the correct CAPTCHA answer <b>only on the server</b> (memory, Redis, or database), never on the client.
Use one-time CAPTCHA IDs (<b>captchaId</b>).
Limit the number of attempts per CAPTCHA.
Always use <b>HTTPS</b> for transmitting images and clicks.
Cache images and use <b>temporary URLs</b> if possible.
Log generation and verification errors (time, IP/fingerprint, reason for failure).
Regularly update CAPTCHA mechanics (image sets, grid size/structure, task types).
Conclusion

If you encounter a site with an already installed CAPTCHA or another protection system and have no access to the code — don’t worry! It is easy to identify which technology is used. To verify functionality, you can use CapMonster Cloud in an isolated test environment to ensure token processing and logic work correctly.

For image CAPTCHAs — it’s enough to identify the system, study its behavior, and make sure protection works. This article showed how to recognize ComplexImage image CAPTCHA and how to integrate or reconfigure it to reliably maintain protection and control its operation.

Conclusion
Helpful links
DocIconCapMonster Cloud Documentation (ComplexImage)DocIconGuide to creating your own CAPTCHADocIconRegister with CapMonster Cloud service