Se a taxa de resolução despencou de um dia para o outro, o problema quase nunca está na CaptchaAI — na grande maioria dos casos é um parâmetro desatualizado do seu lado: sitekey antiga, token usado tarde demais ou action do reCAPTCHA v3 fora do que o site espera. Em vez de trocar de solucionador ou abrir um chamado de suporte, siga o fluxograma abaixo: em poucos minutos ele já aponta se a falha está na chamada à API ou na aceitação do token pelo site de destino.
Fluxograma de diagnóstico
Comece sempre por aqui. Cada ramo leva a uma ação concreta — sem achismo:
Success rate dropped
│
├── Are tokens being generated?
│ ├── NO → Check API errors
│ │ ├── ERROR_WRONG_GOOGLEKEY → Sitekey changed. Re-extract.
│ │ ├── ERROR_BAD_PARAMETERS → Check required params
│ │ ├── ERROR_NO_SLOT → Retry with backoff
│ │ └── Other errors → See error decision tree
│ │
│ └── YES → Tokens generated but rejected by target site
│ │
│ ├── Token expired before use?
│ │ └── YES → Submit token faster (< 60-120s)
│ │
│ ├── Token used for wrong domain?
│ │ └── YES → Check pageurl matches submission domain
│ │
│ ├── reCAPTCHA v3 score too low?
│ │ └── YES → Check action parameter, try score_qa
│ │
│ ├── Site changed CAPTCHA type?
│ │ └── YES → Re-detect CAPTCHA type
│ │
│ └── Site added additional checks?
│ └── YES → Check for sinal de navegadoring, cookies, headers
Antes de seguir qualquer ramo, você precisa de um número de referência confiável — é isso que o próximo passo resolve.
Passo 1: registre a taxa atual antes de mexer em qualquer parâmetro
Sem uma linha de base, é impossível saber se uma mudança realmente ajudou. A classe abaixo agrupa as tentativas por método de resolução e já separa os erros mais frequentes — rode-a por algumas centenas de chamadas antes de tirar qualquer conclusão sobre a causa.
import requests
import time
from collections import defaultdict
class SuccessTracker:
"""Track solve success rates over time."""
def __init__(self):
self.stats = defaultdict(lambda: {"attempts": 0, "success": 0, "errors": defaultdict(int)})
def record(self, method, success, error_code=None):
self.stats[method]["attempts"] += 1
if success:
self.stats[method]["success"] += 1
elif error_code:
self.stats[method]["errors"][error_code] += 1
def report(self):
for method, data in self.stats.items():
rate = data["success"] / data["attempts"] * 100 if data["attempts"] > 0 else 0
print(f"\n{method}:")
print(f" Attempts: {data['attempts']}")
print(f" Success: {data['success']} ({rate:.1f}%)")
if data["errors"]:
print(" Errors:")
for err, count in sorted(data["errors"].items(), key=lambda x: -x[1]):
print(f" {err}: {count}")
tracker = SuccessTracker()
Guarde esse relatório: é o "antes" que você compara com o "depois" de cada correção. Se os logs ficarem armazenados além do necessário para o diagnóstico, lembre-se das obrigações da LGPD sobre retenção e finalidade dos dados — mantenha só o essencial.
Passo 2: separe o problema em duas categorias
Toda queda de taxa cai em uma de duas famílias, e cada uma se corrige de um jeito completamente diferente.
Categoria A: a API devolve erro em vez de token
Nesse caso a CaptchaAI nem chega a gerar um token — o erro já aparece na resposta do in.php ou do res.php. É o cenário mais fácil de depurar, porque o código de erro já diz o que está errado.
def diagnose_api_failures(api_key, method, params, attempts=10):
"""Run test solves and collect error patterns."""
errors = defaultdict(int)
successes = 0
for i in range(attempts):
try:
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": api_key, "method": method, "json": 1, **params,
}, timeout=30)
result = resp.json()
if result.get("status") != 1:
errors[result.get("request", "UNKNOWN")] += 1
continue
task_id = result["request"]
# Quick poll
time.sleep(15)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "get",
"id": task_id, "json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
successes += 1
else:
errors[data.get("request", "POLL_ERROR")] += 1
except Exception as e:
errors[f"EXCEPTION:{type(e).__name__}"] += 1
time.sleep(2)
print(f"\nResults: {successes}/{attempts} success")
for err, count in sorted(errors.items(), key=lambda x: -x[1]):
print(f" {err}: {count}")
Se a sua automação roda em um worker de QA hospedado perto do público-alvo — por exemplo, sa-east-1 da AWS, para reduzir o RTT — rode o diagnóstico nesse mesmo ambiente. Testar de outro continente mascara timeouts que só aparecem sob a latência real.
Categoria B: a CaptchaAI entrega o token, mas o site rejeita
Esse é o cenário mais comum quando a taxa cai de repente: o log mostra status=1 — sucesso — mas o formulário de destino continua recusando o envio. As causas mais frequentes:
| Causa | Verifique |
|---|---|
| Token expirou | Usando token > 120s após geração |
| Incompatibilidade de domínio | pageurl não corresponde ao domínio de envio |
| pontuação v3 muito baixa | O site requer 0,7+, mas o solucionador obtém 0,3 |
| Ação ausente | v3 requer parâmetro de ação correspondente |
| Parâmetros alterados no site | Sitekey ou estrutura da página alterada |
Passo 3: aplique a correção certa para cada causa
Correção 1: token expirando antes do uso
A regra prática é gerar e usar o token na mesma respiração: faça polling agressivo assim que enviar a tarefa e submeta o formulário no instante em que o status vier 1 — nunca guarde o token para "usar depois".
def solve_and_use_immediately(api_key, sitekey, pageurl):
"""Solve and use token as fast as possible."""
# Submit
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
}, timeout=30)
task_id = resp.json()["request"]
# Poll aggressively
for _ in range(24):
time.sleep(5)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "get",
"id": task_id, "json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
token = data["request"]
# USE IMMEDIATELY — don't store for later
submit_form(token)
return True
return False
Correção 2: sitekey desatualizada
Sites trocam a sitekey em deploys de frontend sem avisar ninguém. Se a sua automação guarda esse valor em uma constante ou variável de ambiente fixa, ela continua enviando a chave antiga até alguém notar a queda na taxa — reextraia a sitekey a cada execução, direto do HTML da página:
def solve_with_fresh_params(api_key, pageurl):
"""Re-extract sitekey before each solve."""
import re
resp = requests.get(pageurl, timeout=15)
match = re.search(r'data-sitekey="([^"]+)"', resp.text)
if not match:
raise RuntimeError("Could not find sitekey")
sitekey = match.group(1)
# Now solve with fresh sitekey
# ...
Correção 3: parâmetro action do reCAPTCHA v3
O reCAPTCHA v3 usa o parâmetro action para calcular a pontuação. Se o valor enviado à CaptchaAI não bater com o que o site espera — por exemplo, "submit" quando o site usa "login" — o token sai com pontuação baixa e é rejeitado silenciosamente. Abra o código-fonte da página e procure a chamada grecaptcha.execute para confirmar o valor exato antes de enviar:
# Check what action the site uses
# Look for: grecaptcha.execute('sitekey', {action: 'submit'})
data = {
"key": api_key,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"version": "v3",
"action": "submit", # Must match site's action
"score_qa": "0.7",
"json": 1,
}
Taxas de sucesso esperadas por tipo de CAPTCHA
Use estes intervalos como termômetro no seu painel de monitoramento. Se a taxa medida no Passo 1 cair abaixo do limite de alerta por mais de algumas horas, rode o fluxograma imediatamente — não espere o time de suporte reclamar primeiro.
| Tipo CAPTCHA | Taxa Normal | Limite de alerta |
|---|---|---|
| reCAPTCHA v2 | 95-99% | Abaixo de 90% |
| reCAPTCHA v3 | 90-98% | Abaixo de 85% |
| Cloudflare Turnstile | 99-100% | Abaixo de 95% |
| GeeTest v3 | 99-100% | Abaixo de 95% |
| BLS | 99-100% | Abaixo de 95% |
| Imagem/OCR | 90-98% | Abaixo de 85% |
Erros comuns e correções rápidas
Referência rápida para os quatro cenários mais comuns reportados por equipes que rodam CAPTCHA em produção:
| Problema | Causa | Correção |
|---|---|---|
| Taxa caiu de 98% para 70% | Sitekey ou página alterada | Extraia novamente todos os parâmetros |
| Tokens v3 todos rejeitados | Parâmetro de ação incorreto | Corresponder ação da origem da página |
| Os tokens funcionam, mas expiram | Muito lento para usar | Envie o token em 60 segundos |
| A taxa varia de acordo com a hora do dia | Limitação de taxa do lado do servidor | Adicione atrasos entre envios |
Perguntas frequentes
Qual é a taxa de sucesso normal do reCAPTCHA v2?
Entre 95% e 99% na maioria das integrações configuradas corretamente. Se a sua ficar consistentemente abaixo de 90%, o problema quase sempre é parâmetro ou timing — não o solucionador.
Por que os tokens do reCAPTCHA v3 chegam bons, mas são recusados minutos depois?
Porque o token expira 120 segundos após a geração. Se o seu pipeline enfileira o token para usar depois — por exemplo, esperando outra etapa de fila terminar — ele chega expirado ao site. Envie o token em até 60 segundos para ter margem de sobra.
Preciso reextrair a sitekey a cada execução?
Se o site publica atualizações de frontend com frequência, sim. Reextrair a sitekey do HTML antes de cada solve custa uma requisição extra e evita que a automação inteira pare de funcionar silenciosamente no dia em que o valor mudar.
A taxa de sucesso varia conforme o horário do dia — isso é normal?
Pode ser limitação de taxa do lado do site de destino, não da CaptchaAI. Se a queda for previsível — por exemplo, sempre no horário de pico — adicione um intervalo maior entre os envios nesses períodos.
Vale a pena reportar soluções incorretas?
Sim. Use o endpoint reportbad para reportar tokens que o site rejeitou como inválidos. A CaptchaAI usa esse retorno para calibrar a precisão nos tipos de CAPTCHA suportados.
Guias Relacionados
Diagnostique com método, não com achismo — comece agora com a CaptchaAI.