TenDI (Tencent) CAPTCHA
and CapMonster Cloud

Captcha solving, website integration, and testing.

Pricing of TenDI (Tencent) solution

CAPTCHA
Price (USD)
$ 1.60
1000 tokens
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 <span class="font-bold">AppSecretKey</span> 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 <span class="font-bold">(ticket, randstr)</span> to prevent tampering.
Place correct links to the <span class="font-bold">Privacy Policy</span> and <span class="font-bold">Tencent Terms of Service</span> 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?

Frequently Asked Questions about TenDI (Tencent) CAPTCHA

TenDI offers several challenge types to match different risk levels and user experience needs.

  • Non-Perception — runs silently in the background for low-friction verification.
  • Slider — uses a drag-to-complete puzzle for standard visible checks.
  • Graphic — asks users to click specific shapes, making it suitable for higher-risk traffic.
  • Audio — provides an accessible alternative to visual challenges.
  • Smart Verification — lets trusted users pass silently and shows a challenge only for suspicious sessions.

TenDI also includes Multi-dimensional Defense, a set of 10 background protection mechanisms that improve bot resistance. For CapMonster Cloud, always use type: CustomTask and class: "TenDI" regardless of the challenge shown on the page. For more API details, please see here.

After your client returns a ticket and randstr, your server must validate them by calling Tencent's DescribeCaptchaResult API. To verify the ticket, send a signed API request with these parameters:

  • CaptchaType: 9
  • Ticket: the ticket returned by the client
  • Randstr: the randstr returned by the client
  • CaptchaAppId: your AppId
  • AppSecretKey: your captcha secret key
  • UserIp: the user's IP address (recommended)

Your server also needs Tencent Cloud API credentials (SecretId and SecretKey) to sign the request.

Check the CaptchaCode value in the response:

  • 0 or OK: the captcha passed, and the ticket is valid
  • any other value: verification failed, and the request should be rejected
  • Never expose AppSecretKey in frontend code.
  • Use Tencent's encrypted CaptchaAppId flow on the server side. Generate the encrypted value in your backend for sending it to the client.
  • After the CAPTCHA is solved, send ticket and randstr from the client to your backend to validate them through the DescribeCaptchaResult API.
  • Keep all secrets and verification logic on the backend.

For step-by-step setup, see How to integrate TenDI (Tencent) CAPTCHA into your website on this page above.

For the Tencent client-side integration flow, TenDI supports an optional aidEncrypted parameter that replaces the plain CaptchaAppId in the widget initialization.

aidEncrypted is generated as follows: aidEncrypted = Base64(IV + ciphertext)

ciphertext is the result of encrypting a string that contains your AppId, the current Unix timestamp, and the ttl (expiration time in seconds). Encryption uses AES-256-CBC with PKCS7 padding.

A random 16-byte IV is generated for each request, prepended to the encrypted output.

The final binary value is Base64-encoded before being passed to the widget as aidEncrypted.

If the Tencent CAPTCHA script fails to load or initialize, TenDI Disaster Recovery mode lets the user flow continue instead of blocking the request.

  • Call loadErrorCallback() when the CAPTCHA JavaScript cannot load or start, for example because of a network or CDN issue.
  • This creates a disaster-recovery ticket in the format trerror_<errorcode>_<CaptchaAppId>_<timestamp>.
  • The ticket is returned through the normal callback flow with ret: 0 (success).
  • On the server, do not treat ret: 0 as a normal success by itself. Also check the ticket prefix (trerror_) and the errorCode = 1001 to detect disaster-recovery mode.

To make this work reliably, define the error handler before loading the CAPTCHA script and call it when a JS load error occurs.