Referencia

Migrar de EndCaptcha a CaptchaAI: guía de mapeo de la API

Migrar de EndCaptcha a CaptchaAI es, en la práctica, cambiar dos endpoints y una forma de autenticarte. EndCaptcha expone una API SOAP/XML con nombres de método propios y un par usuario/contraseña; CaptchaAI usa una API REST con in.php y res.php y una única clave API. Solo cambian tres cosas —el endpoint, la autenticación y el formato de respuesta—; el patrón de enviar, recibir un id y sondear se conserva. Esta guía mapea cada llamada a su equivalente en CaptchaAI.

Diferencias de arquitectura entre las dos APIs

Aspecto EndCaptcha CaptchaAI
Protocolo SOAP/XML o HTTP POST HTTP POST/GET (REST)
Envío /Captcha/Upload o WSDL https://ocr.captchaai.com/in.php
Resultado /Captcha/GetText o WSDL https://ocr.captchaai.com/res.php
Autenticación Usuario + contraseña Clave API
Respuesta XML/propietario JSON (json=1) o texto plano

Mapeo de parámetros de EndCaptcha a CaptchaAI

Casi todos los campos tienen equivalente directo; la contraseña desaparece, porque la clave API autentica cada solicitud.

Parámetro EndCaptcha Parámetro CaptchaAI Notas
username key Una única clave API
password No hace falta; la clave API autentica
captchaData (base64) body (base64) Mismos datos base64
captchaType method Distintos identificadores de tipo
siteKey googlekey Para los tipos reCAPTCHA
pageUrl pageurl Distinta capitalización
captchaId id ID de tarea para sondear

Equivalencias de tipos de CAPTCHA

Tipo en EndCaptcha Método CaptchaAI Parámetros CaptchaAI
CAPTCHA de imagen method=base64 body={base64_image}
reCAPTCHA v2 method=userrecaptcha googlekey, pageurl
Cloudflare Turnstile method=turnstile sitekey, pageurl

Ojo al planificar: CaptchaAI no resuelve hCaptcha ni FunCaptcha (Arkose Labs) por ahora. Sí cubre reCAPTCHA v2/v3, Cloudflare Turnstile y Challenge, GeeTest v3, imagen/OCR y grid.

Migración del código, paso a paso

El patrón es idéntico en Python y JavaScript: enviar a in.php, comprobar status, guardar el id y sondear res.php hasta que deje de responder CAPCHA_NOT_READY.

Python — antes (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 — después (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"}

Python — reCAPTCHA v2 con 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"}

JavaScript — antes (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 — después (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" };
}

Diferencias operativas que conviene vigilar

  • Autenticación: de un par usuario + contraseña a una única clave API.
  • Formato de error: de un JSON propietario con campo error al campo estándar request con códigos.
  • Sondeo: de un POST a otro endpoint a un GET sobre res.php con query params.
  • Consulta de saldo: res.php?action=getbalance&key=KEY.
  • Reportar un fallo: res.php?action=reportbad&id=ID&key=KEY.

Solución de problemas frecuentes

  • ERROR_KEY_DOES_NOT_EXIST: estás usando el usuario de EndCaptcha, no la clave API; cópiala desde el panel.
  • El parser falla: la estructura JSON es distinta, así que lee los campos status y request.
  • Falta el parámetro method: EndCaptcha numera con captchaType; usa los métodos de CaptchaAI (base64, userrecaptcha, etc.).
  • Se agota el tiempo en reCAPTCHA: sondea 60 iteraciones × 5 s para los CAPTCHA de token.

Checklist de migración de EndCaptcha a CaptchaAI

  • [ ] Crear la cuenta en CaptchaAI.
  • [ ] Mapear las llamadas de EndCaptcha a sus equivalentes de CaptchaAI.
  • [ ] Reemplazar la autenticación (usuario/contraseña → clave API).
  • [ ] Actualizar el endpoint de envío (/Captcha/Uploadin.php).
  • [ ] Actualizar el endpoint de consulta (/Captcha/GetTextres.php).
  • [ ] Ajustar el análisis de la respuesta.
  • [ ] Probar en paralelo con ambos proveedores.
  • [ ] Cambiar el tráfico de producción y eliminar las credenciales de EndCaptcha.

Preguntas frecuentes

¿Cuánto código real tengo que tocar para migrar?

Poco. Cambias dos URLs, sustituyes usuario/contraseña por key y ajustas el parser para leer status y request. El bucle de sondeo se reutiliza.

¿Puedo correr EndCaptcha y CaptchaAI en paralelo durante el cambio?

Sí, y es lo recomendable. Envía una fracción del tráfico a CaptchaAI, compara soluciones y latencias, y sube el porcentaje poco a poco. Retira las credenciales antiguas cuando te convenzan los resultados.

¿Sirve mi misma configuración de proxy?

Sí. CaptchaAI acepta proxy=user:pass@host:port y proxytype=HTTP|SOCKS5, así que reutilizas tu configuración con cambios mínimos.

¿Qué hago con el endpoint SOAP/WSDL de EndCaptcha?

No lo necesitas. CaptchaAI no tiene API SOAP: cada llamada se traduce a un único HTTP POST o GET contra in.php/res.php, lo que suele reducir tu código.

Artículos relacionados

Próximos pasos

CaptchaAI factura por thread concurrente, no por resolución: desde $15/mes (BASIC, 5 threads), con coste mensual predecible en USD —cómodo para agencias que facturan en monedas locales volátiles—. Simplifica tu resolución de CAPTCHA con la API REST: obtén tu clave API y empieza hoy.

Guías relacionadas:

Los comentarios están deshabilitados para este artículo.