Quem escolhe entre reCAPTCHA v2 padrão e Enterprise é o site, não a sua integração. Do seu lado a diferença cabe em um parâmetro — enterprise=1 — e quase toda falha vem de detectar a versão errada, não de resolver o desafio.
- Na página: a padrão carrega
api.js; a Enterprise,enterprise.js. - Na API: mesmo
method=userrecaptcha, mesma sitekey (chave pública do widget), mesmog-recaptcha-response. - No desafio: idêntico — caixa "Não sou um robô" e grades 3×3 ou 4×4.
- No custo: nada muda; a cobrança é por thread simultânea (BASIC, US$ 15/mês, 5 threads).
Como saber se a página usa reCAPTCHA v2 ou Enterprise
A checagem decisiva leva dois segundos: veja qual arquivo do Google entra no HTML.
<!-- Standard v2 -->
<script src="https://www.google.com/recaptcha/api.js"></script>
<!-- Enterprise v2 -->
<script src="https://www.google.com/recaptcha/enterprise.js"></script>
Em varreduras de QA, automatize a checagem — versão e sitekey na mesma passada:
import requests
from bs4 import BeautifulSoup
def detect_recaptcha_version(url):
resp = requests.get(url)
soup = BeautifulSoup(resp.text, "html.parser")
enterprise_script = soup.find("script", src=lambda s: s and "enterprise.js" in s)
standard_script = soup.find("script", src=lambda s: s and "recaptcha/api.js" in s)
widget = soup.find(class_="g-recaptcha")
sitekey = widget["data-sitekey"] if widget else None
if enterprise_script:
return {"version": "enterprise_v2", "sitekey": sitekey}
elif standard_script:
return {"version": "standard_v2", "sitekey": sitekey}
return None
info = detect_recaptcha_version("https://staging.example.com/qa-login")
print(info)
A mesma checagem em Node.js, com axios e cheerio:
const axios = require("axios");
const cheerio = require("cheerio");
async function detectRecaptchaVersion(url) {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const hasEnterprise = $('script[src*="enterprise.js"]').length > 0;
const hasStandard = $('script[src*="recaptcha/api.js"]').length > 0;
const sitekey = $(".g-recaptcha").attr("data-sitekey");
if (hasEnterprise) return { version: "enterprise_v2", sitekey };
if (hasStandard) return { version: "standard_v2", sitekey };
return null;
}
No DevTools, para conferir uma página à mão:
// Quick check in DevTools
if (document.querySelector('script[src*="enterprise.js"]')) {
console.log("Enterprise v2");
} else if (document.querySelector('script[src*="recaptcha/api.js"]')) {
console.log("Standard v2");
}
O que o Enterprise muda no back-end do site
Enterprise não é um desafio mais difícil: é outro modelo de administração do site — projeto no Google Cloud, regras por ação, códigos de motivo e verificação em endpoint pago. Só duas linhas desta tabela exigem ação de quem resolve.
| Sinal | v2 padrão | v2 Enterprise |
|---|---|---|
| Arquivo JS carregado | api.js |
enterprise.js |
| Função de execução | grecaptcha.execute() |
grecaptcha.enterprise.execute() |
| Verificação no site | siteverify (gratuita) |
recaptchaenterprise.googleapis.com (paga) |
| Códigos de motivo | Não | Sim (AUTOMATION, TOO_MUCH_TRAFFIC) |
| Regras personalizadas | Não | Sim (limites por ação) |
| Parâmetro na CaptchaAI | — | enterprise=1 |
| Tempo de resolução (SLA) | < 60 s | < 60 s |
Erros de detecção que derrubam a integração
| Erro | O que acontece | Correção |
|---|---|---|
enterprise=1 em site padrão |
Token pode voltar inválido | Confirme enterprise.js antes |
Sem enterprise=1 em site Enterprise |
O site recusa o token | Envie sempre que houver enterprise.js |
| Sitekey errada | ERROR_WRONG_GOOGLEKEY |
Leia data-sitekey no elemento .g-recaptcha |
| Confundir v2 com v3 Enterprise | Parâmetros errados | O v2 é visível; o v3 devolve score |
Se o token for recusado, confira nesta ordem:
- o arquivo JS carregado nesta execução;
- a sitekey enviada versus a do HTML atual;
- a
pageurlexata do widget.
Resolvendo os dois casos com a CaptchaAI
O fluxo é o mesmo: envie a tarefa ao in.php, consulte o resultado no res.php e escreva o token no formulário. Os exemplos usam staging.example.com (QA autorizado).
Versão padrão
Sem parâmetro extra; consulta a cada 5 s:
import requests
import time
# Submit task
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url
})
task_id = resp.text.split("|")[1]
# Poll for token
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY", "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
token = result.text.split("|")[1]
break
Versão Enterprise
Uma linha a mais no envio; o polling não muda:
import requests
import time
# Submit task — only difference is enterprise=1
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url,
"enterprise": 1 # Required for Enterprise
})
task_id = resp.text.split("|")[1]
# Polling is identical
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY", "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
token = result.text.split("|")[1]
break
Detecção e resolução no mesmo componente
Em bases de código que atendem vários sites, deixe a decisão com o programa: a classe abaixo lê o HTML, escolhe a versão e devolve o token com o que detectou.
import requests
import time
from bs4 import BeautifulSoup
class RecaptchaV2Solver:
def __init__(self, api_key):
self.api_key = api_key
def detect_and_solve(self, page_url, page_html=None):
if not page_html:
page_html = requests.get(page_url).text
soup = BeautifulSoup(page_html, "html.parser")
is_enterprise = bool(soup.find("script", src=lambda s: s and "enterprise.js" in s))
widget = soup.find(class_="g-recaptcha")
sitekey = widget["data-sitekey"] if widget else None
if not sitekey:
raise Exception("No reCAPTCHA sitekey found on page")
params = {
"key": self.api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": page_url
}
if is_enterprise:
params["enterprise"] = 1
resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
if not resp.text.startswith("OK|"):
raise Exception(f"Submit failed: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key, "action": "get", "id": task_id
})
if result.text.startswith("OK|"):
return {
"token": result.text.split("|")[1],
"is_enterprise": is_enterprise,
"sitekey": sitekey
}
if result.text != "CAPCHA_NOT_READY":
raise Exception(f"Solve failed: {result.text}")
raise Exception("Solve timed out")
solver = RecaptchaV2Solver("YOUR_API_KEY")
result = solver.detect_and_solve("https://staging.example.com/qa-login")
print(f"Enterprise: {result['is_enterprise']}, Token: {result['token'][:40]}...")
Envio do token ao endpoint de verificação
Depois do token, os caminhos convergem: escreva o valor em g-recaptcha-response e chame o callback do widget, quando houver.
# Selenium injection — works for both standard and enterprise
driver.execute_script(
f'document.getElementById("g-recaptcha-response").value = "{token}";'
)
# If the page uses a callback function
callback = driver.find_element("css selector", ".g-recaptcha").get_attribute("data-callback")
if callback:
driver.execute_script(f'{callback}("{token}");')
// Puppeteer injection — works for both
await page.evaluate((token) => {
document.getElementById("g-recaptcha-response").value = token;
// Find and call callback if present
const widget = document.querySelector(".g-recaptcha");
const cb = widget?.getAttribute("data-callback");
if (cb && typeof window[cb] === "function") {
window[cb](token);
}
}, token);
Cenário: a suíte que quebrou sem mudança de código
Um time em São Paulo mantém um portal de atendimento com formulários de três fornecedores; a suíte roda contra staging, com workers em sa-east-1. De um sprint para o outro, um formulário passou a recusar o token sem mudança no código: o fornecedor havia migrado o widget para enterprise.js.
A correção não foi ajustar uma constante, e sim rodar o detector em todas as URLs da suíte a cada execução, registrando a versão no resultado. Com dados fictícios nos formulários, a auditoria continua simples do ponto de vista da LGPD.
Perguntas frequentes
E se o site trocar api.js por enterprise.js?
É a causa mais comum de token recusado "do nada". Mantenha a detecção no código: leia o HTML a cada execução e derive o parâmetro dali.
reCAPTCHA v2 Enterprise é o mesmo que v3 Enterprise?
Não. O v2 mantém a interação visível; o v3 é invisível e devolve um score. A CaptchaAI resolve os dois, com envios diferentes.
Preciso de conta no Google Cloud?
Não. O projeto e a chave de verificação pertencem ao site. Do seu lado ficam a sitekey pública, a pageurl e a sua chave de API.
E se o site migrar para hCaptcha?
Nesse caso, este caminho não serve: o hCaptcha não é suportado pela CaptchaAI. A cobertura inclui:
- reCAPTCHA v2 e v3, inclusive Enterprise;
- Cloudflare Turnstile e Challenge;
- GeeTest v3, imagem/OCR e grade de imagens.
Guias relacionados
- Enterprise vs padrão: comparação completa — todas as variantes lado a lado.
- Resolver reCAPTCHA v2 pela API — tutorial da versão padrão.
- Resolver reCAPTCHA v2 Enterprise pela API — com
enterprise=1. - Como identificar uma implementação Enterprise