Invisible reCAPTCHA runs in the background without a visible checkbox. It triggers when a user interacts with the page (clicks a button, submits a form). For automation, invisible reCAPTCHA requires different handling than the visible checkbox version.
How Invisible reCAPTCHA Works
- The page loads with an invisible reCAPTCHA badge.
- When the user clicks submit, reCAPTCHA runs its challenge in the background.
- If the score is low, a visible challenge appears.
- The token is injected into
g-recaptcha-response.
Detecting Invisible reCAPTCHA
# Check for invisible reCAPTCHA
badge = page.query_selector(".grecaptcha-badge")
if badge:
print("Invisible reCAPTCHA detected")
sitekey = page.eval_on_selector(".grecaptcha-badge", "el => el.dataset.sitekey")
Solving with DeathByCaptcha
Invisible reCAPTCHA uses type=4:
import json
from playwright.sync_api import sync_playwright
import deathbycaptcha
client = deathbycaptcha.SocketClient(username, password)
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com/form")
sitekey = page.eval_on_selector(".grecaptcha-badge", "el => el.dataset.sitekey")
result = client.decode(type=4, token_params=json.dumps({
"googlekey": sitekey,
"pageurl": "https://example.com/form"
}))
print("Solution:", result["text"])
page.evaluate("document.querySelector(\"#g-recaptcha-response\").value=\"%s\"" % result["text"])
page.evaluate("typeof ___grecaptcha_cfg !== \"undefined\" && Object.keys(___grecaptcha_cfg.clients).forEach(function(key) { ___grecaptcha_cfg.clients[key].callback(\"%s\") })" % result["text"])
page.click("button[type=submit]")
browser.close()
Key Differences from Visible reCAPTCHA
- Type parameter: Use type=4 for invisible, type=4 for visible checkbox.
- No checkbox: There is no iframe checkbox to interact with.
- Badge detection: Look for
.grecaptcha-badgeinstead of the checkbox iframe. - Callback injection: Some sites require calling the reCAPTCHA callback function directly.
reCAPTCHA Enterprise
Enterprise invisible reCAPTCHA adds scoring. The solving process is the same, but the token includes enterprise-specific fields. Pass the enterprise flag in your API call:
result = client.decode(type=4, token_params=json.dumps({
"googlekey": sitekey,
"pageurl": page_url,
"enterprise": True
}))
Troubleshooting
- Token not working: Ensure you inject into the correct element. Invisible reCAPTCHA may use a hidden textarea.
- Callback errors: Some sites check if the callback was triggered programmatically. Use headed mode.
- Score too low: Enterprise reCAPTCHA may reject tokens with low scores. Increase timeout for better solving.
For API documentation, see the API reference and client libraries.

English
Spanish
Russian
Chinese
French
Hindi
Arabic
Bengali
Indonesian
Portuguese
com, 