logo
bars

TenDI (Tencent) CAPTCHA
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 TenDI (Tencent), 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 TenDI (Tencent) 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 TenDI CAPTCHA
What is TenDI CAPTCHA
TenDI (Tencent) CAPTCHA is a multi-layer bot protection system. Using behavioral analysis and specialized mechanisms, it determines whether a website visitor is a real human. It is used to protect registrations, logins, marketing campaigns, prevent spam, and data theft.
Background
Examples of TenDI (Tencent)
Non-perception CAPTCHA
Non-perception CAPTCHA
Verification is performed automatically without user interaction. Ideal for scenarios where usability is critical.
Slider CAPTCHA
Slider CAPTCHA
Fast and simple verification by dragging a slider. Suitable for most use cases.
Graphic CAPTCHA
Graphic CAPTCHA
The user clicks sequentially on elements within an image. Used in high-security scenarios.
Audio CAPTCHA
Audio CAPTCHA
Verification via audio recording. Optimal for users with disabilities.
Smart Verification
Smart Verification
The system evaluates user behavior: trusted users pass immediately, suspicious ones are checked additionally.
Multi-dimensional Defense
Multi-dimensional Defense
Multiple protection mechanisms are used: dynamic encryption, anti-bot, and others.

How to solve Tencent CAPTCHA using CapMonster Cloud

When testing forms with Tencent CAPTCHA, it is often necessary to verify that the captcha works correctly and is properly integrated.
You can manually test the captcha integrated into 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 be submitted without errors.
For automatic captcha recognition, you can use specialized services such as CapMonster Cloud — a tool that accepts captcha parameters, processes them on its servers, and returns a ready-to-use token. This token can be injected into the form to pass verification without user interaction.

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
Solving TenDI (Tencent) CAPTCHA using ready-made libraries
CapMonster Cloud provides ready-to-use libraries for convenient integration in Python, JavaScript (Node.js), and C#.
Python
JavaScript
C#
Solving, token insertion, and form submission
A Node.js example demonstrating the full captcha-solving cycle on your webpage. Possible approaches include: using HTTP requests to fetch HTML and protection parameters, submitting the solution, and processing the response. Or, as shown below, using automation tools (e.g., Playwright) — opening the page, waiting for verification, sending parameters via the CapMonster Cloud client, receiving the result, injecting the token into the form (for testing, you may use both valid and invalid data), and observing the outcome.

// npx playwright install chromium

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

// Replace with your own values
const API_KEY = "YOUR_API_KEY";         
const WEBSITE_URL = "https://example.com";

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

    // 1. Open the page
    await page.goto(WEBSITE_URL, { waitUntil: 'networkidle' });

    // 2. Wait for the captcha to appear (e.g., input or iframe)
    await page.waitForSelector('#tendi_response, iframe[src*="tendi"], input[name="tendi_response"]', { timeout: 15000 });

    // If necessary, the websiteKey can be extracted directly from the page
    const WEBSITE_KEY = await page.evaluate(() => {
        // Example: the sitekey may be located in a data attribute or a global variable
        const el = document.querySelector('#tendi_response') || document.querySelector('div[data-sitekey]');
        return el?.getAttribute('data-sitekey') || window.TenDI_siteKey || "183268248";
    });

    console.log("Website key detected:", WEBSITE_KEY);

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

    // 3. Create a TenDI task
    const tenDIRequest = new TenDIRequest({
        websiteURL: page.url(),
        websiteKey: WEBSITE_KEY,
    });

    const balance = await client.getBalance();
    console.log("Balance:", balance);

    // 4. Solve the captcha
    const solution = await client.Solve(tenDIRequest);
    console.log("Solution:", solution);

    const { ticket, randstr } = solution.solution.data;

    // 5. Ways to inject the solution result
    await page.evaluate(({ ticket, randstr }) => {
        // Inject into an input field
        const inputSelectors = ['#tendi_response', 'input[name="tendi_response"]', 'input[type="hidden"]'];
        let inserted = false;
        for (const sel of inputSelectors) {
            const input = document.querySelector(sel);
            if (input) {
                input.value = ticket;
                input.dispatchEvent(new Event('input', { bubbles: true }));
                const form = input.closest('form');
                if (form) form.submit();
                inserted = true;
                break;
            }
        }

        // JavaScript callback function
        if (typeof window.onCaptchaSolved === 'function') {
            window.onCaptchaSolved(ticket, randstr);
            inserted = true;
        }

        // If there is no input and no callback
        if (!inserted) {
            window._tenDITicket = ticket;
            window._tenDIRandStr = randstr;
            console.log("Ticket and randstr saved to window._tenDITicket and window._tenDIRandStr");
        }
    }, { ticket, randstr });

    await page.waitForTimeout(5000);
    await browser.close();
}

solveTenDIOnPage().catch(console.error);
  
How to integrate TenDI (Tencent) CAPTCHA into your website
To confidently understand how captcha works on your website, grasp the verification logic, re-integrate or reconfigure it, we recommend reviewing this section. It describes the full integration process and helps you quickly understand all details.
  • 1. Log in to your account or create a new one in the Captcha Console.
  • 2. Open the Verification Management section.
  • 3. Create a new captcha (if it does not already exist).

You will receive two parameters: CaptchaAppId and AppSecretKey. These are used on the frontend and server side.

Frontend integration exampleFrontend integration example
arrow

How the integration works

Step 1: Load the captcha JavaScript

The script must be loaded dynamically:

<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>

If the script is loaded in a non-standard way or cached, the captcha may work incorrectly.

Step 2: Create a TencentCaptcha object

After the JavaScript is loaded, a global class becomes available:

<script src="new TencentCaptcha(domElement, CaptchaAppId, callback, options);"></script>

Parameters:

domElement - Container where the checkbox/iframe is embedded

CaptchaAppId - Your ID

callback - Action after verification

options - Appearance settings (optional)

Step 3: Call the method .show()

captcha.show();

Displays the captcha. Can be called multiple times.

Step 4: Process the result

The callback receives an object:


{
  ret: 0,              // 0 -- success, 2 -- user closed the window
  ticket: "...",       // required by the server
  randstr: "...",      // also required by the server
  errorCode: 1001,     // if the captcha failed to load
  errorMessage: "..."  // error message
}

On the server, a secondary verification of the ticket must always be performed.

"Disaster Recovery" mode

If the captcha fails to load (for example, if the CDN is unavailable), an emergency ticket can be issued automatically to avoid disrupting business processes.

Scenario:

  • Attempt to create a captcha → error.
  • Call loadErrorCallback().
  • Generate a ticket in the format:
    trerror_<errorcode>_<appid>_<timestamp>
  • Continue processing as usual, but the server recognizes it as an emergency ticket and decides how to handle it.

AppId encryption (optional)

If maximum protection is required, you can pass an encrypted AppId to the captcha instead of the plain one:

aidEncrypted = Base64(IV + AES256(AppId & timestamp & ttl))

Required:

  • 32-byte key (AppSecretKey → padded to 32 bytes)
  • AES-256 CBC + PKCS7Padding
  • 16-byte IV
  • timestamp and expiration time in seconds

Server-side encryption example (Python)


from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64

def encrypt(plaintext, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
    return base64.b64encode(iv + ciphertext).decode("utf-8")

Server-side validation

Step 1. Configure API access

In the key management panel (CAM / API Key Management), obtain SecretId and SecretKey for API access. These keys are required for signed API requests.

Step 2. Call the DescribeCaptchaResult API

After the client returns ticket and randstr, the server must send the following request:

  • Action: DescribeCaptchaResult
  • Version: 2019-07-22 (or the current version)

Parameters:

CaptchaType - 9 (fixed value)

Ticket - string — ticket returned from the client

Randstr - string — randstr returned from the client

CaptchaAppId - your AppId

AppSecretKey - your secret key

UserIp - user IP address (recommended)

Step 3. Process the response

The API returns:

  • CaptchaCode: integerthe verification result.
  • 0 (or OK) — captcha passed, ticket is valid

If CaptchaCode === OK, the user can be considered verified. Otherwise, reject the request.

Example — ticket verification in Node.js


import { v20190722 as captcha } from "@tencentcloud/tencentcloud-sdk-nodejs";
const client = new captcha.Client({
  credential: {
    secretId: "YOUR_SECRET_ID",
    secretKey: "YOUR_SECRET_KEY"
  },
  region: "ap-project", // region, if required
});

async function verifyCaptcha(ticket, randstr, userIp) {
  const params = {
    CaptchaType: 9,
    Ticket: ticket,
    Randstr: randstr,
    CaptchaAppId: YOUR_APP_ID,
    AppSecretKey: "YOUR_APP_SECRET_KEY",
    UserIp: userIp
  };

  const resp = await client.DescribeCaptchaResult(params);
  const code = resp.Response.CaptchaCode;
  return code === 0;
}
HelpIcon

You can find more detailed information about integrating Tencent CAPTCHA into your website in the official documentation.

Background
Possible errors and debugging
Bug Icon
Captcha does not load
(Errors 1001, 1002, or an invalid signature message) — the cause may be incorrect request parameters. Make sure that CaptchaAppId, AppSecretKey, and all request parameters are specified correctly.
Bug Icon
Invalid or empty ticket/randstr
Make sure the client correctly passes both parameters.
Bug Icon
Solution timeout
Increase the timeout on the server side.
Protection resilience checks
After integration, it is important to ensure that the protection actually works correctly.
Security and optimization tips
Store the <b>AppSecretKey</b> only on the server, never expose it to the browser or include it in JavaScript code.
Log full Tencent CAPTCHA responses, including error codes, request timing, and validation parameters — this will help diagnose issues faster.
Use HTTPS when transmitting all parameters <b>(ticket, randstr)</b> to prevent tampering.
Place correct links to the <b>Privacy Policy</b> and <b>Tencent Terms of Service</b> on the page, as required by the license.
Conclusion

If you’ve taken over a website that already has a captcha or another protection system installed, but you don’t have access to the code, don’t worry! It’s quite easy to identify which technology is being used. To verify that everything works correctly, you can use the CapMonster Cloud recognition service in an isolated test environment to make sure that the token processing mechanism and the validation logic are functioning properly.

In the case of TenDI (Tencent), it’s enough to detect the system, observe its behavior, and confirm that the protection is working correctly. In this article, we showed how to identify TenDI (Tencent) and where to find instructions on how to integrate or reconfigure it, so you can confidently maintain the protection and keep its operation under control.

Conclusion
Helpful links
DocIconTenDI (Tencent) CAPTCHA DocumentationDocIconCapMonster Cloud Documentation (working with Tencent CAPTCHA)DocIconWhat is Tencent Captcha (TenDI) and how to solve it?