Переход с NextCaptcha на CaptchaAI не требует переписывать логику решения CAPTCHA — меняются только эндпоинт, формат тела запроса (JSON → form-data) и поля ответа (status/request вместо errorId/taskId). Дальше — по шагам: что делать, как сопоставляются оба API и готовый код на Python и JavaScript, который можно взять за основу.
Чек-лист миграции: что нужно сделать
- Создать аккаунт CaptchaAI и пополнить баланс.
- Сопоставить все типы
createTaskс методами CaptchaAI (таблица ниже). - Заменить
clientKeyна API-ключ CaptchaAI. - Перевести отправку из JSON-тела POST в form-data POST.
- Перевести опрос с POST на GET с query-параметрами.
- Обновить разбор ответа под формат
status/request. - Запустить параллельный сравнительный тест на части трафика.
- Постепенно перевести оставшийся продакшн-трафик.
Сопоставление эндпоинтов NextCaptcha и CaptchaAI
| Действие | NextCaptcha | CaptchaAI |
|---|---|---|
| Отправить задачу | POST /createTask |
POST https://ocr.captchaai.com/in.php |
| Получить результат | POST /getTaskResult |
GET https://ocr.captchaai.com/res.php |
| Проверить баланс | POST /getBalance |
GET res.php?action=getbalance&key=KEY |
JSON против form-data: как отличается тело запроса
Как выглядит запрос в NextCaptcha (тело JSON)
{
"clientKey": "next_captcha_key",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}
}
Тот же запрос в CaptchaAI (параметры формы)
POST https://ocr.captchaai.com/in.php
key=YOUR_API_KEY&method=userrecaptcha&googlekey=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-&pageurl=https://example.com&json=1
Поля запроса и типы задач
Прямое соответствие полей между API:
clientKey→key— API-ключ.task.type→method— см. сопоставление типов ниже.task.websiteURL→pageurl— URL целевой страницы.task.websiteKey→googlekeyилиsitekey— ключ сайта для токена CAPTCHA.task.recaptchaDataSValue→data-s— параметр reCAPTCHA.task.isInvisible→invisible=1— невидимая reCAPTCHA.task.pageAction→action— действие reCAPTCHA v3.taskId→id— ID задачи для опроса.
Сопоставление типов задач
| Тип задачи NextCaptcha | Метод + параметры CaptchaAI |
|---|---|
RecaptchaV2TaskProxyless |
method=userrecaptcha |
RecaptchaV2Task |
method=userrecaptcha + proxy, proxytype |
ImageToTextTask |
method=base64 + body |
TurnstileTaskProxyless |
method=turnstile |
HCaptchaTaskProxyless/HCaptchaTask аналога не имеют: hCaptcha CaptchaAI пока не поддерживает, такие задачи придётся временно оставить на другом провайдере.
Миграция кода: Python и JavaScript
Python — было (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 — стало (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 — было (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 — стало (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" };
}
Формат ответа: что меняется в парсинге
Ответ на отправку задачи:
- Проверка успеха:
errorId === 0(NextCaptcha) →status === 1(CaptchaAI). - Идентификатор задачи:
taskId, целое число →request, строка. - Сообщение об ошибке:
errorDescription→request(строка с кодом ошибки).
Ответ при опросе:
- Проверка готовности:
status === "ready"→status === 1. - Ещё не готово:
status === "processing"→request === "CAPCHA_NOT_READY". - Решение:
solution.gRecaptchaResponse→request. - Ошибка:
errorDescription→request(код ошибки).
Совет: заведите общую функцию-адаптер для разбора ответа CaptchaAI (
status/request), а не проверяйте условия россыпью по коду — так меньше шансов пропустить место, где ещё ждут старый формат NextCaptcha.
Типичные ошибки при переходе
ERROR_KEY_DOES_NOT_EXIST— в запросе всё ещё передаётсяclientKeyот NextCaptcha; замените его на API-ключ CaptchaAI.- Разбор ответа падает с ошибкой — код рассчитан на JSON-структуру NextCaptcha; проверяйте поля
status(число) иrequest, структура CaptchaAI другая. ERROR_WRONG_USER_KEY— API-ключ передан в неверном формате; сверьте его с панелью управления CaptchaAI.- Тип задачи не распознаётся — в коде остались названия типов NextCaptcha (
RecaptchaV2TaskProxylessи подобные); сопоставьте их со значениямиmethodиз таблицы выше.
Пример: параллельный запуск для парсинг-команды
Команда, которая парсит витрины или проверяет доступность товаров под нагрузкой, обычно не отключает NextCaptcha резко: часть трафика (например, 10–20% задач по хэшу) направляется в CaptchaAI параллельно, остальное — как раньше, а провайдеры сравниваются по доле успешных решений и времени ответа на одних и тех же типах CAPTCHA. Для такого теста хватает тарифа BASIC ($15/мес, 5 потоков) — он покрывает репрезентативный объём задач до полного переключения.
Совет: если инфраструктура парсера развёрнута в европейских регионах или в Казахстане, отдельно замерьте RTT до
ocr.captchaai.com, а не полагайтесь на цифры из документации — реальная сетевая задержка зависит от маршрута конкретного провайдера.
FAQ
CaptchaAI принимает JSON-тело запроса, как в NextCaptcha, или только form-data?
Оба варианта. in.php штатно работает с form-data, но принимает и JSON — часть клиентского кода можно оставить без изменений, сменив только эндпоинт и имена полей.
Что делать с задачами, которые уже стоят в очереди NextCaptcha на момент переключения?
Не обрывайте их резко. Держите оба интеграционных пути активными до полного израсходования очереди NextCaptcha, направляя в CaptchaAI только новые задачи.
Нужно ли получать новый sitekey при переходе на CaptchaAI?
Нет. sitekey/googlekey — это идентификатор виджета CAPTCHA на стороне целевого сайта, а не значение, которое выдаёт провайдер-решатель. Он остаётся тем же, меняется только имя поля в запросе.
Поддерживает ли CaptchaAI callback/webhook, как NextCaptcha?
Да. Параметр pingback принимает URL, на который CaptchaAI отправит POST с результатом сразу после решения — аналог callback-механизма NextCaptcha, только без отдельного колбэк-эндпоинта.