API Tutorials

How to Solve reCAPTCHA Invisible Using API

Invisible reCAPTCHA fires when a user clicks a button or submits a form — there is no checkbox. The challenge happens in the background, and the page continues only when the token is verified. Solving it through CaptchaAI is similar to standard v2, with one key addition: you must pass invisible=1 in your API request.

The biggest difference in integration is how you inject the token. Most invisible implementations use a callback function instead of the hidden g-recaptcha-response field. You need to find and call that callback.

Not sure if it is invisible or standard v2? Read reCAPTCHA v2 vs Invisible Explained for detection tips.


What you need

Requirement Details
CaptchaAI API key captchaai.com/api.php
Sitekey From data-sitekey on the widget or button
Page URL Full URL where the invisible CAPTCHA runs
Browser tool Selenium/Puppeteer to execute the callback

Step 1: Detect invisible reCAPTCHA

Look for these patterns in the page HTML:

<!-- Option 1: div with data-size="invisible" -->
<div class="g-recaptcha" data-sitekey="6LdKlZEU..." data-size="invisible" data-callback="onSubmit"></div>

<!-- Option 2: button with data-sitekey (invisible by default) -->
<button data-sitekey="6LdKlZEU..." data-callback="onSubmit">Submit</button>

<!-- Option 3: programmatic execution -->
<script>
  grecaptcha.execute('6LdKlZEU...', {action: 'submit'});
</script>

If you see data-size="invisible", a button with data-sitekey, or grecaptcha.execute() without a container, it is invisible reCAPTCHA.

Step 2: Submit to CaptchaAI

import requests

response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": "6LdKlZEUAAAAAPoxm...",
    "pageurl": "https://example.com/signup",
    "invisible": 1,
    "json": 1
})

task_id = response.json()["request"]
const params = new URLSearchParams({
  key: "YOUR_API_KEY", method: "userrecaptcha",
  googlekey: "6LdKlZEUAAAAAPoxm...",
  pageurl: "https://example.com/signup",
  invisible: 1, json: 1,
});
const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const { request: taskId } = await res.json();

Step 3: Poll for the result

import time

for _ in range(40):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        token = result["request"]
        break
    if result.get("request") != "CAPCHA_NOT_READY":
        raise RuntimeError(f"Error: {result['request']}")

Step 4: Inject the token via callback

This is the critical step. Invisible reCAPTCHA expects a callback function, not just a hidden field value:

# Selenium example
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com/signup")

# Find the callback name
callback = driver.execute_script("""
    var el = document.querySelector('[data-callback]');
    if (el) return el.getAttribute('data-callback');
    var btn = document.querySelector('[data-sitekey]');
    if (btn) return btn.getAttribute('data-callback');
    return null;
""")

# Execute the callback with the token
if callback:
    driver.execute_script(f"window['{callback}']('{token}');")
else:
    # Fallback: fill hidden field and submit
    driver.execute_script(f"""
        document.getElementById('g-recaptcha-response').innerHTML = '{token}';
        document.querySelector('form').submit();
    """)
// Puppeteer example
await page.evaluate((token) => {
  const el = document.querySelector('[data-callback]') || document.querySelector('[data-sitekey]');
  const callbackName = el?.getAttribute('data-callback');

  if (callbackName && window[callbackName]) {
    window[callbackName](token);
  } else {
    document.getElementById('g-recaptcha-response').innerHTML = token;
    document.querySelector('form').submit();
  }
}, token);

Complete working function

import requests
import time

def solve_invisible_recaptcha(api_key, sitekey, page_url):
    submit = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": api_key, "method": "userrecaptcha", "googlekey": sitekey,
        "pageurl": page_url, "invisible": 1, "json": 1
    }).json()

    if submit.get("status") != 1:
        raise RuntimeError(f"Submit error: {submit.get('request')}")

    task_id = submit["request"]

    for _ in range(40):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1
        }).json()
        if result.get("status") == 1:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise RuntimeError(f"Solve error: {result.get('request')}")

    raise TimeoutError("Timed out")

token = solve_invisible_recaptcha("YOUR_API_KEY", "6LdKlZEU...", "https://example.com/signup")

FAQ

How do I know if reCAPTCHA is invisible?

Look for data-size="invisible" on the widget div or a button with data-sitekey. If there is no visible checkbox, it is likely invisible.

Do I need invisible=1 for invisible reCAPTCHA?

Yes. Without it, CaptchaAI treats the task as standard v2 and the token may be rejected.

What if I cannot find the callback function?

Try filling the g-recaptcha-response hidden field and submitting the form. Some invisible implementations fall back to this method. If that fails, search the page JavaScript for functions that handle reCAPTCHA responses.

Can invisible reCAPTCHA be Enterprise?

Yes. Add both invisible=1 and enterprise=1 to your request.

Why does the page not respond after callback execution?

The callback name may be wrong, or the page may expect additional form fields. Verify the exact callback name and ensure all required form fields are filled before the callback fires.


Start solving invisible reCAPTCHA

Get your API key at captchaai.com/api.php. Add invisible=1 to your v2 solve code and use the callback injection pattern above.


Full Working Code

Complete runnable examples for this article in Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin & Bash.

View on GitHub →

Discussions (0)

No comments yet.