Reference

Migrar de AZCaptcha para CaptchaAI: guia completo

Trocar de provedor sem quebrar produção é a maior preocupação em qualquer migração de captcha solver — e a boa notícia é que AZCaptcha e CaptchaAI compartilham o mesmo formato de API compatível com 2Captcha. Na prática você muda dois valores: a URL base e a chave de API. O restante do fluxo — parâmetros, resposta em JSON, lógica de polling — continua igual.

Para uma base de código única, o trabalho leva entre 15 e 30 minutos, incluindo um teste paralelo para confirmar que tudo se comporta como esperado antes de desligar a chave antiga. Este guia mostra o que muda, o roteiro de 4 etapas para migrar sem downtime e uma referência completa de endpoints e parâmetros para consultar durante o código.

O que muda e o que continua igual

  • URL base — muda: de azcaptcha.com para ocr.captchaai.com.
  • Chave de API — muda: gere uma nova em captchaai.com, não reaproveite a antiga.
  • Parâmetros de requisição (method, googlekey, pageurl, json, proxy) — não mudam.
  • proxytype — não muda: continua aceitando HTTP e SOCKS5.
  • Formato da resposta JSON (status, request) — não muda.
  • Lógica de polling (consultar res.php até status == 1) — não muda.

Migração em 4 etapas

Etapa 1: crie e financie sua conta CaptchaAI

  1. Inscreva-se em captchaai.com
  2. Adicione créditos à conta
  3. Copie sua chave de API no painel

Guarde a chave em uma variável de ambiente desde o início — é o que os exemplos abaixo já assumem, e evita ter que caçar chaves hardcoded no código depois.

Etapa 2: troque a URL base no código

A mudança real está só na URL e na origem da chave. No Python, compare o solve_recaptcha de antes — com a URL e a chave do AZCaptcha hardcoded — com a versão depois, já apontando para ocr.captchaai.com e lendo a chave do ambiente.

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

Se seu stack é Node.js em vez de Python, a mudança é a mesma coisa em outra sintaxe — só as URLs se movem:

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 - Depois (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" };
}

Etapa 3: encapsule o provedor em uma classe reutilizável

Se você atende mais de um projeto, ou pode precisar trocar de provedor de novo no futuro, não hardcode a URL em cada chamada. Encapsule tudo numa classe: trocar de provedor vira uma linha, não um find-and-replace pelo repositório inteiro.

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"]
)

Etapa 4: rode um teste paralelo antes de virar de vez

Nunca migre tráfego de produção só porque o código compilou. Rode os dois provedores lado a lado num mesmo lote de tarefas e compare taxa de sucesso e tempo de resolução antes de desativar o AZCaptcha.

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

Se os seus workers rodam no Brasil — por exemplo em sa-east-1 (São Paulo) na AWS —, meça também o RTT até cada endpoint: parte da diferença em time.time() pode vir da distância até o datacenter, não da resolução em si. Rode ao menos 50 tarefas antes de concluir algo — com apenas 10, uma solução lenta já distorce a média.

Checklist de corte: o que não pode faltar antes da virada

  • [ ] Crie a conta na CaptchaAI e adicione créditos
  • [ ] Troque a URL base em todos os arquivos do projeto
  • [ ] Atualize a chave de API (use variável de ambiente)
  • [ ] Rode o teste paralelo (10+ resoluções)
  • [ ] Compare as taxas de sucesso
  • [ ] Compare os tempos de resolução
  • [ ] Atualize monitoramento e alertas para os novos endpoints
  • [ ] Migre o tráfego de produção
  • [ ] Monitore por 24 horas
  • [ ] Desative a chave do AZCaptcha

Erros comuns na migração e como resolver

ERROR_KEY_DOES_NOT_EXIST

Geralmente é chave de API incorreta. Confira a chave da CaptchaAI no painel e confirme que copiou sem espaços extras.

ERROR_ZERO_BALANCE

A conta nova ainda não tem créditos. Adicione créditos em captchaai.com antes de rodar o teste paralelo.

Códigos de erro diferentes dos que eu via no AZCaptcha

Pequenas diferenças de nomenclatura entre provedores são normais. Compare os códigos lado a lado — a maioria é idêntica entre AZCaptcha e CaptchaAI.

Taxa de resolução diferente da que eu via antes

Os dois provedores usam pools de solvers diferentes. Rode 50 ou mais resoluções de teste antes de comparar; com poucas amostras, o resultado não é estatisticamente válido.

Perguntas frequentes

Dá para migrar sem reescrever a lógica de polling?

Sim. O polling segue o mesmo contrato — res.php com action=get, checando status e request a cada 5 segundos — então basta trocar a URL base e a chave, como nos exemplos acima.

O que acontece com as tarefas que já estão em andamento no AZCaptcha durante a troca?

Elas continuam sendo processadas normalmente pelo AZCaptcha até você desativar a chave antiga. Por isso o checklist recomenda manter as duas chaves ativas durante o teste paralelo e só desativar o AZCaptcha depois de monitorar 24 horas de produção estável na CaptchaAI.

Minha configuração atual de proxy continua funcionando?

Sim. A CaptchaAI usa os mesmos parâmetros proxy e proxytype (HTTP/SOCKS5), então nenhuma mudança é necessária na resolução baseada em proxy.

A CaptchaAI resolve os mesmos tipos de CAPTCHA que eu já uso no AZCaptcha?

Para os tipos mais comuns, sim: reCAPTCHA v2/v3, Cloudflare Turnstile e Cloudflare Challenge, GeeTest v3, CAPTCHA de imagem/OCR, grid e BLS. hCaptcha e FunCaptcha não são suportados atualmente — confira o tipo usado no seu fluxo antes de migrar para evitar surpresas.

Quanto tempo leva a migração?

Para uma única base de código, 15 a 30 minutos. A maior parte disso é trocar a URL base com busca e substituição, mais o tempo do teste paralelo para validar.

Referência completa: endpoints e parâmetros

Consulte estas tabelas durante o find-and-replace do Passo 2.

Endpoints

Operação AZCaptcha CaptchaAI
Enviar tarefa https://azcaptcha.com/in.php https://ocr.captchaai.com/in.php
Consultar resultado https://azcaptcha.com/res.php https://ocr.captchaai.com/res.php
Consultar saldo res.php?action=getbalance res.php?action=getbalance
Reportar erro res.php?action=reportbad res.php?action=reportbad

Parâmetros

A maior parte dos parâmetros é idêntica. As diferenças reais:

Parâmetro AZCaptcha CaptchaAI Observação
key chave de API chave de API Chave diferente — gere a sua em captchaai.com
method userrecaptcha userrecaptcha Igual
googlekey sitekey sitekey Igual
pageurl URL da página URL da página Igual
json 1 1 Igual
proxy user:pass@host:port user:pass@host:port Mesmo formato
proxytype HTTP/SOCKS5 HTTP/SOCKS5 Igual

Próximos passos

Pronto para migrar? Obtenha sua chave de API da CaptchaAI e comece pelo teste paralelo antes de virar o tráfego de produção.

Guias relacionados:

Os comentários estão desativados para este artigo.