Côté navigateur, reCAPTCHA Enterprise ne demande rien de plus que reCAPTCHA v3 : le même appel execute(), le même token opaque. Toute la différence se joue côté serveur, dans l'API Assessment, qui renvoie le score, les raisons chiffrées derrière ce score et un verdict sur le compte utilisateur. Pour une équipe d'automatisation, la conséquence tient en une ligne : un seul paramètre change dans la requête envoyée au solveur.
Le trajet complet d'une évaluation Enterprise
Le flux se lit en deux moitiés, séparées par l'envoi du token à votre backend :
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)
L'étape 4 est propre à Enterprise : l'exploitant réinjecte le verdict humain (fraude avérée, client légitime) pour affiner le modèle sur son trafic.
Enterprise ou reCAPTCHA v3 : ce qui change vraiment
| Caractéristique | reCAPTCHA v3 (gratuit) | reCAPTCHA Enterprise |
|---|---|---|
| Score | 0,0 à 1,0 | 0,0 à 1,0 + raisons |
| Analyse de risque | Basique | Détaillée (fraude, données de compte) |
| Raisons du score | Absentes | Explicites, derrière chaque score |
| Account Defender | Non | Oui (suivi du cycle de vie du compte) |
| Intégration WAF | Non | Oui (Cloudflare, Fastly, F5) |
| Express | Non | Oui (côté serveur uniquement, sans JS) |
| Détection de fuite de mot de passe | Non | Oui |
| Tarif | Gratuit (1 million d'évaluations/mois) | $1 pour 1 000 évaluations (1 million gratuit) |
| Endpoint API | google.com/recaptcha/api/siteverify | recaptchaenterprise.googleapis.com |
Retenez la dernière ligne : la validation ne passe plus par siteverify. Un backend migré vers Enterprise mais resté sur l'ancien endpoint renvoie des erreurs alors que le token, lui, est valide.
Poser le SDK côté client
Le script 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>
Trois écarts seulement par rapport à reCAPTCHA v3 :
- Le script chargé est
.../recaptcha/enterprise.jset non.../recaptcha/api.js - L'objet exposé est
grecaptcha.enterpriseet nongrecaptcha execute()produit un token au format identique
Repérer Enterprise dans le code source d'une page
Première chose à automatiser quand vous auditez un parc de sites :
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://example.com/login"))
Le champ actions collecte les noms d'action utilisés par la page (LOGIN, CHECKOUT, SIGNUP…) : transmettez-les à l'identique au solveur.
Créer une évaluation côté serveur
Cette partie concerne l'exploitant du site, pas l'automatisation — mais elle explique pourquoi un token accepté peut quand même aboutir à un blocage.
L'appel via le client Google Cloud
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
La réponse renvoyée
{
"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"]
}
}
Deux blocs, dans l'ordre : tokenProperties.valid dit si le token est authentique, riskAnalysis.score dit si la session mérite votre confiance. Un valid: true assorti d'un score de 0,1 est normal, pas un défaut d'intégration.
hashedAccountId mérite une note à part : c'est un identifiant utilisateur transmis à un tiers, même haché. Si vous exploitez le site depuis la France ou la Belgique, inscrivez-le à votre registre de traitements RGPD et réservez-le aux parcours qui en ont besoin (connexion, paiement).
Pourquoi un score s'effondre : les raisons renvoyées
C'est l'apport principal d'Enterprise. Là où v3 laisse deviner, Enterprise nomme le signal :
| Raison | Ce qu'elle signale | Effet sur le score |
|---|---|---|
AUTOMATION |
User-agent automatisé ou navigateur headless | -0,3 à -0,7 |
UNEXPECTED_ENVIRONMENT |
Incohérences navigateur ou appareil | -0,2 à -0,4 |
TOO_MUCH_TRAFFIC |
Volume élevé depuis cette IP ou cette session | -0,1 à -0,3 |
UNEXPECTED_USAGE_PATTERNS |
Comportement éloigné des normes humaines | -0,2 à -0,5 |
LOW_CONFIDENCE_SCORE |
Données insuffisantes pour trancher | Variable |
SUSPECTED_CARDING |
Schéma proche d'une fraude à la carte | -0,3 à -0,6 |
SUSPECTED_CHARGEBACK |
Risque d'impayé d'après la transaction | -0,2 à -0,4 |
Ces amplitudes sont indicatives : elles reposent sur des observations de terrain et varient selon le site, le volume et l'heure de la journée.
Les raisons de verdict étendues
| Raison | Ce qu'elle signale |
|---|---|
BROWSER_ERROR |
Erreurs JavaScript pendant l'exécution du SDK CAPTCHA |
SITE_MISMATCH |
Token émis pour un site différent de celui qui le valide |
FAILED_TWO_FACTOR |
Échec récent d'une authentification à deux facteurs |
Account Defender : le verdict sur le compte
Account Defender juge le compte, pas la session :
{
"accountDefenderAssessment": {
"labels": [
"PROFILE_MATCH",
"SUSPICIOUS_LOGIN_ACTIVITY",
"SUSPICIOUS_ACCOUNT_CREATION",
"RELATED_ACCOUNTS_NUMBER_HIGH"
]
}
}
| Étiquette | Signification |
|---|---|
PROFILE_MATCH |
Le comportement correspond au profil connu du compte |
SUSPICIOUS_LOGIN_ACTIVITY |
Connexion inhabituelle (nouvel appareil, nouvelle localisation) |
SUSPICIOUS_ACCOUNT_CREATION |
La création du compte semble automatisée |
RELATED_ACCOUNTS_NUMBER_HIGH |
Plusieurs comptes rattachés au même appareil ou à la même session |
Ces étiquettes restent dans la console de l'exploitant, invisibles depuis l'extérieur.
Enterprise posé à la périphérie : l'intégration WAF
Beaucoup de sites francophones à fort trafic — e-commerce, médias, réservation — branchent Enterprise non pas dans leur code applicatif mais dans leur WAF. Le défi surgit alors avant l'origine, qu'elle soit hébergée chez OVHcloud, Scaleway ou en région AWS eu-west-3.
Chez 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
Chez 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
Conséquence pour vos tests : un défi peut apparaître sur une URL qui n'affichait aucun formulaire la veille, parce qu'une règle WAF a changé. Détectez à chaque exécution, pas une fois pour toutes.
Traiter Enterprise dans vos automatisations
Un seul paramètre à ajouter
Du point de vue du solveur, un token Enterprise se produit comme un token reCAPTCHA classique : ni endpoint dédié ni méthode spécifique, le paramètre enterprise suffit. La facturation ne bouge pas non plus — CaptchaAI facture au thread simultané, pas à la résolution, dès BASIC ($15/mois, 5 threads).
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
Le token obtenu s'injecte ensuite comme d'habitude dans le champ g-recaptcha-response avant l'envoi du formulaire.
La même chose en Node.js
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");
}
Router automatiquement selon la variante détectée
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"
Branchez-la en amont de l'appel au solveur : elle décide seule d'envoyer enterprise: 1 ou non.
Dépannage
| Problème | Cause probable | Correctif |
|---|---|---|
| Token refusé par l'API Enterprise | Requête sans indicateur Enterprise | Ajoutez enterprise=1 |
| Score bloqué à 0,1 avec un token valide | action différente de celle de la page |
Alignez action sur la valeur du site |
SITE_MISMATCH dans les raisons |
Token généré pour un autre domaine | Vérifiez pageurl |
AUTOMATION dans les raisons du score |
Signaux d'environnement côté client | Vérifiez votre environnement ; sinon, contactez le support |
| Token accepté, accès refusé | D'autres contrôles se superposent au CAPTCHA | Cherchez règles WAF, empreinte de navigateur, limitation de débit |
Questions fréquentes
Le paramètre enterprise=1 est-il vraiment obligatoire ?
Oui, dès que la page charge recaptcha/enterprise.js. Sans lui, la requête est traitée comme du reCAPTCHA v3 classique et le token, rendu sans erreur apparente, sera rejeté à la validation.
Résoudre un CAPTCHA Enterprise coûte-t-il plus cher ?
Non. CaptchaAI facture des threads simultanés, sans supplément par type de CAPTCHA : votre débit dépend de votre plan, pas de la variante rencontrée. Le tarif de $1 pour 1 000 évaluations cité plus haut est celui que Google facture à l'exploitant du site.
Comment savoir quelle valeur d'action transmettre ?
Extrayez-la du code source : c'est la chaîne passée à grecaptcha.enterprise.execute(), souvent LOGIN, SIGNUP ou CHECKOUT. La fonction detect_recaptcha_enterprise() ci-dessus la collecte dans son champ actions.
Que faire des données personnelles vues par Enterprise côté RGPD ?
Si vous exploitez le site, traitez hashedAccountId et les étiquettes Account Defender comme des données personnelles : base légale, durée de conservation, mention dans votre politique de confidentialité. Ce n'est pas un avis juridique — référez-vous aux recommandations de la CNIL.
CaptchaAI prend-il en charge hCaptcha ou FunCaptcha comme alternatives ?
Non — ces deux types ne sont pas pris en charge. Les types disponibles sont reCAPTCHA v2 et v3 (Enterprise inclus), Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3 et les CAPTCHA image/OCR. CaptchaFox (bêta), Friendly Captcha (bêta) et Lemin (bêta) sont en phase bêta ; GeeTest v4 est annoncé comme à venir.
À retenir
Enterprise ajoute à reCAPTCHA v3 une analyse de risque explicable, Account Defender et une intégration WAF — trois briques qui servent surtout l'exploitant du site. Pour vos scripts, l'écart tient à deux gestes : détecter recaptcha/enterprise.js, puis transmettre l'indicateur enterprise et la bonne action à votre requête API CaptchaAI. Le reste — polling, injection du token, envoi du formulaire — ne change pas.