Logo of «2Captcha»To home page
Captcha bypass tutorials

Was this helpful?

How to bypass MTCaptcha on Checkinhoudingsplicht

Gregory Fisher
Gregory Fisher

Technical engineer

The Checkinhoudingsplicht website (checkinhoudingsplicht.be) is an official Belgian government portal designed for employers. It is used to verify and confirm compliance with the duty to check the residence status of foreign workers (known as the houdingsplicht). To protect its forms from automation and bots, the site uses the MTCaptcha system.

This captcha is an interactive widget that evaluates user behavior. For a successful solution via API v2, you need to extract the public site key (sitekey) and pass it along with the full page URL. In this guide, we will break down how to find these parameters, send the task, and correctly inject the received token.

Task Parameters (API v2)

To send a task via the modern API v2, the createTask endpoint is used. The task object must contain the following parameters:

Parameter Type Required Description
type String Yes Task type: MTCaptchaTaskProxyless or MTCaptchaTask
websiteURL String Yes Full URL of the page where the captcha is located
websiteKey String Yes MTCaptcha public site key (starts with MTPublic-)

How to find parameters

Parameters for MTCaptcha are static for a specific page and can be easily extracted from the source code.

  1. Open the website https://www.checkinhoudingsplicht.be/ in your browser.
  2. Press F12 to open Developer Tools (DevTools) and go to the Elements tab.
  3. Press Ctrl+F (or Cmd+F) and search for mt-captcha or data-sitekey.
  4. You will find a div element similar to this:
  5. The value of the data-sitekey attribute (in this example, MTPublic-QPs1BHRjl) is your websiteKey.
  6. Copy the full URL from the browser's address bar. This will be your websiteURL.

Code Examples

Python + requests (API v2)

Example of sending a task and polling for the result using the requests library via API v2 endpoints.

python Copy
import requests
import time

API_KEY = 'YOUR_API_KEY'
WEBSITE_URL = 'https://www.checkinhoudingsplicht.be/'
WEBSITE_KEY = 'MTPublic-QPs1BHRjl'

# 1. Create task via API v2
url = 'https://api.2captcha.com/createTask'
headers = {
    'Content-Type': 'application/json'
}
payload = {
    "clientKey": API_KEY,
    "task": {
        "type": "MTCaptchaTaskProxyless",
        "websiteURL": WEBSITE_URL,
        "websiteKey": WEBSITE_KEY
    }
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result.get('errorId') == 0:
    task_id = result.get('taskId')
    print(f"Task created, ID: {task_id}")
    
    # 2. Get result via API v2
    res_url = 'https://api.2captcha.com/getTaskResult'
    while True:
        time.sleep(5) # Pause between requests
        
        res_payload = {
            "clientKey": API_KEY,
            "taskId": task_id
        }
        
        res_response = requests.post(res_url, headers=headers, json=res_payload).json()
        
        if res_response.get('errorId') == 0 and res_response.get('status') == 'ready':
            print("Captcha solved successfully!")
            token = res_response['solution']['token']
            print(f"Token: {token}")
            break
        elif res_response.get('errorId') != 0:
            print(f"Error: {res_response.get('errorDescription')}")
            break
        else:
            # Status processing - task is not ready yet
            continue
else:
    print(f"Task creation error: {result.get('errorDescription')}")

Python + Playwright

Example of automation that dynamically extracts the sitekey from the page, sends the task via API v2, and injects the token.

python Copy
from playwright.sync_api import sync_playwright
import requests
import time

API_KEY = 'YOUR_API_KEY'
TARGET_URL = 'https://www.checkinhoudingsplicht.be/'

def solve_mtcaptcha():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        try:
            page.goto(TARGET_URL)
            
            # Wait for the MTCaptcha widget to appear
            page.wait_for_selector('.mt-captcha', timeout=10000)
            
            # Extract sitekey from the data-sitekey attribute
            site_key = page.evaluate("""
                () => {
                    const captchaDiv = document.querySelector('.mt-captcha');
                    return captchaDiv ? captchaDiv.getAttribute('data-sitekey') : null;
                }
            """)
            
            if not site_key:
                raise Exception("Failed to find MTCaptcha sitekey on the page.")
            
            print(f"Found sitekey: {site_key}")
            
            # Send to API v2
            api_url = 'https://api.2captcha.com/createTask'
            headers = {'Content-Type': 'application/json'}
            payload = {
                "clientKey": API_KEY,
                "task": {
                    "type": "MTCaptchaTaskProxyless",
                    "websiteURL": page.url,
                    "websiteKey": site_key
                }
            }
            
            task_response = requests.post(api_url, headers=headers, json=payload).json()
            if task_response.get('errorId') != 0:
                raise Exception(f"Task creation error: {task_response.get('errorDescription')}")
                
            task_id = task_response.get('taskId')
            
            # Waiting for the solution via getTaskResult
            res_url = 'https://api.2captcha.com/getTaskResult'
            token = None
            for _ in range(20):
                time.sleep(5)
                res = requests.post(res_url, headers=headers, json={"clientKey": API_KEY, "taskId": task_id}).json()
                if res.get('status') == 'ready':
                    token = res['solution']['token']
                    break
                if res.get('errorId') != 0:
                    print(f"API error: {res.get('errorDescription')}")
                    break
                    
            if token:
                print(f"Token received: {token}")
                
                # Injecting the token into the form
                # MTCaptcha usually expects the token in a hidden field named mt-captcha-response
                page.evaluate(f"""
                    let input = document.querySelector('input[name="mt-captcha-response"]');
                    if (!input) {{
                        input = document.createElement('input');
                        input.type = 'hidden';
                        input.name = 'mt-captcha-response';
                        document.querySelector('form')?.appendChild(input);
                    }}
                    input.value = "{token}";
                    
                    // Sometimes a callback needs to be triggered if defined
                    if (typeof window.mtCaptchaVerified === 'function') {{
                        window.mtCaptchaVerified("{token}");
                    }}
                """)
                print("Token injected into DOM.")
            else:
                print("Failed to get token.")
                
        except Exception as e:
            print(f"Error: {e}")
        finally:
            # browser.close()

if __name__ == '__main__':
    solve_mtcaptcha()

Alternative Solving Method

In some cases, if the standard MTCaptcha method encounters difficulties or specific protections, you can try an alternative solution using our Normal Captcha method.

If the MTCaptcha widget displays a classic text or character image to be typed, you can take a screenshot of this element using Playwright or Selenium and send it for recognition as a normal captcha. After receiving the text response, you can type it into the captcha input field using keyboard emulation.

Normal Captcha method documentation: https://2captcha.com/api-docs/normal-captcha

Common Errors and Solutions

Error / Problem Cause Solution
ERROR_WRONG_USER_KEY Invalid or empty API key. Check that the key is copied correctly from the dashboard.
ERROR_ZERO_BALANCE Insufficient funds in the account. Top up your account balance.
ERROR_CAPTCHA_UNSOLVABLE The captcha cannot be solved (e.g., expired or incorrect parameters). Ensure that the websiteKey and websiteURL are copied exactly. Do not use outdated values.
Token not accepted by the form Incorrect field name for injection or missing callback trigger. Check the page source code. Make sure you are injecting the token into the mt-captcha-response field and triggering the verification function if necessary.