Migrer de NextCaptcha vers CaptchaAI ne vous oblige pas à réécrire votre logique de résolution. Le travail tient en trois changements : l'URL des endpoints, le format d'envoi (formulaire au lieu de JSON) et la lecture des réponses. Votre boucle d'interrogation et votre gestion des erreurs ne bougent pas.
Ce guide donne la correspondance entre les deux API — endpoints, paramètres, types de tâches et code — plus un test en parallèle pour basculer sans interruption. Côté facturation, CaptchaAI compte en threads concurrents plutôt qu'à la tâche : BASIC ($15/mois, 5 threads) inclut des résolutions illimitées par thread.
Correspondance des endpoints
Trois appels couvrent l'essentiel.
| Action | NextCaptcha | CaptchaAI |
|---|---|---|
| Soumettre la tâche | POST /createTask |
POST https://ocr.captchaai.com/in.php |
| Récupérer le résultat | POST /getTaskResult |
GET https://ocr.captchaai.com/res.php |
| Vérifier le solde | POST /getBalance |
GET res.php?action=getbalance&key=KEY |
Traduction des paramètres
Chaque champ du bloc task a un équivalent plat côté CaptchaAI.
| Champ NextCaptcha | Champ CaptchaAI | Remarque |
|---|---|---|
clientKey |
key |
Clé API |
task.type |
method |
Voir la correspondance des types ci-dessous |
task.websiteURL |
pageurl |
URL de la page cible |
task.websiteKey |
googlekey ou sitekey |
Clé de site pour les CAPTCHA à token |
task.recaptchaDataSValue |
data-s |
Paramètre reCAPTCHA data-s |
task.isInvisible |
invisible=1 |
Indicateur reCAPTCHA invisible |
task.pageAction |
action |
Action reCAPTCHA v3 |
taskId |
id |
ID de tâche/captcha pour l'interrogation |
Correspondance des types de tâches
Le task.type devient une valeur method.
| Type NextCaptcha | Méthode CaptchaAI + paramètres |
|---|---|
RecaptchaV2TaskProxyless |
method=userrecaptcha |
RecaptchaV2Task |
method=userrecaptcha + proxy, proxytype |
ImageToTextTask |
method=base64 + body |
TurnstileTaskProxyless |
method=turnstile |
HCaptchaTaskProxyless / HCaptchaTask |
Non pris en charge — voir la remarque ci-dessous |
Remarque sur hCaptcha et FunCaptcha. CaptchaAI ne prend pas en charge hCaptcha ni FunCaptcha (Arkose Labs) : prévoyez une solution distincte pour ces types. Le reste — reCAPTCHA v2/v3, Cloudflare Turnstile et Challenge, GeeTest v3, images/OCR et grilles — bascule normalement.
Structure des requêtes
NextCaptcha attend un corps JSON ; CaptchaAI accepte de simples paramètres de formulaire (ou du JSON).
{
"clientKey": "next_captcha_key",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}
}
Les mêmes valeurs vers in.php :
POST https://ocr.captchaai.com/in.php
key=YOUR_API_KEY&method=userrecaptcha&googlekey=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-&pageurl=https://example.com&json=1
Migrer le code : avant et après
La même fonction reCAPTCHA v2, avant puis après.
Python — avant (NextCaptcha)
import requests
import time
CLIENT_KEY = "your_nextcaptcha_key"
BASE_URL = "https://api.nextcaptcha.com"
def solve_recaptcha_v2(sitekey, pageurl):
# Submit
resp = requests.post(f"{BASE_URL}/createTask", json={
"clientKey": CLIENT_KEY,
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": pageurl,
"websiteKey": sitekey
}
})
data = resp.json()
if data.get("errorId") != 0:
return {"error": data.get("errorDescription")}
task_id = data["taskId"]
# Poll
for _ in range(60):
time.sleep(5)
result = requests.post(f"{BASE_URL}/getTaskResult", json={
"clientKey": CLIENT_KEY,
"taskId": task_id
}).json()
if result.get("status") == "ready":
return {"solution": result["solution"]["gRecaptchaResponse"]}
if result.get("errorId") != 0:
return {"error": result.get("errorDescription")}
return {"error": "TIMEOUT"}
Python — après (CaptchaAI)
import os
import time
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_recaptcha_v2(sitekey, pageurl):
# Submit — different endpoint and format
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {"error": data.get("request")}
captcha_id = data["request"]
# Poll — GET instead of POST, different response format
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": captcha_id,
"json": 1
}).json()
if result.get("status") == 1:
return {"solution": result["request"]}
if result.get("request") != "CAPCHA_NOT_READY":
return {"error": result.get("request")}
return {"error": "TIMEOUT"}
JavaScript — avant (NextCaptcha)
const axios = require("axios");
const CLIENT_KEY = "your_nextcaptcha_key";
const BASE_URL = "https://api.nextcaptcha.com";
async function solveRecaptchaV2(sitekey, pageurl) {
const submit = await axios.post(`${BASE_URL}/createTask`, {
clientKey: CLIENT_KEY,
task: {
type: "RecaptchaV2TaskProxyless",
websiteURL: pageurl,
websiteKey: sitekey,
},
});
if (submit.data.errorId !== 0) return { error: submit.data.errorDescription };
const taskId = submit.data.taskId;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const poll = await axios.post(`${BASE_URL}/getTaskResult`, {
clientKey: CLIENT_KEY,
taskId,
});
if (poll.data.status === "ready") return { solution: poll.data.solution.gRecaptchaResponse };
if (poll.data.errorId !== 0) return { error: poll.data.errorDescription };
}
return { error: "TIMEOUT" };
}
JavaScript — après (CaptchaAI)
const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;
async function solveRecaptchaV2(sitekey, pageurl) {
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: { key: API_KEY, method: "userrecaptcha", googlekey: sitekey, pageurl, json: 1 },
});
if (submit.data.status !== 1) return { error: submit.data.request };
const captchaId = submit.data.request;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const poll = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
});
if (poll.data.status === 1) return { solution: poll.data.request };
if (poll.data.request !== "CAPCHA_NOT_READY") return { error: poll.data.request };
}
return { error: "TIMEOUT" };
}
Différences dans le format des réponses
NextCaptcha renvoie un errorId et un statut textuel ; CaptchaAI, un status entier et un champ request polyvalent.
| Phase | Champ | NextCaptcha | CaptchaAI |
|---|---|---|---|
| Soumission | Contrôle de réussite | errorId === 0 |
status === 1 |
| Soumission | ID de tâche | taskId (entier) |
request (chaîne) |
| Soumission | Message d'erreur | errorDescription |
request (code en chaîne) |
| Interrogation | Contrôle « prêt » | status === "ready" |
status === 1 |
| Interrogation | En cours de traitement | status === "processing" |
request === "CAPCHA_NOT_READY" |
| Interrogation | Solution | solution.gRecaptchaResponse |
request |
| Interrogation | Erreur | errorDescription |
request (code d'erreur) |
Liste de contrôle pour la migration
Déroulez ces étapes dans l'ordre.
- ☐ Créer un compte CaptchaAI et créditer le solde
- ☐ Faire correspondre chaque type
createTaskà une méthode CaptchaAI - ☐ Remplacer
clientKeypar votre clé API CaptchaAI - ☐ Passer la soumission du POST JSON au POST de formulaire
- ☐ Passer l'interrogation du POST au GET avec paramètres d'URL
- ☐ Adapter l'analyse des réponses (format status/request)
- ☐ Lancer un test comparatif en parallèle
- ☐ Basculer le trafic de production
Dépannage
| Problème | Cause | Correctif |
|---|---|---|
ERROR_KEY_DOES_NOT_EXIST |
Utilisation du clientKey NextCaptcha |
Le remplacer par la clé API CaptchaAI |
| L'analyse des réponses casse | Structure JSON différente | Vérifier les champs status (entier) et request |
ERROR_WRONG_USER_KEY |
Clé API mal formée | Contrôler le format de la clé dans le tableau de bord CaptchaAI |
| Types de tâches non reconnus | Noms de types NextCaptcha conservés | Utiliser les valeurs method de CaptchaAI (voir le tableau plus haut) |
FAQ
Faut-il réécrire toute mon intégration pour passer à CaptchaAI ?
Non. Votre logique reste identique : seuls changent les deux endpoints, le format d'envoi et la lecture de status/request.
CaptchaAI prend-il en charge hCaptcha et FunCaptcha comme NextCaptcha ?
Non — hCaptcha et FunCaptcha (Arkose Labs) ne sont pas pris en charge à ce jour. Prévoyez une solution distincte pour ces flux ; tout le reste bascule normalement.
Comment tester CaptchaAI sans couper NextCaptcha ?
Faites tourner les deux services en parallèle : envoyez un échantillon aux deux API et comparez taux de réussite et temps de résolution. La bascule ne touchant que vos appels réseau, rien à redéployer chez OVHcloud, Scaleway ou ailleurs. Une fois les résultats stables, basculez un type à la fois, en minimisant les données personnelles journalisées (RGPD).
CaptchaAI peut-il notifier mon serveur quand une résolution est prête ?
Oui. Passez le paramètre pingback avec une URL : CaptchaAI y envoie le résultat par POST dès qu'il est prêt, l'équivalent du callback de NextCaptcha. Sinon, interrogez res.php toutes les 5 secondes.
Prochaines étapes
Créez votre compte CaptchaAI et basculez en quelques minutes.
Guides associés :