Referencia

Migrar de AZCaptcha a CaptchaAI sin reescribir tu código

Si ya tienes AZCaptcha integrado, cambiar a CaptchaAI no significa rehacer tu integración: en la práctica ajustas dos cosas, la URL base y la clave API. El resto —el método, los parámetros y el formato de respuesta— sigue igual, porque ambos servicios hablan el mismo dialecto de API compatible con 2Captcha.

Es una tarea de minutos. Aquí tienes la equivalencia de endpoints, los parámetros, el código antes y después, y cómo validar el cambio con una prueba en paralelo.

Qué cambia realmente al migrar

Tu integración actual envía una tarea a in.php, recibe un id y sondea el resultado en res.php. En la práctica, la migración toca muy poco:

  • Cambia: la URL base (de azcaptcha.com a ocr.captchaai.com) y la clave API.
  • No cambia: el method, los parámetros (googlekey, pageurl, json), la lógica de sondeo ni el formato de respuesta.

Un ejemplo típico: una agencia en Madrid o Ciudad de México que corre monitoreo de precios o QA, factura a sus clientes en moneda local y paga las herramientas en USD.

Ahí pesa el modelo de precio: CaptchaAI factura por thread, no por resolución —BASIC arranca en $15/mes con 5 threads y resoluciones ilimitadas por thread—, y un costo fijo en USD es más fácil de presupuestar.

CaptchaAI resuelve los tipos que suele usar ese flujo: reCAPTCHA v2 y v3, Cloudflare Turnstile y Cloudflare Challenge, GeeTest v3, imagen/OCR y grid, y BLS. El method que ya usas para reCAPTCHA (userrecaptcha) es idéntico.

Antes de empezar

Para seguir esta guía sin sorpresas necesitas tres cosas:

  • Una integración de AZCaptcha que ya funcione en producción.
  • Acceso al código donde llamas a in.php y res.php.
  • Una cuenta de CaptchaAI con saldo; el plan BASIC ($15/mes) basta para las pruebas.

Equivalencia de endpoints

Solo cambia el host; la correspondencia es directa:

Acción AZCaptcha CaptchaAI
Enviar tarea https://azcaptcha.com/in.php https://ocr.captchaai.com/in.php
Obtener resultado https://azcaptcha.com/res.php https://ocr.captchaai.com/res.php
Consultar saldo res.php?action=getbalance res.php?action=getbalance
Reportar resolución incorrecta res.php?action=reportbad res.php?action=reportbad

Consultar el saldo e informar resoluciones incorrectas usan las mismas rutas de res.php, así que ese código tampoco cambia.

Parámetros que se mantienen igual

La mayoría de los parámetros son idénticos. Las diferencias que importan:

Parámetro AZCaptcha CaptchaAI Notas
key clave API clave API Clave distinta: consigue la tuya en captchaai.com
method userrecaptcha userrecaptcha Igual
googlekey sitekey sitekey Igual
pageurl URL de la página URL de la página Igual
json 1 1 Igual
proxy user:pass@host:port user:pass@host:port Mismo formato
proxytype HTTP/SOCKS5 HTTP/SOCKS5 Igual

Dos consecuencias prácticas:

  • Reutilizas tu configuración de proxy y proxytype sin ningún cambio.
  • Lo único nuevo que generas es la clave, en captchaai.com.

Migración paso a paso

El recorrido tiene cuatro pasos, del alta a la puesta en producción:

  • Consigue tu clave API y añade saldo.
  • Sustituye la URL base y externaliza la clave.
  • Abstrae el proveedor detrás de una interfaz común.
  • Valida con una prueba en paralelo antes de cambiar el tráfico.

Paso 1: consigue tu clave API de CaptchaAI

  1. Regístrate en captchaai.com
  2. Añade saldo a tu cuenta
  3. Copia tu clave API desde el panel de control

Guarda esa clave fuera del código, en una variable de entorno, no en un literal.

Paso 2: actualiza tu código

Sustituye el host en las llamadas a in.php y res.php, y lee la clave desde una variable de entorno.

Compara el antes y el después:

Python: antes (AZCaptcha)

import requests

API_KEY = "your_azcaptcha_key"

def solve_recaptcha(sitekey, pageurl):
    # Submit
    resp = requests.post("https://azcaptcha.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1
    })
    data = resp.json()
    if data["status"] != 1:
        return {"error": data["request"]}

    captcha_id = data["request"]

    # Poll
    import time
    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://azcaptcha.com/res.php", params={
            "key": API_KEY, "action": "get", "id": captcha_id, "json": 1
        }).json()
        if result["status"] == 1:
            return {"solution": result["request"]}
        if result["request"] != "CAPCHA_NOT_READY":
            return {"error": result["request"]}

    return {"error": "TIMEOUT"}

Python: después (CaptchaAI)

import os
import time
import requests

API_KEY = os.environ["CAPTCHAAI_API_KEY"]  # Changed: use env var

def solve_recaptcha(sitekey, pageurl):
    # Submit — only URL changed
    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 — only URL changed
    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"}

El mismo ajuste —host y clave— en JavaScript con Axios:

JavaScript: antes (AZCaptcha)

const axios = require("axios");
const API_KEY = "your_azcaptcha_key";

async function solveRecaptcha(sitekey, pageurl) {
  const submit = await axios.post("https://azcaptcha.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://azcaptcha.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" };
}

JavaScript: después (CaptchaAI)

const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;  // Changed: env var

async function solveRecaptcha(sitekey, pageurl) {
  // Only URLs changed
  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" };
}

Paso 3: abstrae el proveedor detrás de una interfaz

Para una transición más segura, con opción de volver atrás, encapsula el proveedor en una clase; cambiar de servicio se reduce a una línea:

import os
import time
import requests


class CaptchaProvider:
    def __init__(self, base_url, api_key):
        self.submit_url = f"{base_url}/in.php"
        self.result_url = f"{base_url}/res.php"
        self.api_key = api_key
        self.session = requests.Session()

    def solve(self, sitekey, pageurl, method="userrecaptcha"):
        resp = self.session.post(self.submit_url, data={
            "key": self.api_key,
            "method": method,
            "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 = self.session.get(self.result_url, params={
                "key": self.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"}


# Switch by changing one line:
# provider = CaptchaProvider("https://azcaptcha.com", "old_key")
provider = CaptchaProvider(
    "https://ocr.captchaai.com",
    os.environ["CAPTCHAAI_API_KEY"]
)

Paso 4: prueba en paralelo antes de cambiar

Corre ambos proveedores sobre los mismos CAPTCHA y compara tasa de éxito y tiempo de resolución:

def parallel_test(sitekey, pageurl, runs=10):
    azcaptcha = CaptchaProvider("https://azcaptcha.com", "old_key")
    captchaai = CaptchaProvider(
        "https://ocr.captchaai.com",
        os.environ["CAPTCHAAI_API_KEY"]
    )

    results = {"azcaptcha": [], "captchaai": []}

    for i in range(runs):
        start = time.time()
        az_result = azcaptcha.solve(sitekey, pageurl)
        results["azcaptcha"].append({
            "success": "solution" in az_result,
            "time": time.time() - start
        })

        start = time.time()
        cai_result = captchaai.solve(sitekey, pageurl)
        results["captchaai"].append({
            "success": "solution" in cai_result,
            "time": time.time() - start
        })

    for provider, data in results.items():
        successes = sum(1 for r in data if r["success"])
        avg_time = sum(r["time"] for r in data) / len(data)
        print(f"{provider}: {successes}/{runs} success, {avg_time:.1f}s avg")

Checklist de migración

Recorre esta lista antes de dar por cerrado el cambio y desmantelar la clave antigua:

Paso Estado
Crear la cuenta de CaptchaAI y añadir saldo
Reemplazar la URL base en todos los archivos
Mover la clave API a una variable de entorno
Ejecutar la prueba en paralelo (más de 10 resoluciones)
Comparar las tasas de éxito
Comparar los tiempos de resolución
Actualizar el monitoreo y las alertas para los nuevos endpoints
Cambiar el tráfico de producción
Vigilar el comportamiento durante 24 horas
Dar de baja la clave de AZCaptcha

Errores comunes y cómo resolverlos

Estos son los tropiezos más habituales justo después del cambio, con su causa y su arreglo:

Problema Causa Solución
ERROR_KEY_DOES_NOT_EXIST Clave API incorrecta Verifica la clave API en el panel de control
ERROR_ZERO_BALANCE Cuenta nueva sin saldo Añade saldo en captchaai.com
Códigos de error distintos Diferencias menores entre servicios Mapea los códigos; la mayoría son idénticos
La tasa de resolución no coincide Distintos grupos de solvers Ejecuta más de 50 resoluciones de prueba para una comparación válida

Preguntas frecuentes

Las dudas que suelen aparecer al planificar el cambio:

¿Tengo que cambiar el método o los parámetros de mi código?

No. El method (userrecaptcha para reCAPTCHA) y parámetros como googlekey, pageurl y json son idénticos. Solo cambian el host de los endpoints y la clave API.

¿Qué tipos de CAPTCHA puedo resolver después de migrar?

reCAPTCHA v2 y v3, Cloudflare Turnstile y Cloudflare Challenge, GeeTest v3, imagen/OCR, grid y BLS. Si usabas reCAPTCHA en AZCaptcha, el código sigue igual.

¿Cómo funciona el precio frente al pago por resolución?

CaptchaAI factura por thread, no por resolución: cada plan incluye resoluciones ilimitadas por thread al mes y BASIC arranca en $15/mes con 5 threads. Para volúmenes constantes, un costo fijo en USD es más predecible.

¿Puedo mantener AZCaptcha y CaptchaAI a la vez durante la transición?

Sí, y es lo recomendable. Con la clase CaptchaProvider corres ambos en paralelo y solo desmantelas la clave de AZCaptcha cuando el nuevo flujo lleva 24 horas estable.

Empieza tu migración

Pásate a una resolución de CAPTCHA estable: consigue tu clave API de CaptchaAI y migra en minutos.

Guías relacionadas:

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