reCAPTCHA v2 Enterprise fails for the same reasons as standard v2 — wrong sitekey, bad page URL, expired tokens — plus a few Enterprise-specific issues. The biggest Enterprise gotcha is misidentifying the implementation: using standard v2 parameters against an Enterprise widget, or vice versa. If you send method=userrecaptcha without the enterprise=1 flag for an Enterprise widget, the returned token will be rejected by the target site's backend.
This guide covers every common failure when solving reCAPTCHA v2 Enterprise through the CaptchaAI API. If you are not sure whether you are dealing with standard or Enterprise, read How to Identify reCAPTCHA Enterprise Implementation first.
How reCAPTCHA v2 Enterprise differs from standard
| Feature | Standard v2 | Enterprise v2 |
|---|---|---|
| Script URL | google.com/recaptcha/api.js |
google.com/recaptcha/enterprise.js |
| JS object | grecaptcha |
grecaptcha.enterprise |
| Verification endpoint | google.com/recaptcha/api/siteverify |
recaptchaenterprise.googleapis.com |
| CaptchaAI parameter | method=userrecaptcha |
method=userrecaptcha + enterprise=1 |
data-s parameter |
Never used | Sometimes present (additional token) |
Enterprise-specific errors
Sending standard parameters for an Enterprise widget
Symptom: The API returns a token, but the target site rejects it.
Cause: You submitted the task without enterprise=1. CaptchaAI solved it as standard v2, but the backend verifies against the Enterprise API — which rejects standard tokens.
Fix: Add enterprise=1 to your request:
import requests
response = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAFJR-JhNbC6CC42wKCbR9Hq_kVCd",
"pageurl": "https://example.com/login",
"enterprise": 1,
"json": 1
})
data = response.json()
task_id = data["request"]
const params = new URLSearchParams({
key: "YOUR_API_KEY",
method: "userrecaptcha",
googlekey: "6LcR_RsTAAAAAFJR-JhNbC6CC42wKCbR9Hq_kVCd",
pageurl: "https://example.com/login",
enterprise: 1,
json: 1,
});
const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const data = await res.json();
const taskId = data.request;
Missing data-s parameter
Symptom: ERROR_BAD_PARAMETERS or the token is rejected by the site.
Cause: Some Enterprise implementations include a data-s attribute on the reCAPTCHA div. This is an additional session token required for solving. If present, you must include it.
Fix: Check the page for data-s and include it if found:
# Look for: <div class="g-recaptcha" data-sitekey="..." data-s="..."></div>
response = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"enterprise": 1,
"data-s": data_s_value, # Include if present on the page
"json": 1
})
Wrong script identification
Symptom: Token works inconsistently or is always rejected.
Cause: You identified the widget as standard when it is Enterprise (or vice versa).
Fix: Check the script source in the page HTML:
// Enterprise uses enterprise.js
// <script src="https://www.google.com/recaptcha/enterprise.js?render=SITEKEY"></script>
// Standard uses api.js
// <script src="https://www.google.com/recaptcha/api.js"></script>
// Also check the JS object:
// Enterprise: grecaptcha.enterprise.render(...)
// Standard: grecaptcha.render(...)
General errors (shared with standard v2)
| Error Code | Cause | Fix |
|---|---|---|
ERROR_WRONG_USER_KEY |
Invalid API key format | Verify at captchaai.com/api.php |
ERROR_KEY_DOES_NOT_EXIST |
API key not found | Check for extra spaces or missing characters |
ERROR_ZERO_BALANCE |
No balance | Top up your account |
ERROR_PAGEURL |
Missing pageurl |
Add the full page URL |
ERROR_GOOGLEKEY |
Malformed sitekey | Re-extract from data-sitekey |
ERROR_BAD_TOKEN_OR_PAGEURL |
Sitekey/URL mismatch | Check iframe context |
CAPCHA_NOT_READY |
Still solving | Wait 5 seconds, poll again |
ERROR_CAPTCHA_UNSOLVABLE |
Cannot be solved | Submit a new task |
Complete solve flow with error handling
import requests
import time
def solve_recaptcha_v2_enterprise(api_key, sitekey, page_url, data_s=None):
params = {
"key": api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"enterprise": 1,
"json": 1
}
if data_s:
params["data-s"] = data_s
response = requests.get("https://ocr.captchaai.com/in.php", params=params)
data = response.json()
if data.get("status") != 1:
raise RuntimeError(f"Submit failed: {data.get('request')}")
task_id = data["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":
continue
raise RuntimeError(f"Solve failed: {result.get('request')}")
raise TimeoutError("Solve timed out after 200 seconds")
token = solve_recaptcha_v2_enterprise("YOUR_API_KEY", "SITEKEY", "https://example.com/login")
async function solveRecaptchaV2Enterprise(apiKey, sitekey, pageUrl, dataS) {
const params = new URLSearchParams({
key: apiKey, method: "userrecaptcha", googlekey: sitekey,
pageurl: pageUrl, enterprise: 1, json: 1,
});
if (dataS) params.set("data-s", dataS);
const submitRes = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const submitData = await submitRes.json();
if (submitData.status !== 1) throw new Error(`Submit failed: ${submitData.request}`);
const taskId = submitData.request;
for (let i = 0; i < 40; i++) {
await new Promise(r => setTimeout(r, 5000));
const res = await fetch(`https://ocr.captchaai.com/res.php?${new URLSearchParams({
key: apiKey, action: "get", id: taskId, json: 1,
})}`);
const data = await res.json();
if (data.status === 1) return data.request;
if (data.request === "CAPCHA_NOT_READY") continue;
throw new Error(`Solve failed: ${data.request}`);
}
throw new Error("Timed out after 200s");
}
FAQ
How do I know if a site uses reCAPTCHA Enterprise or standard?
Check the script tag in the HTML. Enterprise loads recaptcha/enterprise.js while standard loads recaptcha/api.js. The JavaScript object is also different: Enterprise uses grecaptcha.enterprise while standard uses grecaptcha.
Do I need to change my API call for Enterprise?
Yes. Add enterprise=1 to your CaptchaAI request. Without this flag, the token is generated for standard v2, which Enterprise backends reject.
What is the data-s parameter?
Some Enterprise implementations include a data-s attribute on the reCAPTCHA div. This is an additional session token. If present on the page, include it in your API request.
Why does my Enterprise token get rejected even with enterprise=1?
Check three things: (1) the sitekey is correct, (2) the data-s parameter is present on the page but missing from your request, or (3) the token expired before you submitted the form.
Can I use the same code for standard and Enterprise v2?
Yes — add enterprise=1 to switch. Everything else (method name, parameters, polling) stays the same.
Fix your Enterprise workflow
- Verify the implementation type — check for
enterprise.jsin the script tag - Add
enterprise=1to your CaptchaAI request - Check for
data-s— include it if the page has this attribute - Submit the token immediately — Enterprise tokens also expire after ~2 minutes
Get your API key at captchaai.com/api.php.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.