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 etpageurlne changent pas. - Côté site : Enterprise passe par un projet Google Cloud et l'endpoint
recaptchaenterprise.googleapis.comau lieu desiteverify. - 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Écontreapi.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 attributdata-sitekeycomme 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.
- La page charge-t-elle
enterprise.js? Si oui, ajoutezenterprise=1. - L'action envoyée correspond-elle à celle de la page (
signup, et nonsubmit) ? - 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 ».