Comparativas

reCAPTCHA v3 estándar vs Enterprise: cómo detectar y resolver

Si integras reCAPTCHA v3 con la API de CaptchaAI, hay una buena noticia: la versión estándar y la Enterprise se resuelven con el mismo método. La única diferencia en la solicitud es el parámetro enterprise=1; el endpoint, el sondeo y el token son idénticos. El trabajo real no está en resolver, sino en detectar cuál usa cada sitio, porque ambas son invisibles y no muestran ningún widget.

Piensa en un equipo que hace QA del login de una tienda tipo MercadoLibre: el script debe seguir funcionando aunque el sitio migre a Enterprise de un día para otro. Por eso conviene detectar primero y dejar que la detección decida qué enviar.


Qué cambia realmente entre estándar y Enterprise

Ambas versiones se ejecutan de forma invisible y devuelven una puntuación de riesgo (0,0 a 1,0). Enterprise añade códigos de motivo, umbrales adaptativos por acción y gestión desde un proyecto de Google Cloud. Pero para resolver casi nada de eso importa: para CaptchaAI todo se reduce a una bandera.

Característica Estándar v3 Enterprise v3
Operación invisible
Puntuación (0,0–1,0)
Parámetro action Requerido Requerido
Archivo JS api.js?render=KEY enterprise.js?render=KEY
Función de ejecución grecaptcha.execute() grecaptcha.enterprise.execute()
Códigos de motivo No Sí (AUTOMATION, TOO_MUCH_TRAFFIC, etc.)
Umbrales por acción No Sí (desde Cloud Console)
Detección de fuga de contraseñas No
Account Defender No
Endpoint de verificación siteverify (gratis) recaptchaenterprise.googleapis.com (de pago)
Parámetros en CaptchaAI version=v3 version=v3 + enterprise=1
Tiempo típico de resolución 10-20 segundos 10-20 segundos

Casi todas esas filas solo importan al dueño del sitio. Para quien resuelve, la única accionable es enterprise=1.


Cómo saber qué versión usa un sitio

Como ninguna versión dibuja un widget, la detección tiene que leer el JavaScript de la página. La señal más limpia es el script que se carga: api.js frente a enterprise.js. Conviene comprobar tres señales:

  • El archivo JS: enterprise.js (Enterprise) o api.js?render= (estándar).
  • La función: grecaptcha.enterprise.execute() o grecaptcha.execute().
  • El sitekey: sale de render=KEY en ambos casos.

En Python

import requests
import re

def detect_v3_type(url):
    resp = requests.get(url)
    html = resp.text

    # Check for enterprise.js
    if "enterprise.js" in html:
        version = "enterprise_v3"
        execute_fn = "grecaptcha.enterprise.execute"
    elif "recaptcha/api.js" in html and "render=" in html:
        version = "standard_v3"
        execute_fn = "grecaptcha.execute"
    else:
        return None

    # Extract sitekey from render parameter
    key_match = re.search(r'render[=:]\s*["\']?([A-Za-z0-9_-]{40})', html)
    sitekey = key_match.group(1) if key_match else None

    # Extract action parameter
    action_match = re.search(r'action["\']?\s*[:=]\s*["\'](\w+)', html)
    action = action_match.group(1) if action_match else "unknown"

    return {
        "version": version,
        "sitekey": sitekey,
        "action": action,
        "execute_fn": execute_fn
    }

info = detect_v3_type("https://staging.example.com/qa-login")
print(info)

En Node.js

const axios = require("axios");

async function detectV3Type(url) {
  const { data: html } = await axios.get(url);

  let version, executeFn;
  if (html.includes("enterprise.js")) {
    version = "enterprise_v3";
    executeFn = "grecaptcha.enterprise.execute";
  } else if (html.includes("recaptcha/api.js") && html.includes("render=")) {
    version = "standard_v3";
    executeFn = "grecaptcha.execute";
  } else {
    return null;
  }

  const keyMatch = html.match(/render[=:]\s*['"]?([A-Za-z0-9_-]{40})/);
  const actionMatch = html.match(/action['"]?\s*[:=]\s*['"](\w+)/);

  return {
    version,
    sitekey: keyMatch?.[1] || null,
    action: actionMatch?.[1] || "unknown",
    executeFn,
  };
}

Comprobación rápida en el navegador

// Paste in DevTools console
if (document.querySelector('script[src*="enterprise.js"]')) {
  console.log("Enterprise v3");
  console.log("Execute:", typeof grecaptcha?.enterprise?.execute);
} else if (document.querySelector('script[src*="api.js"][src*="render="]')) {
  console.log("Standard v3");
  console.log("Execute:", typeof grecaptcha?.execute);
}

Resolver ambas versiones con la API de CaptchaAI

Con la versión detectada, el flujo es el de siempre: envías la tarea a in.php, sondeas res.php y recibes el token.

Estándar v3

import requests
import time

# Submit
resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "version": "v3",
    "googlekey": sitekey,
    "action": "login",
    "pageurl": page_url
})
task_id = resp.text.split("|")[1]

# Poll
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

Enterprise v3

import requests
import time

# Submit — add enterprise=1
resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "version": "v3",
    "enterprise": 1,  # Required for Enterprise
    "googlekey": sitekey,
    "action": "login",
    "pageurl": page_url
})
task_id = resp.text.split("|")[1]

# Polling is identical to standard
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

Solver universal con detección automática

En producción no querrás dos rutas separadas. Lo más robusto es un solver que detecte la versión en cada carga y decida si añade enterprise=1:

import requests
import time
import re

class RecaptchaV3Solver:
    def __init__(self, api_key):
        self.api_key = api_key

    def detect_and_solve(self, page_url, action=None):
        """Auto-detect standard vs enterprise and solve."""
        html = requests.get(page_url).text

        is_enterprise = "enterprise.js" in html
        key_match = re.search(r'render[=:]\s*["\']?([A-Za-z0-9_-]{40})', html)
        if not key_match:
            raise Exception("No v3 sitekey found")
        sitekey = key_match.group(1)

        if not action:
            action_match = re.search(r'action["\']?\s*[:=]\s*["\'](\w+)', html)
            action = action_match.group(1) if action_match else "verify"

        params = {
            "key": self.api_key,
            "method": "userrecaptcha",
            "version": "v3",
            "googlekey": sitekey,
            "action": action,
            "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 result.text.split("|")[1]
            if result.text != "CAPCHA_NOT_READY":
                raise Exception(f"Solve failed: {result.text}")

        raise Exception("Timed out")

solver = RecaptchaV3Solver("YOUR_API_KEY")
token = solver.detect_and_solve("https://staging.example.com/qa-login", action="login")
print(f"Token: {token[:40]}...")

Extraer el parámetro action correcto

El action es el detalle que más gente pasa por alto, e importa igual en ambas versiones. Si envías la acción equivocada, la puntuación baja y el token puede rechazarse. Extrae siempre la cadena exacta del JavaScript:

import re

def find_v3_actions(html):
    """Extract all action parameters from page JavaScript."""
    # Look for grecaptcha.execute(key, {action: '...'})
    pattern = r"(?:grecaptcha\.(?:enterprise\.)?execute|action)\s*[(:]\s*['\"](\w+)"
    actions = re.findall(pattern, html)
    return list(set(actions))

# Common actions: "login", "submit", "register", "checkout", "homepage"

Inyectar el token en tu flujo

La inyección tampoco distingue versiones: siempre es el campo g-recaptcha-response, en navegador o en HTTP puro.

# For browser-based workflows (Selenium)
driver.execute_script(
    f'document.getElementById("g-recaptcha-response").value = "{token}";'
)

# For pure HTTP workflows
requests.post(page_url, data={
    "g-recaptcha-response": token,
    "username": "user",
    "password": "pass"
})
// Puppeteer
await page.evaluate((tok) => {
  document.getElementById("g-recaptcha-response").value = tok;
}, token);

// Pure HTTP (axios)
await axios.post(pageUrl, new URLSearchParams({
  "g-recaptcha-response": token,
  username: "user",
  password: "pass",
}));

Errores frecuentes al migrar

Casi todos los fallos vienen de mezclar las señales de una versión con los parámetros de la otra:

Error Resultado Solución
Usar enterprise=1 en un v3 estándar El token puede ser inválido Comprueba enterprise.js antes de añadir la bandera
Omitir enterprise=1 en Enterprise v3 El backend rechaza el token Añádelo siempre que aparezca enterprise.js
Enviar un action incorrecto Puntuación baja, token rechazado Extrae la cadena de acción exacta del JavaScript de la página
Omitir version=v3 El solver lo trata como v2 Incluye siempre version=v3 para el reCAPTCHA basado en puntuación
Usar un sitekey de v2 para resolver v3 ERROR_WRONG_GOOGLEKEY Los sitekeys de v3 salen del parámetro render=KEY

Preguntas frecuentes

¿Es fiable detectar la versión de forma programática?

Sí. La comprobación de una línea sobre el código de la página es estable, porque enterprise.js solo aparece cuando el sitio carga la variante Enterprise:

page_source = driver.page_source
is_enterprise = "enterprise.js" in page_source

Ejecútala en cada carga de página por si el sitio migra sin avisar.

¿Necesito una cuenta de Google Cloud para resolver Enterprise v3?

No. El proyecto de Google Cloud, los umbrales por acción y el Account Defender son cosa del dueño del sitio. Tú solo envías el sitekey, el action y la bandera enterprise=1; el resto no interviene en la resolución.

¿Resolver Enterprise v3 cuesta más que el estándar?

No hay recargo por tipo. CaptchaAI factura por thread concurrente, no por resolución, con resoluciones ilimitadas por thread en todos los planes. Estándar y Enterprise usan el mismo método userrecaptcha: mismo precio, misma integración.

¿Qué plan me conviene para resolver v3 a gran escala?

Depende de cuántas resoluciones corras en paralelo, no del tipo de CAPTCHA. Para pruebas puntuales basta BASIC ($15/mes, 5 threads); con mucho volumen simultáneo, ADVANCE ($90/mes, 50 threads) da margen de sobra. Consulta las cifras vigentes en captchaai.com/pricing.

¿Puedo reutilizar un token de v3 entre peticiones?

No. Un token de reCAPTCHA v3 es de un solo uso y expira rápido; hay que resolver de nuevo en cada envío. La puntuación se calcula para el action concreto, así que reciclarlo con otra acción suele terminar en rechazo.


Guías relacionadas

Los comentarios están deshabilitados para este artículo.