Recebeu ERROR_CAPTCHA_UNSOLVABLE mesmo enviando o parâmetro certo? Na maioria dos casos o problema não é a chave de API nem o proxy — é confundir as duas proteções da Cloudflare. O Desafio Cloudflare (página inteira) e o Cloudflare Turnstile (widget no formulário) usam parâmetros diferentes na CaptchaAI, e enviar um método pelo outro nunca resolve. Veja como reconhecer cada um em segundos — pelo HTML, pelo visual e por código — e qual método enviar em cada caso.
Resposta rápida: verifique primeiro se a página é um intersticial que bloqueia tudo (Desafio Cloudflare) ou um widget dentro de um formulário que carregou normalmente (Turnstile). Os dois usam parâmetros próprios na CaptchaAI, e escolher o errado é a causa mais comum do
ERROR_CAPTCHA_UNSOLVABLE.
Desafio Cloudflare x Turnstile, lado a lado
| Característica | Desafio Cloudflare | Cloudflare Turnstile |
|---|---|---|
| Tipo | Intersticial de página inteira | Widget incorporado no formulário |
| Aparência | Bloqueia a página toda, "Verificando seu navegador" | Caixa de seleção pequena ou widget invisível |
| Método CaptchaAI | turnstile_staging |
turnstile |
| Retorno | Cookie de validação | Token |
| Proxy obrigatório | Sim | Recomendado |
| User-Agent obrigatório | Sim | Não |
Erros comuns e como corrigir
Antes de investigar o HTML da página, veja se o seu caso já está aqui — a maioria das falhas cai em uma destas quatro linhas:
| Erro | Resultado | Correção |
|---|---|---|
Usar turnstile numa página de Desafio Cloudflare |
ERROR_CAPTCHA_UNSOLVABLE |
Trocar para turnstile_staging |
Usar turnstile_staging para o Turnstile |
Formato de resposta incorreto | Trocar para turnstile |
| Não enviar proxy no Desafio Cloudflare | ERROR_PROXY_NOT_AUTHORIZED |
Adicionar proxy — é obrigatório nesse tipo |
| Não enviar sitekey no Turnstile | ERROR_BAD_PARAMETERS |
Extrair o sitekey do HTML da página |
Se nenhuma dessas linhas bate com o seu erro, siga para a detecção detalhada abaixo — o problema provavelmente é confundir os dois tipos, não um parâmetro isolado.
Perguntas frequentes
O plano BASIC já cobre os dois tipos de proteção?
Sim. Os planos são cobrados por thread, não por tipo de CAPTCHA: o BASIC (US$ 15/mês, 5 threads) resolve os dois dentro do mesmo saldo, sem cobrança extra por tipo.
Por que o Desafio Cloudflare exige proxy e o Turnstile não?
O Desafio Cloudflare retorna um cookie vinculado ao IP que resolveu a verificação, então a CaptchaAI precisa do seu proxy para gerar um cookie válido na sua sessão. O Turnstile retorna um token independente de IP, por isso o proxy é só recomendado.
A detecção não encontrou nada, mas eu ainda vejo uma tela da Cloudflare. O que fazer?
Algumas proteções só aparecem em ações específicas — POST, chamadas de API ou certos User-Agents. Repita a requisição com um User-Agent que pareça automatizado; se a proteção só aparecer nesse caso, ela vem de uma regra de WAF, não da verificação padrão.
O erro ERROR_CAPTCHA_UNSOLVABLE sempre significa que escolhi o método errado?
Não sempre, mas é a causa mais comum. Antes de investigar outra coisa, confirme qual proteção a página usa de fato — reenviar a tarefa com o método trocado resolve a maioria dos casos.
A região do worker (ex.: sa-east-1) muda o método que devo enviar?
Não. A região só afeta a latência de rede até o seu staging, nunca o parâmetro correto para a CaptchaAI. Quem decide o método é sempre o tipo de proteção que a página exibe naquele momento — por isso vale detectar a cada etapa, não assumir o mesmo tipo do início ao fim do fluxo.
Como reconhecer o Desafio Cloudflare
O Desafio Cloudflare é um intersticial de página inteira que bloqueia o acesso antes de a página real carregar.
Sinais visuais:
| Onde olhar | O que você vê |
|---|---|
| Mensagem na tela | "Verificando seu navegador antes de acessar..." |
| Indicador de carregamento | Ícone de carregamento da Cloudflare |
| Título da aba | Vira "Just a moment..." |
| Barra de endereço | A URL continua a mesma, mas o conteúdo é uma página da Cloudflare |
Sinais no HTML:
<!-- Cloudflare Turnstile em staging page indicators -->
<title>Just a moment...</title>
<div id="challenge-running">...</div>
<div class="cf-browser-verification">...</div>
Detecção programática:
import requests
resp = requests.get("https://example.com")
is_cf_challenge = (
resp.status_code == 403 and
"Just a moment" in resp.text or
"cf-browser-verification" in resp.text or
"challenge-platform" in resp.text
)
if is_cf_challenge:
print("Cloudflare Turnstile em staging detected — use method: turnstile_staging")
Como reconhecer o Cloudflare Turnstile
O Turnstile é um widget incorporado numa página já carregada, como o reCAPTCHA.
Sinais visuais:
| Onde olhar | O que você vê |
|---|---|
| Dentro do formulário | Widget pequeno da Cloudflare (estilo caixa de seleção) |
| Restante da página | Conteúdo visível normalmente, nada bloqueado |
| Texto do widget | "Verifique se você é humano" |
Sinais no HTML:
<!-- Turnstile widget indicators -->
<div class="cf-turnstile" data-sitekey="0x4AAAAAAADnPIDROz1234"></div>
<!-- Or loaded via JavaScript -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"></script>
Detecção programática:
import requests
resp = requests.get("https://staging.example.com/qa-login")
is_turnstile = (
"cf-turnstile" in resp.text or
"challenges.cloudflare.com/turnstile" in resp.text
)
if is_turnstile:
# Extract sitekey
if 'data-sitekey="' in resp.text:
start = resp.text.index('data-sitekey="') + 14
end = resp.text.index('"', start)
sitekey = resp.text[start:end]
print(f"Turnstile detected — sitekey: {sitekey}")
print("Use method: turnstile")
Um script para detectar as duas de uma vez
Combine as duas verificações numa função só e deixe o pipeline decidir o método sozinho:
def detect_cloudflare_type(url):
"""Detect which Cloudflare protection a URL uses."""
resp = requests.get(url, allow_redirects=True)
# Check for full-page Challenge
if resp.status_code in [403, 503]:
if any(marker in resp.text for marker in [
"Just a moment",
"cf-browser-verification",
"challenge-platform",
"challenge-running"
]):
return {"type": "turnstile_staging", "method": "turnstile_staging"}
# Check for embedded Turnstile
if "cf-turnstile" in resp.text or "challenges.cloudflare.com/turnstile" in resp.text:
sitekey = None
if 'data-sitekey="' in resp.text:
start = resp.text.index('data-sitekey="') + 14
end = resp.text.index('"', start)
sitekey = resp.text[start:end]
return {"type": "turnstile", "method": "turnstile", "sitekey": sitekey}
return {"type": "none", "method": None}
# Usage
result = detect_cloudflare_type("https://example.com")
print(f"Protection: {result['type']}")
print(f"CaptchaAI method: {result['method']}")
Um cenário comum: pipeline de QA rodando na sa-east-1
Um time de QA roda workers na região sa-east-1 (São Paulo) para reduzir a latência até o staging, onde o acesso inicial cai no Desafio Cloudflare e o login usa Turnstile. Se o pipeline sempre envia turnstile, ele resolve o widget mas nunca passa do intersticial, e os testes falham por timeout antes de chegar à tela de login — sem nenhum erro claro no log, só um timeout genérico.
O padrão de diagnóstico é sempre o mesmo, independentemente da região do worker:
- Rode a função de detecção acima a cada etapa do fluxo, não só uma vez no início.
- Trate o resultado de
detect_cloudflare_type()como parte do estado do teste, não como um detalhe de infraestrutura. - Se o tipo mudar entre o acesso inicial e o login (comum em fluxos de autenticação), envie duas tarefas distintas à CaptchaAI, uma por etapa.
Isso evita a falha silenciosa: o pipeline para de "resolver o widget errado" e passa a resolver a proteção que a página realmente está mostrando naquele momento.
Como resolver cada proteção com a CaptchaAI
Desafio Cloudflare:
data = {
"key": "YOUR_API_KEY",
"method": "turnstile_staging",
"pageurl": "https://example.com",
"proxy": "host:port:user:pass", # MANDATORY
"proxytype": "HTTP", # MANDATORY
"userAgent": "Mozilla/5.0 ...", # MANDATORY
"json": 1
}
# Returns cookie_qa_validacao cookie — set it in your session
Cloudflare Turnstile:
data = {
"key": "YOUR_API_KEY",
"method": "turnstile",
"sitekey": "0x4AAAAAAADnPIDROz1234",
"pageurl": "https://staging.example.com/qa-login",
"json": 1
}
# Returns a token — inject into cf-turnstile-response field
Resolva as duas proteções da Cloudflare com a CaptchaAI
Lide com as duas em captchaai.com.