Comparisons

Comparaison entre reCAPTCHA v3 Enterprise et standard

Vous inspectez une page, vous y trouvez enterprise.js au lieu de api.js : faut-il refaire votre intégration ? Non. Côté API CaptchaAI, un seul paramètre s'ajoute, enterprise=1. Côté site, la différence est réelle : Enterprise expose des codes de motif, des seuils réglables action par action et un modèle qui apprend du trafic de la page.

Les deux versions restent invisibles et renvoient un score sur la même échelle, de 0,0 (trafic automatisé) à 1,0 (visiteur humain). Ce comparatif suit l'ordre du terrain : reconnaître la version, comprendre la notation, puis écrire le code.


L'essentiel en quatre points

  • Intégration CaptchaAI : un paramètre, enterprise=1. Méthode, sitekey, action et pageurl ne changent pas.
  • Côté site : Enterprise passe par un projet Google Cloud et l'endpoint recaptchaenterprise.googleapis.com au lieu de siteverify.
  • Score : même plage, mais un seuil d'acceptation qui peut varier d'une action à l'autre.
  • Diagnostic : des codes de motif, invisibles pour vous, expliquent les refus côté site.

Repérer la version avant d'intégrer

Rien ne les distingue à l'écran : la réponse est dans le HTML, où trois signaux suffisent.

  • Le fichier chargé : enterprise.js?render=CLÉ contre api.js?render=CLÉ.
  • L'appel JavaScript : grecaptcha.enterprise.execute() d'un côté, grecaptcha.execute() de l'autre.
  • La clé : elle se lit toujours dans le paramètre render=, jamais dans un attribut data-sitekey comme en v2.

Détection en Python

Une seule requête sur la page donne les trois informations.

import requests
import re

def detect_v3_version(url):
    html = requests.get(url).text

    if "enterprise.js" in html:
        version = "enterprise"
    elif "recaptcha/api.js" in html and "render=" in html:
        version = "standard"
    else:
        return None

    # Extract sitekey
    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
    action_match = re.search(r'action["\']?\s*[:=]\s*["\'](\w+)', html)
    action = action_match.group(1) if action_match else None

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

Détection en Node.js

Même logique si votre orchestration tourne en JavaScript.

const axios = require("axios");

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

  const version = html.includes("enterprise.js")
    ? "enterprise"
    : html.includes("recaptcha/api.js") && html.includes("render=")
      ? "standard"
      : 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],
    action: actionMatch?.[1],
  };
}

Fonctionnalités : ce qu'Enterprise ajoute côté site

Fonctionnalité v3 standard v3 Enterprise
Fonctionnement invisible Oui Oui
Score de 0,0 à 1,0 Oui Oui
Paramètre action Obligatoire Obligatoire
Codes de motif Non Oui
Seuils par action Non Oui (via la Cloud Console)
Mots de passe compromis Non Oui
Account Defender Non Oui
Étiquettes anti-fraude Non Oui
Intégration MFA Non Oui
Endpoint de vérification siteverify (gratuit) recaptchaenterprise.googleapis.com
Quota mensuel 1 million d'évaluations offertes Facturation à l'évaluation
Fichier JS chargé api.js?render=KEY enterprise.js?render=KEY
Paramètres CaptchaAI version=v3 version=v3 + enterprise=1

Notation : ce que change Enterprise

La version standard s'appuie sur un modèle global unique. Enterprise empile des couches par-dessus.

Aspect de la notation v3 standard v3 Enterprise
Modèle de base Modèle global de Google Modèle global, enrichi de signaux propres au site
Seuils Un seuil pour toutes les actions Un seuil par action (login = 0,7, checkout = 0,9)
Apprentissage Générique Ajusté sur le trafic réel du site
Granularité 0,0 à 1,0, deux décimales Même plage, signaux plus fins
Faux positifs Réglage manuel du seuil Analyse appuyée sur les codes de motif

Conséquence directe : le paramètre action pèse plus lourd sur un site Enterprise. Une action inconnue du site peut retomber sur le seuil le plus strict — reprenez-la telle quelle depuis l'appel grecaptcha.enterprise.execute() de la page.


Les codes de motif Enterprise

Les réponses Enterprise contiennent des codes qui justifient le score. Ils servent au propriétaire du site, mais les connaître aide à comprendre ce que votre trafic de test laisse voir.

Code Ce qu'il signale Ce que vous pouvez ajuster
AUTOMATION Comportement automatisé détecté Piloter un vrai navigateur (Playwright, Selenium)
UNEXPECTED_ENVIRONMENT Environnement de navigateur inhabituel Vérifier ce que trahit votre navigateur headless
TOO_MUCH_TRAFFIC Volume élevé depuis la même source Rate limiting et rotation de proxys
UNEXPECTED_USAGE_PATTERNS Rythme d'interaction anormal Espacer les actions, varier les délais
LOW_CONFIDENCE_SCORE Trop peu de données pour trancher Laisser la page vivre quelques secondes
SUSPECTED_CARDING Motifs de fraude à la carte bancaire Sans objet pour l'automatisation
SUSPECTED_CHARGEBACK Motifs de rétrofacturation Sans objet pour l'automatisation

À noter : ces codes ne transitent pas par CaptchaAI. Google les renvoie au backend du site lors de la vérification du token. Vous ne les lisez jamais, mais ils expliquent bien des refus.


Résoudre les deux versions avec l'API CaptchaAI

Même schéma des deux côtés : soumission sur in.php, puis interrogation de res.php toutes les 5 s.

v3 standard : soumettre puis interroger

import requests
import time

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]

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

v3 Enterprise : le même appel, plus un paramètre

import requests
import time

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

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

Un solveur qui détecte la version

Un site peut basculer vers Enterprise sans prévenir. Laissez le code déduire la version à chaque exécution plutôt que de la figer dans votre configuration.

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

    def solve(self, page_url, action=None):
        import re
        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")

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

        params = {
            "key": self.api_key,
            "method": "userrecaptcha",
            "version": "v3",
            "googlekey": key_match.group(1),
            "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 error: {result.text}")
        raise Exception("Timed out")

Exemple : inscription SaaS testée depuis Paris

Une équipe QA surveille le formulaire d'inscription de son SaaS, hébergé chez OVHcloud, avec des workers sur Scaleway. L'équipe sécurité migre le formulaire vers Enterprise pour distinguer les seuils de signup et de login.

Le lendemain, les tests échouent alors que le token revient normalement. Trois vérifications tranchent.

  1. La page charge-t-elle enterprise.js ? Si oui, ajoutez enterprise=1.
  2. L'action envoyée correspond-elle à celle de la page (signup, et non submit) ?
  3. Le seuil serveur a-t-il été relevé pour cette action lors de la migration ?

Deux réflexes utiles. La facturation CaptchaAI se compte en threads simultanés, en dollars US, pas en résolutions : un plan STANDARD ($30/mois, 15 threads) absorbe une campagne de tests nocturne. Et comme ces scénarios journalisent des adresses IP, gardez le réflexe RGPD : ne conservez que les données de test utiles.


Dépannage

Symptôme Cause probable Correctif
Token refusé sur un site Enterprise enterprise=1 absent Cherchez enterprise.js et ajoutez le paramètre
Score faible alors que le token est valide Mauvais paramètre action Reprenez l'action de grecaptcha.enterprise.execute()
Fonctionne en recette, échoue en production Motif de trafic répétitif repéré par le modèle du site Alternez vos proxys, espacez les requêtes
ERROR_WRONG_GOOGLEKEY Clé lue dans un attribut data-sitekey Récupérez-la dans le paramètre render= du script
CAPCHA_NOT_READY jusqu'au timeout Interrogation trop rapprochée ou threads saturés Laissez 5 s entre deux appels à res.php

Questions fréquentes

Faut-il un compte Google Cloud pour résoudre un reCAPTCHA v3 Enterprise ?

Non. Le projet Google Cloud est une contrainte de l'éditeur du site. De votre côté, vous transmettez le sitekey, l'action et enterprise=1 à l'API CaptchaAI.

Que se passe-t-il si le paramètre action est faux ?

Aucune erreur d'API : le token revient normalement, puis le site l'évalue avec le mauvais seuil et rejette la requête. C'est la première cause du fameux « token valide, requête refusée ».

Résoudre de l'Enterprise coûte-t-il plus cher ?

Non. Les plans CaptchaAI se facturent au thread simultané, avec des résolutions illimitées par thread et sans supplément selon le type de CAPTCHA. Votre budget dépend de votre parallélisme.

Un score de 0,3 signifie-t-il que le token est mauvais ?

Non : le score évalue le contexte de la session, pas le token. C'est le site qui décide de la suite, et 0,3 peut suffire sur un formulaire de contact tout en bloquant un paiement.

Quels autres types CaptchaAI prend-il en charge ?

reCAPTCHA v2 et v3 (Enterprise compris), Cloudflare Turnstile et Cloudflare Challenge, GeeTest v3, les CAPTCHA image/OCR, les grilles et BLS, plus CaptchaFox (bêta), Friendly Captcha (bêta) et Lemin (bêta). hCaptcha et FunCaptcha (Arkose Labs) ne sont pas pris en charge ; GeeTest v4 est annoncé « à venir ».


Guides associés

Les commentaires sont désactivés pour cet article.