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.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.