Reference

Переход с EndCaptcha на CaptchaAI: руководство по сопоставлению API

По сути миграция с EndCaptcha на CaptchaAI сводится к трём заменам:

  • пара «имя пользователя + пароль» → один API-ключ;
  • SOAP/XML-вызовы → два REST-эндпоинта, in.php и res.php;
  • разбор XML → разбор JSON.

Логика «отправить задачу → опрашивать результат» остаётся прежней, поэтому переписывать интеграцию с нуля не нужно. Ниже каждый вызов EndCaptcha сопоставлен с эквивалентом CaptchaAI, приведён готовый код на Python и Node.js и план параллельного перехода без простоя.

Чем отличается архитектура API

EndCaptcha построен на SOAP/XML, CaptchaAI — на REST: запрос уходит обычным HTTP-методом, ответ приходит в JSON.

Аспект EndCaptcha CaptchaAI
Протокол SOAP/XML или HTTP POST HTTP POST/GET (REST)
Отправка задачи /Captcha/Upload или WSDL https://ocr.captchaai.com/in.php
Получение результата /Captcha/GetText или WSDL https://ocr.captchaai.com/res.php
Авторизация Имя пользователя + пароль API-ключ
Формат ответа XML/собственный JSON (json=1) или обычный текст

Соответствие параметров запроса

Главное отличие — вместо двух полей аутентификации у CaptchaAI один key.

Параметр EndCaptcha Параметр CaptchaAI Примечания
username key В CaptchaAI один API-ключ
password Не нужен; аутентификацию покрывает API-ключ
captchaData (base64) body (base64) Те же данные изображения в base64
captchaType method Разные идентификаторы типов
siteKey googlekey Для типов reCAPTCHA
pageUrl pageurl Та же концепция, другой регистр букв
captchaId id ID задачи для опроса

Соответствие типов CAPTCHA

Числовые коды captchaType заменяются именами методов CaptchaAI.

Тип EndCaptcha Метод CaptchaAI Параметры CaptchaAI
Капча-изображение method=base64 body={base64_image}
reCAPTCHA v2 method=userrecaptcha googlekey, pageurl

Важное отличие в покрытии: hCaptcha CaptchaAI пока не поддерживает (), поэтому не переносите вызовы hCaptcha в код миграции — для них понадобится отдельное решение. CaptchaAI решает reCAPTCHA v2/v3, Cloudflare Turnstile и Challenge, GeeTest v3, изображения, grid и BLS.

На что обратить внимание после переноса

Правок в коде чаще всего требуют три вещи: аутентификация, чтение поля ошибки и вспомогательные операции (баланс, жалоба на решение). Держите эту таблицу под рукой, пока переписываете функции.

Область EndCaptcha CaptchaAI
Аутентификация Пара «имя пользователя + пароль» Единый API-ключ
Формат ошибки Собственный JSON с полем error Стандартное поле request с кодами ошибок
Опрос результата POST на отдельный эндпоинт GET-запрос к res.php с параметрами
Проверка баланса Отдельный метод SOAP res.php?action=getbalance&key=KEY
Жалоба на решение Отдельный метод res.php?action=reportbad&id=ID&key=KEY

Перенос кода: до и после

Структура функции не меняется — отправка, цикл опроса, возврат; меняются URL, поля запроса и разбор ответа.

Python: было (EndCaptcha)

import requests

USERNAME = "your_endcaptcha_user"
PASSWORD = "your_endcaptcha_pass"

def solve_image_endcaptcha(image_base64):
    # EndCaptcha image solve
    resp = requests.post("https://api.endcaptcha.com/Captcha/Upload", data={
        "username": USERNAME,
        "password": PASSWORD,
        "captchaData": image_base64,
        "captchaType": "1"
    })
    result = resp.json()
    captcha_id = result.get("captchaId")

    import time
    for _ in range(30):
        time.sleep(5)
        poll = requests.post("https://api.endcaptcha.com/Captcha/GetText", data={
            "username": USERNAME,
            "password": PASSWORD,
            "captchaId": captcha_id
        })
        poll_result = poll.json()
        if poll_result.get("text"):
            return {"solution": poll_result["text"]}
        if poll_result.get("error"):
            return {"error": poll_result["error"]}

    return {"error": "TIMEOUT"}

Python: стало (CaptchaAI)

import os
import time
import requests

API_KEY = os.environ["CAPTCHAAI_API_KEY"]

def solve_image_captchaai(image_base64):
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_base64,
        "json": 1
    })
    data = resp.json()
    if data.get("status") != 1:
        return {"error": data.get("request")}

    captcha_id = data["request"]

    for _ in range(30):
        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"}

Обратите внимание на разбор ответа: успех — это status == 1, а само решение лежит в поле request, а не в text, как было у EndCaptcha.

Python: reCAPTCHA v2 (CaptchaAI)

def solve_recaptcha_v2(sitekey, pageurl):
    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"]

    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"}

Для токен-капч (reCAPTCHA, Turnstile) увеличьте число итераций опроса: они решаются дольше, чем изображения, поэтому здесь цикл рассчитан на 60 попыток вместо 30.

JavaScript: было (EndCaptcha)

const axios = require("axios");

const USERNAME = "your_endcaptcha_user";
const PASSWORD = "your_endcaptcha_pass";

async function solveImageEndCaptcha(imageBase64) {
  const submit = await axios.post("https://api.endcaptcha.com/Captcha/Upload", {
    username: USERNAME,
    password: PASSWORD,
    captchaData: imageBase64,
    captchaType: "1",
  });
  const captchaId = submit.data.captchaId;

  for (let i = 0; i < 30; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.post("https://api.endcaptcha.com/Captcha/GetText", {
      username: USERNAME,
      password: PASSWORD,
      captchaId,
    });
    if (poll.data.text) return { solution: poll.data.text };
    if (poll.data.error) return { error: poll.data.error };
  }
  return { error: "TIMEOUT" };
}

JavaScript: стало (CaptchaAI)

const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;

async function solveImageCaptchaAI(imageBase64) {
  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: { key: API_KEY, method: "base64", body: imageBase64, json: 1 },
  });
  if (submit.data.status !== 1) return { error: submit.data.request };

  const captchaId = submit.data.request;

  for (let i = 0; i < 30; 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" };
}

Диагностика типичных ошибок

Проблема Причина Решение
ERROR_KEY_DOES_NOT_EXIST Используется имя пользователя EndCaptcha вместо API-ключа Возьмите API-ключ CaptchaAI из панели управления
Ошибка разбора ответа Другая структура JSON Проверяйте поля status и request, а не captchaId/text
Отсутствует параметр method В EndCaptcha тип задаётся числовым captchaType Сопоставьте с именами методов CaptchaAI (base64, userrecaptcha)
Тайм-аут на reCAPTCHA Другие тайм-ауты по умолчанию Задайте опрос 60 итераций × 5 с для токен-капч

Чек-лист миграции

Шаг Статус
Создать аккаунт CaptchaAI и получить API-ключ
Сопоставить все вызовы EndCaptcha с эквивалентами CaptchaAI
Заменить аутентификацию (имя пользователя/пароль → API-ключ)
Обновить эндпоинт отправки (/Captcha/Upload/in.php)
Обновить эндпоинт опроса (/Captcha/GetText/res.php)
Обновить разбор ответа (status / request)
Прогнать параллельный тест с обоими провайдерами
Переключить боевой трафик
Удалить учётные данные EndCaptcha

Параллельный прогон удобно встроить в существующий пайплайн: например, агентство в Алма-Ате неделю шлёт каждую капчу в оба сервиса, сравнивает решения и время ответа и только потом убирает EndCaptcha. Для команд, выставляющих счета в нестабильной валюте, оплата по потокам в USD (от BASIC — $15/мес, 5 потоков) делает бюджет предсказуемым: вы платите за число одновременных потоков, а не за каждое решение.

Частые вопросы

Нужно ли переписывать логику опроса при переходе на CaptchaAI?

Нет, цикл остаётся тем же: отправили задачу, получили id, опрашиваете res.php. Меняется критерий готовности — вместо поля text проверяете status == 1, а «ещё не готово» приходит как request == "CAPCHA_NOT_READY".

Что делать с hCaptcha после перехода с EndCaptcha?

hCaptcha пока не входит в поддерживаемые типы CaptchaAI (), поэтому не переносите такие вызовы «как есть». CaptchaAI решает reCAPTCHA v2/v3, Turnstile и Cloudflare Challenge, GeeTest v3, изображения, grid и BLS; CaptchaFox (beta), Friendly Captcha (beta) и Lemin (beta) — в бета-режиме.

Можно ли оставить ту же настройку прокси?

Да. CaptchaAI принимает proxy=user:pass@host:port и proxytype=HTTP|SOCKS5, как и большинство сервисов. Значения прокси из конфигурации EndCaptcha переносятся напрямую.

Как проверить баланс через API?

Через res.php доступны служебные действия, которые в EndCaptcha были отдельными методами:

  • action=getbalance — вернуть текущий баланс;
  • action=reportbad&id=ID — пожаловаться на неверное решение.

Тарификация идёт по числу одновременных потоков: поток — это одна капча в обработке, число решений в месяц на поток не ограничено.

Что дальше

Комментарии для этой статьи отключены.