reCAPTCHA v2 Enterprise adds enterprise-grade risk scoring to the standard "I'm not a robot" checkbox. The widget looks the same as standard v2, but tokens are verified through Google's Enterprise backend with stricter validation. To solve it with CaptchaAI, add enterprise=1 to your v2 request.
This guide covers the complete Node.js implementation — detecting Enterprise v2, submitting to CaptchaAI, polling for the result, and injecting the token.
What you need
| Requirement | Details |
|---|---|
| CaptchaAI API key | captchaai.com |
| Node.js 14+ | With built-in fetch or node-fetch |
| Sitekey | From the Enterprise anchor URL (k= parameter) |
| Page URL | Full URL where the CAPTCHA appears |
| Action (optional) | From the sa= parameter in the anchor URL |
Step 1: Identify reCAPTCHA v2 Enterprise
Open DevTools and look for the Enterprise anchor request in the Network tab:
https://www.google.com/recaptcha/enterprise/anchor?ar=1&k=6LdxxXXxAAAAAAcX...&sa=LOGIN&...
Key indicators:
- Script source includes
/recaptcha/enterprise.jsor/enterprise/anchor - The
k=parameter is the sitekey - The
sa=parameter (if present) is the action
Standard v2 uses /recaptcha/api2/anchor — do not add enterprise=1 for standard v2.
Step 2: Submit the task to CaptchaAI
const API_KEY = "YOUR_API_KEY";
async function submitTask(sitekey, pageurl, action) {
const params = new URLSearchParams({
key: API_KEY,
method: "userrecaptcha",
googlekey: sitekey,
pageurl: pageurl,
enterprise: "1",
json: "1",
});
if (action) {
params.set("action", action);
}
const response = await fetch(
`https://ocr.captchaai.com/in.php?${params}`
);
const data = await response.json();
if (data.status !== 1) {
throw new Error(`Submit failed: ${data.request}`);
}
console.log(`Task submitted. ID: ${data.request}`);
return data.request;
}
Step 3: Poll for the result
Wait 20 seconds before the first poll, then check every 5 seconds:
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function pollResult(taskId) {
await delay(20000);
for (let attempt = 0; attempt < 30; attempt++) {
const params = new URLSearchParams({
key: API_KEY,
action: "get",
id: taskId,
json: "1",
});
const response = await fetch(
`https://ocr.captchaai.com/res.php?${params}`
);
const data = await response.json();
if (data.status === 1) {
console.log(`Solved. Token: ${data.request.substring(0, 60)}...`);
return {
token: data.request,
userAgent: data.user_agent || "",
};
}
if (data.request !== "CAPCHA_NOT_READY") {
throw new Error(`Solve failed: ${data.request}`);
}
console.log(`Attempt ${attempt + 1}: not ready, waiting 5s...`);
await delay(5000);
}
throw new Error("Solve timed out");
}
Step 4: Inject the token
Submit the solved token as g-recaptcha-response. If the API returned a user_agent, use it in your request headers:
async function submitForm(token, userAgent) {
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
if (userAgent) {
headers["User-Agent"] = userAgent;
}
const response = await fetch("https://example.com/api/login", {
method: "POST",
headers,
body: new URLSearchParams({
username: "user",
password: "pass",
"g-recaptcha-response": token,
}),
});
console.log(`Response status: ${response.status}`);
return response;
}
Complete working script
const API_KEY = "YOUR_API_KEY";
const SITE_KEY = "6LdxxXXxAAAAAAcXxxXxxX91xxxxxxxx8xxOx7A";
const PAGE_URL = "https://example.com/login";
const ACTION = "LOGIN"; // optional — omit if not in anchor URL
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function solveRecaptchaV2Enterprise() {
// Submit task
const submitParams = new URLSearchParams({
key: API_KEY,
method: "userrecaptcha",
googlekey: SITE_KEY,
pageurl: PAGE_URL,
enterprise: "1",
action: ACTION,
json: "1",
});
const submitRes = await fetch(
`https://ocr.captchaai.com/in.php?${submitParams}`
);
const submitData = await submitRes.json();
if (submitData.status !== 1) {
throw new Error(`Submit error: ${submitData.request}`);
}
const taskId = submitData.request;
console.log(`Task ID: ${taskId}`);
// Poll for result
await delay(20000);
for (let i = 0; i < 30; i++) {
const pollParams = new URLSearchParams({
key: API_KEY,
action: "get",
id: taskId,
json: "1",
});
const pollRes = await fetch(
`https://ocr.captchaai.com/res.php?${pollParams}`
);
const pollData = await pollRes.json();
if (pollData.status === 1) {
return {
token: pollData.request,
userAgent: pollData.user_agent || "",
};
}
if (pollData.request !== "CAPCHA_NOT_READY") {
throw new Error(`Solve error: ${pollData.request}`);
}
await delay(5000);
}
throw new Error("Solve timed out");
}
(async () => {
const { token, userAgent } = await solveRecaptchaV2Enterprise();
console.log(`Token: ${token.substring(0, 60)}...`);
if (userAgent) console.log(`User-Agent: ${userAgent}`);
})();
Expected output:
Task ID: 73849562810
Token: 03AGdBq24PBCqLmOx2V4pGHJjkR2xZ1r...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
ERROR_WRONG_USER_KEY |
Invalid API key format | Check key is 32 characters from your dashboard |
ERROR_KEY_DOES_NOT_EXIST |
Key not found | Verify key at captchaai.com |
ERROR_ZERO_BALANCE |
Insufficient balance | Top up your account |
ERROR_BAD_TOKEN_OR_PAGEURL |
Wrong sitekey or URL | Extract correct k= value from the Enterprise anchor URL |
ERROR_CAPTCHA_UNSOLVABLE |
Could not solve | Verify sitekey is Enterprise v2, retry |
| Token rejected by site | User-Agent mismatch | Use user_agent from the solve response |
FAQ
How do I detect Enterprise v2 vs standard v2?
Enterprise v2 loads from /recaptcha/enterprise/ in the script or anchor URL. Standard v2 uses /recaptcha/api2/.
Is the action parameter required?
Only if the anchor URL includes sa=. If absent, omit it from your CaptchaAI request.
Why does the target site reject my token?
Most commonly: User-Agent mismatch. Enterprise v2 tokens are bound to the solver's User-Agent. Always use the user_agent value returned in the poll response.
Can I use this with Puppeteer or Playwright?
Yes. Extract the sitekey from the page, solve via the API, then inject the token into document.getElementById('g-recaptcha-response').innerHTML.
What is the typical solve time?
15–30 seconds depending on server load.
Start solving reCAPTCHA v2 Enterprise
Get your API key at captchaai.com and add enterprise=1 to your v2 requests.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.