Explainers

reCAPTCHA Enterprise: como funciona a API de avaliação

Para quem escreve automação, o reCAPTCHA Enterprise não é um desafio mais difícil que o v3: é o mesmo token, avaliado por um serviço mais detalhado do lado de quem opera a página. Em vez de "pontuação e ação", o Google devolve uma avaliação (assessment) com motivos de pontuação, sinais de fraude e rótulos de conta.

Isso resolve a dúvida mais comum. Quem opera o site lê a avaliação; quem integra um fluxo autorizado só precisa de um token válido, com a sitekey certa, a action correspondente e o sinalizador enterprise=1.

Resumo para quem vai integrar

  • O desafio no navegador é idêntico ao do reCAPTCHA v3; a diferença está no servidor.
  • O script sai de recaptcha/api.js para recaptcha/enterprise.js, e o objeto vira grecaptcha.enterprise.
  • Na CaptchaAI o método segue userrecaptcha, agora com enterprise=1.

reCAPTCHA Enterprise vs reCAPTCHA v3

O v3 gratuito devolve um número entre 0,0 e 1,0. O Enterprise mantém o número, explica de onde ele veio e acrescenta recursos de análise de risco.

Recurso reCAPTCHA v3 (grátis) reCAPTCHA Enterprise
Pontuação 0,0-1,0 0,0-1,0 + motivos da pontuação
Análise de risco Básica Detalhada (sinais de fraude, dados da conta)
Motivos da pontuação Não Motivos que explicam a pontuação
Account Defender Não Sim (ciclo de vida da conta)
Integração com WAF Não Sim (Cloudflare, Fastly, F5)
Avaliação express Não Sim (só no servidor, sem JS)
Detecção de vazamento de senha Não Sim
Preços Grátis (1 milhão de avaliações/mês) US$ 1 por 1.000 avaliações (0-1 milhão grátis)
Endpoint da API google.com/recaptcha/api/siteverify recaptchaenterprise.googleapis.com

O fluxo de avaliação

Client-side:

  1. Load reCAPTCHA Enterprise script
  2. Call grecaptcha.enterprise.execute(SITE_KEY, {action: 'LOGIN'})
  3. Receive token
  4. Send token to your backend

Server-side:

  1. Create assessment via Enterprise API
  2. Receive detailed risk analysis
  3. Make access decision based on score + reasons
  4. Optionally annotate the assessment (report fraud/legitimate)

A avaliação é criada pelo backend do site, nunca pelo navegador. O token é só o insumo: uso único e validade curta, por isso segue para verificação logo após a geração.

Integração no lado do cliente

SDK JavaScript do Enterprise

<script src="https://www.google.com/recaptcha/enterprise.js?render=SITE_KEY"></script>
<script>
    grecaptcha.enterprise.ready(function() {
        grecaptcha.enterprise.execute('SITE_KEY', { action: 'LOGIN' })
            .then(function(token) {
                // Send token to backend
                fetch('/api/verify', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ token: token })
                });
            });
    });
</script>

Diferenças em relação ao reCAPTCHA v3 padrão:

  • A URL do script usa .../recaptcha/enterprise.js no lugar de .../recaptcha/api.js
  • O objeto da API é grecaptcha.enterprise, e não grecaptcha
  • execute() devolve o token no mesmo formato

Como identificar o Enterprise no HTML

Confirme a variante antes de integrar: o script e a action estão no HTML.

import requests
import re

def detect_recaptcha_enterprise(url):
    """Detect if a page uses reCAPTCHA Enterprise."""
    html = requests.get(url, timeout=10).text

    indicators = {
        "is_enterprise": False,
        "is_standard": False,
        "site_key": None,
        "actions": [],
    }

    # Enterprise detection
    if "recaptcha/enterprise.js" in html:
        indicators["is_enterprise"] = True
        match = re.search(r"render=([A-Za-z0-9_-]+)", html)
        if match:
            indicators["site_key"] = match.group(1)

    # Standard v3 detection
    elif "recaptcha/api.js?render=" in html:
        indicators["is_standard"] = True
        match = re.search(r"render=([A-Za-z0-9_-]+)", html)
        if match:
            indicators["site_key"] = match.group(1)

    # Extract action names
    actions = re.findall(r"action:\s*['\"](\w+)['\"]", html)
    indicators["actions"] = list(set(actions))

    return indicators

print(detect_recaptcha_enterprise("https://staging.example.com/qa-login"))

A API de avaliação no lado do servidor

Como criar uma avaliação

Esta parte existe só para quem opera o site: o projeto no Google Cloud e a chamada create_assessment pertencem ao backend que valida o token.

from google.cloud import recaptchaenterprise_v1
from google.cloud.recaptchaenterprise_v1 import Assessment

def create_assessment(project_id, site_key, token, action):
    """Create a reCAPTCHA Enterprise assessment."""
    client = recaptchaenterprise_v1.RecaptchaEnterpriseServiceClient()

    event = recaptchaenterprise_v1.Event()
    event.site_key = site_key
    event.token = token
    event.expected_action = action

    assessment = recaptchaenterprise_v1.Assessment()
    assessment.event = event

    request = recaptchaenterprise_v1.CreateAssessmentRequest()
    request.assessment = assessment
    request.parent = f"projects/{project_id}"

    response = client.create_assessment(request)
    return response

Estrutura da resposta da avaliação

{
    "name": "projects/123456/assessments/abcdef123",
    "event": {
        "token": "...",
        "siteKey": "6Le...",
        "expectedAction": "LOGIN",
        "hashedAccountId": "abc123..."
    },
    "riskAnalysis": {
        "score": 0.9,
        "reasons": [
            "AUTOMATION",
            "TOO_MUCH_TRAFFIC"
        ],
        "extendedVerdictReasons": [
            "BROWSER_ERROR"
        ]
    },
    "tokenProperties": {
        "valid": true,
        "hostname": "example.com",
        "action": "LOGIN",
        "createTime": "2025-01-15T10:30:00Z",
        "invalidReason": ""
    },
    "accountDefenderAssessment": {
        "labels": ["PROFILE_MATCH"]
    }
}

Três campos decidem tudo: riskAnalysis.score, riskAnalysis.reasons e tokenProperties.valid com invalidReason. Um token expirado ou de outro domínio falha já em tokenProperties.

Account Defender: ciclo de vida da conta

O Account Defender acompanha as contas ao longo do tempo e devolve rótulos na avaliação:

{
    "accountDefenderAssessment": {
        "labels": [
            "PROFILE_MATCH",
            "SUSPICIOUS_LOGIN_ACTIVITY",
            "SUSPICIOUS_ACCOUNT_CREATION",
            "RELATED_ACCOUNTS_NUMBER_HIGH"
        ]
    }
}
Rótulo Significado
PROFILE_MATCH Comportamento compatível com o perfil da conta
SUSPICIOUS_LOGIN_ACTIVITY Login fora do padrão (novo dispositivo, nova localização)
SUSPICIOUS_ACCOUNT_CREATION Criação da conta parece automatizada
RELATED_ACCOUNTS_NUMBER_HIGH Muitas contas no mesmo dispositivo ou sessão

reCAPTCHA Enterprise no WAF

O Enterprise também pode ser acionado via WAF, antes de a requisição chegar à aplicação. O desafio aparece em uma URL fora do fluxo original — o que quebra suítes escritas só para a página de login.

Integração com o WAF da Cloudflare

Request arrives at Cloudflare edge
    ↓
Cloudflare WAF rule evaluates request
    ↓
Rule triggers reCAPTCHA Enterprise challenge
    ↓
Client solves CAPTCHA → token returned
    ↓
Cloudflare validates token via Enterprise API
    ↓
If valid + score above threshold → request forwarded to origin

Integração com F5 BIG-IP

F5 iRule or policy evaluates request
    ↓
Triggers reCAPTCHA Enterprise challenge page
    ↓
Client solves → token validated server-side
    ↓
F5 forwards or blocks based on assessment score

Como tratar o reCAPTCHA Enterprise na automação

Para um serviço de resolução de CAPTCHA, o token Enterprise nasce igual ao do padrão: muda um parâmetro.

Python: mesmo método, com enterprise=1

import requests
import time

API_KEY = "YOUR_API_KEY"

# Enterprise is solved with the same method
# The solver handles the Enterprise variant automatically
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
    "pageurl": "https://enterprise-site.com/login",
    "enterprise": 1,  # Flag for Enterprise variant
    "json": 1,
})

task_id = submit.json()["request"]

for _ in range(60):
    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:
        token = result["request"]
        print(f"Enterprise token: {token[:50]}...")
        break

Node.js com axios

const axios = require("axios");

async function solveEnterprise(sitekey, pageurl) {
    const API_KEY = "YOUR_API_KEY";

    const { data: submit } = await axios.post(
        "https://ocr.captchaai.com/in.php",
        new URLSearchParams({
            key: API_KEY,
            method: "userrecaptcha",
            googlekey: sitekey,
            pageurl: pageurl,
            enterprise: 1,
            json: 1,
        })
    );

    const taskId = submit.request;

    for (let i = 0; i < 60; i++) {
        await new Promise(r => setTimeout(r, 5000));
        const { data: result } = await axios.get(
            "https://ocr.captchaai.com/res.php",
            { params: { key: API_KEY, action: "get", id: taskId, json: 1 } }
        );

        if (result.status === 1) return result.request;
    }

    throw new Error("Timeout");
}

Detecte a versão antes de enviar

Em um crawler autorizado com vários fluxos internos, identifique a variante em tempo de execução:

def identify_recaptcha_version(html):
    """Determine which reCAPTCHA version a page uses."""
    if "recaptcha/enterprise.js" in html:
        return "enterprise"
    elif "recaptcha/api.js?render=" in html:
        return "v3"
    elif "g-recaptcha" in html and 'data-size="invisible"' in html:
        return "v2_invisible"
    elif "g-recaptcha" in html:
        return "v2"
    else:
        return "none"

Motivos de pontuação: como ler o veredicto

Quando a pontuação cai, o Enterprise diz por quê — com peso aproximado por motivo.

Motivo Descrição Impacto na pontuação
AUTOMATION User agent automatizado ou navegador headless -0,3 a -0,7
UNEXPECTED_ENVIRONMENT Inconsistências no ambiente do navegador ou dispositivo -0,2 a -0,4
TOO_MUCH_TRAFFIC Alto volume de requisições do IP ou da sessão -0,1 a -0,3
UNEXPECTED_USAGE_PATTERNS Comportamento fora do padrão humano -0,2 a -0,5
LOW_CONFIDENCE_SCORE Dados insuficientes para avaliar Variável
SUSPECTED_CARDING Transação com padrão de fraude de cartão -0,3 a -0,6
SUSPECTED_CHARGEBACK Risco de estorno pelos sinais da transação -0,2 a -0,4

Motivos estendidos do veredicto

Motivo Descrição
BROWSER_ERROR Erro de JavaScript no SDK do CAPTCHA
SITE_MISMATCH Token criado para site diferente daquele em que foi validado
FAILED_TWO_FACTOR Autenticação em dois fatores falhou recentemente

Atenção: esses motivos só chegam ao operador do site, na resposta da avaliação. Em sites de terceiros você enxerga apenas o desfecho.

Diagnóstico: erros comuns

Problema Diagnóstico Como resolver
Token recusado pela API Enterprise Método padrão usado em site Enterprise Acrescente enterprise=1 à requisição
Pontuação sempre 0,1 com token válido Parâmetro action divergente Confira se a action bate com a da página
SITE_MISMATCH entre os motivos Token gerado para o domínio errado Use o pageurl exato do desafio
AUTOMATION nos motivos de pontuação Ambiente de resolução identificado A CaptchaAI trata o caso; se persistir, acione o suporte
Token válido, mas o site ainda bloqueia O site aplica verificações além do CAPTCHA Investigue outras camadas de detecção (WAF, sinal de navegador)

Cenário: QA de checkout em homologação

Imagine um time de e-commerce em São Paulo que protegeu login e checkout com reCAPTCHA Enterprise e roda testes a cada deploy, em ambiente próprio, no domínio staging.example.com e com dados fictícios.

Três decisões deixam o fluxo estável:

  • Use a mesma action da produção (LOGIN, CHECKOUT); divergência derruba a pontuação.
  • Mantenha os workers em sa-east-1 para cortar RTT.
  • Ao gravar tokens em log, considere a LGPD (RGPD em Portugal): hashedAccountId e o id de sessão são dados pessoais.

Um volume desse porte cabe no BASIC (US$ 15/mês, 5 threads) com testes em série; em paralelo, no STANDARD (US$ 30/mês, 15 threads). A cobrança é por thread simultânea, com resoluções ilimitadas.

Perguntas frequentes

Preciso mesmo enviar enterprise=1 em todo site Enterprise?

Sim, sempre que a página carrega recaptcha/enterprise.js. Sem o sinalizador a tarefa vira reCAPTCHA padrão e o token costuma ser recusado — a causa número um dos "token válido que não funciona".

O token é aceito, mas a pontuação continua baixa. O que verificar?

Comece pela action, que precisa ser idêntica à da página, maiúsculas incluídas. Depois confira o pageurl: divergência de domínio aparece como SITE_MISMATCH. Com os dois corretos, o site aplica outras camadas de detecção.

hCaptcha e FunCaptcha entram na cobertura da CaptchaAI?

Não. hCaptcha e FunCaptcha (Arkose Labs) não são suportados. A cobertura vai de reCAPTCHA v2 e v3 (Enterprise incluído) a Cloudflare Turnstile e Challenge, GeeTest v3, imagem/OCR, grade de imagens e BLS, além de CaptchaFox (beta), Friendly Captcha (beta) e Lemin (beta). GeeTest v4 aparece apenas como "em breve".

Preciso de conta no Google Cloud para resolver CAPTCHA Enterprise?

Não. Basta a sitekey (chave pública do widget) da página e um serviço de resolução de CAPTCHA. A conta no Google Cloud é de quem opera o site e valida as avaliações.

Resumo

O reCAPTCHA Enterprise acrescenta ao padrão análise de risco detalhada, motivos de pontuação, Account Defender e integração com WAF — tudo do lado de quem opera o site. Na automação, a mudança cabe em uma linha: envie enterprise=1 na requisição da API da CaptchaAI, com pageurl e action alinhados à página.

Artigos relacionados

Os comentários estão desativados para este artigo.