Captcha bypass tutorials

Was this helpful?

How to bypass MTCaptcha

Narco Marco

Punisher in the IT cartel

Introduction

MTCaptcha is a modern anti-automation system used on many websites and mobile applications. Unlike classic text or image CAPTCHAs, MTCaptcha operates on a token-based mechanism: the widget analyzes user behavior in real-time, and upon successful verification, returns a cryptographic token mtcaptcha-verifiedtoken, which must be sent to the target website's server to confirm the legitimacy of the request.

In this guide, we will thoroughly explain how to automate MTCaptcha solving via API, what parameters are required, how to integrate the solution into Python scripts, and what to do if the standard token-based method doesn't work.


How MTCaptcha works

Characteristic Description
Verification Type Token-based (JavaScript widget)
Visual Element Text CAPTCHA, invisible verification, or adaptive challenge
Protection Mechanism Behavioral signal collection, fingerprint analysis, proof-of-work, Threat SPECT
Verification Result Generation of a one-time token mtcaptcha-verifiedtoken
Token Lifetime Minimum 50 seconds, typically up to 120 seconds

MTCaptcha offers several operating modes:

  • Modern Mini — compact widget for forms
  • Invisible Captcha — fully invisible verification for most users
  • Adaptive Complexity — dynamic difficulty increase when bot activity is suspected

Required parameters for task submission

For proper functionality, you must provide a minimal set of parameters. Depending on the task type selected, the structure may vary slightly.

Basic parameters (for all task types)

Property Type Required Description
type String Yes Task type: MtCaptchaTaskProxyless or MtCaptchaTask
websiteURL String Yes Full URL of the page where the CAPTCHA widget is displayed
websiteKey String Yes Public site key (SiteKey), extracted from the page source code

Proxy parameters (only for MtCaptchaTask)

Property Type Required Description
proxyType String Yes Protocol: http, https, or socks5
proxyAddress String Yes IP address or domain name of the proxy server
proxyPort Integer Yes Proxy server port
proxyLogin String No Login for authentication (if required)
proxyPassword String No Password for authentication (if required)

The MtCaptchaTaskProxyless type is recommended for websites without strict IP binding. The MtCaptchaTask type is required if the target resource validates that the IP address matches between the CAPTCHA request and form submission.


Step by Step Guide: API integration

Step 1. Extracting the websiteKey

  1. Open the target website in a browser and press F12 to open Developer Tools
  2. Navigate to the Elements (or Inspector) tab
  3. Locate the CAPTCHA container. It typically looks like this:
html Copy
<!-- MTCaptcha Anchor DOM -->
<div class="mtcaptcha" data-mtcaptcha-site-key="MTPublic-ExampleKey123"></div>

Or in the script configuration:

html Copy
<script>
var mtcaptchaConfig = {
  "sitekey": "MTPublic-ExampleKey123"
};
</script>
  1. Copy the sitekey value. This is your websiteKey.

If the key is not found in the markup, open the Network tab, reload the page, and filter requests by mtcaptcha. The sitekey is often passed in the script initialization parameters.

Step 2. Creating a task

Send a POST request to the task creation endpoint:
https://api.2captcha.com/createTask

Example request body (without proxy):

json Copy
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "MtCaptchaTaskProxyless",
    "websiteURL": "https://example.com/login",
    "websiteKey": "MTPublic-ExampleKey123"
  }
}

Example request body (with proxy):

json Copy
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "MtCaptchaTask",
    "websiteURL": "https://example.com/login",
    "websiteKey": "MTPublic-ExampleKey123",
    "proxyType": "http",
    "proxyAddress": "198.51.100.10",
    "proxyPort": 8080,
    "proxyLogin": "user",
    "proxyPassword": "secret"
  }
}

Step 3. Receiving the taskId

Upon successful task acceptance, the server will return:

json Copy
{
  "errorId": 0,
  "taskId": "a1b2c3d4e5f6g7h8i9j0"
}

Save the taskId for subsequent polling.

Step 4. Polling for results

Periodically send a POST request to:
https://api.2captcha.com/getTaskResult

Request body:

json Copy
{
  "clientKey": "YOUR_API_KEY",
  "taskId": "a1b2c3d4e5f6g7h8i9j0"
}

Successful response:

json Copy
{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "token": "v1(8f3a1c,7b2d9e,MTPublic-ExampleKey123,4a5b6c7d8e9f0...)"
  },
  "cost": "0.00299",
  "ip": "198.51.100.10",
  "createTime": 1714489200,
  "endTime": 1714489212
}

Step 5. Using the token in the target request

The received token must be submitted to the website in a hidden form field named mtcaptcha-verifiedtoken:

html Copy
<input type="hidden" name="mtcaptcha-verifiedtoken" value="v1(8f3a1c,7b2d9e,...)">

Or in the POST request body:

javascript Copy
fetch("https://example.com/api/verify", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: `mtcaptcha-verifiedtoken=v1(8f3a1c,7b2d9e,...)&username=test&password=123`
});

The token is single-use and has a short lifetime (minimum 50 seconds). Submit it to the target request immediately after receiving it.


Python code examples

Option 1: Pure Python (requests library)

python Copy
import requests
import time

API_KEY = "YOUR_API_KEY"
CREATE_URL = "https://api.2captcha.com/createTask"
RESULT_URL = "https://api.2captcha.com/getTaskResult"

def solve_mtcaptcha(url: str, sitekey: str, proxy: dict = None) -> str:
    task = {
        "clientKey": API_KEY,
        "task": {
            "type": "MtCaptchaTaskProxyless" if not proxy else "MtCaptchaTask",
            "websiteURL": url,
            "websiteKey": sitekey
        }
    }
    
    if proxy:
        task["task"].update({
            "proxyType": proxy.get("type", "http"),
            "proxyAddress": proxy["address"],
            "proxyPort": proxy["port"],
            "proxyLogin": proxy.get("login"),
            "proxyPassword": proxy.get("password")
        })

    # Create task
    resp = requests.post(CREATE_URL, json=task).json()
    if resp["errorId"] != 0:
        raise RuntimeError(f"Task creation error: {resp}")
        
    task_id = resp["taskId"]
    
    # Wait for solution
    for _ in range(24):  # up to 120 seconds
        time.sleep(5)
        res = requests.post(RESULT_URL, json={
            "clientKey": API_KEY,
            "taskId": task_id
        }).json()
        
        if res["status"] == "ready":
            return res["solution"]["token"]
        if res["errorId"] != 0:
            raise RuntimeError(f"Solution error: {res}")
            
    raise TimeoutError("Solution timeout exceeded")

# Usage example
token = solve_mtcaptcha(
    url="https://example.com/login",
    sitekey="MTPublic-ExampleKey123"
)
print(f"Ready token: {token}")

Option 2: Official Python Library

Installation: pip install 2captcha-python

python Copy
from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

# Solve without proxy
result = solver.mtcaptcha(
    websiteURL='https://example.com/login',
    websiteKey='MTPublic-ExampleKey123'
)
print(f"Token: {result['code']}")

# Solve with proxy
result = solver.mtcaptcha(
    websiteURL='https://example.com/login',
    websiteKey='MTPublic-ExampleKey123',
    proxyType='http',
    proxyAddress='198.51.100.10',
    proxyPort='8080',
    proxyLogin='user',
    proxyPassword='secret'
)
print(f"Token: {result['code']}")

Library source code: GitHub


Alternative method: when tokens don't work

In some configurations, the target website may reject tokens obtained via the standard API, or the widget may display a non-standard image/text challenge. If you cannot solve the CAPTCHA using tokens, you can use an alternative solving method: Normal CAPTCHA

When to use this method:

  • The website does not accept tokens obtained via API
  • MTCaptcha displays as a text image
  • You need to recognize a text CAPTCHA embedded in the widget

How it works:

  1. Use browser automation (Selenium, Playwright, Puppeteer) to capture a screenshot of the CAPTCHA area
  2. Encode the image to Base64
  3. Submit an ImageToTextTask type task
  4. Use the returned text as the answer in the corresponding form field

Example request:

json Copy
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type": "ImageToTextTask",
    "body": "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAA...",
    "phrase": false,
    "case": false,
    "numeric": 0
  }
}

Python example:

python Copy
import base64
from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

# From file
result = solver.normal('screenshot.png')
print(f"Answer: {result['code']}")

# From Base64 string
with open('screenshot.png', 'rb') as f:
    b64 = base64.b64encode(f.read()).decode()
result = solver.normal(b64)
print(f"Answer: {result['code']}")

This approach is useful for non-standard widget implementations, outdated protection versions, or situations where server-side validation expects exact text input.


Error handling and recommendations

Common error codes

Error Code Cause Solution
ERROR_WRONG_USER_KEY Invalid API key Verify the key in your account dashboard
ERROR_NO_SLOT_AVAILABLE No available workers Retry the request after 10–15 seconds
ERROR_CAPTCHA_UNSOLVABLE Current instance cannot be solved Refresh websiteKey, change proxy, or use alternative method
ERROR_BAD_PARAMETERS JSON structure error or missing fields Compare request with documentation
ERROR_ZERO_BALANCE Insufficient funds Top up your account balance

Practical tips for stability

Synchronize request context
MTCaptcha may bind the token to User-Agent, headers, and IP. Send the target request with the same parameters used when creating the task.

Respect timing constraints
Tokens are valid for at least 50 seconds, typically up to 120 seconds. Do not add delays between receiving the solution and submitting the form.

Handle dynamic sitekeys
On some websites, the key is generated on each page load. Always parse the fresh page version before creating a task.

Implement retries
Network errors and temporary service load are normal. Add 2–3 retry attempts with exponential backoff.

Emulate human behavior
Even with a valid token, the website may reject requests suspected of being bot-driven. Use realistic headers, random pauses between actions, and avoid sending batch requests without parameter rotation.



Conclusion

Automated MTCaptcha solving boils down to correctly extracting the websiteKey, submitting the task to the API, and quickly inserting the received token into the mtcaptcha-verifiedtoken field. The key success factor is maintaining context: the token must be used under the same conditions in which it was generated.

If the standard token-based method fails validation, switch to image recognition via the ImageToTextTask method. This is a reliable fallback option for complex or non-standard protection implementations.

Start integration with test pages, log server responses, and implement retry mechanisms—this will ensure stable automation performance even when protection logic changes.