Enviaste un CAPTCHA de Turnstile a CaptchaAI, recuperaste un token, pero el sitio de destino lo rechaza. El token está técnicamente resuelto: el problema es cómo o cuándo usarlo. Esta guía cubre todas las razones por las que las fichas de Turnstile fallan después de resolverse.
Síntomas
| lo que ves | causa probable |
|---|---|
| El sitio devuelve 403 después de enviar el token | El token expiró antes del envío |
| El envío del formulario falla silenciosamente | Nombre de campo incorrecto para la inyección de token |
| Token aceptado pero acción bloqueada | No coincide la clave del sitio: widget incorrecto resuelto |
| Funciona una vez y luego falla | Token ya utilizado (de un solo uso) |
| Funciona en el navegador, falla en el script | Faltan cookies o encabezados |
Causa 1: el token expiró
Los tokens de torniquete caducan rápidamente, normalmente en 300 segundos (5 minutos). Si su código tarda demasiado entre recibir el token y enviarlo, el token está inactivo.
Solución: envíe el token inmediatamente después de recibirlo.
import requests
import time
API_KEY = "YOUR_API_KEY"
# Submit Turnstile task
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "0x4AAAAAAADnPIDROz1234",
"pageurl": "https://staging.example.com/qa-login",
"json": 1
}).json()
task_id = submit["request"]
time.sleep(10)
# Poll for result
for _ in range(24):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
token = result["request"]
# USE TOKEN IMMEDIATELY — do not delay
response = requests.post("https://staging.example.com/qa-login", data={
"username": "user",
"password": "pass",
"cf-turnstile-response": token
})
break
time.sleep(5)
Causa 2: clave de sitio incorrecta
Cada widget Turnstile tiene una clave de sitio única. Si la página tiene varios widgets o copió la clave incorrecta, el token será válido pero rechazado.
Cómo encontrar la clave de sitio correcta:
// In browser console on the target page
document.querySelectorAll('[data-sitekey]').forEach(el => {
console.log('Sitekey:', el.getAttribute('data-sitekey'));
console.log('Element:', el);
});
Si hay varias claves de sitio, utilice la adjunta al formulario que está enviando.
Causa 3: nombre de campo incorrecto
Turnstile espera el token en cf-turnstile-response, no en g-recaptcha-response.
# WRONG — this is for reCAPTCHA
data = {"g-recaptcha-response": token}
# CORRECT — this is for Turnstile
data = {"cf-turnstile-response": token}
Algunos sitios utilizan un nombre de campo personalizado. Inspeccione el formulario para encontrar el campo real:
// Check what field the Turnstile widget populates
document.querySelector('[name*="turnstile"], [name*="cf-"]')
Causa 4: Token ya utilizado
Las fichas de torniquete son de un solo uso. Si su código vuelve a intentar una solicitud con el mismo token, el segundo intento fallará.
Solución: resuelva un nuevo CAPTCHA para cada intento de envío.
Causa 5: Faltan cookies o contexto de sesión
Cloudflare puede validar el token con las cookies de sesión. Si resuelve el CAPTCHA en una sesión y lo envía en otra, es probable que lo rechacen.
# Use the SAME session for page load and token submission
session = requests.Session()
# Load the page first to establish cookies
session.get("https://staging.example.com/qa-login")
# Then solve and submit using the same session
token = solve_turnstile(sitekey, pageurl)
session.post("https://staging.example.com/qa-login", data={
"cf-turnstile-response": token
})
Causa 6: acción o discrepancia de datos c
Algunas implementaciones de Turnstile incluyen parámetros action o cData vinculados al token. Si el sitio los espera, debe pasarlos al resolver.
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "0x4AAAAAAADnPIDROz1234",
"pageurl": "https://staging.example.com/qa-login",
"action": "login", # If required by the site
"data": "custom_cdata_value", # If required by the site
"json": 1
}).json()
Árbol de decisión
Token solved but rejected
↓
Used within 5 minutes? → No → Solve again, submit immediately
↓ Yes
Correct sitekey? → No → Find the correct sitekey from the page
↓ Yes
Using cf-turnstile-response field? → No → Change field name
↓ Yes
Same session for page load + submit? → No → Use session persistence
↓ Yes
Token used only once? → No → Solve a new token per submission
↓ Yes
Site requires action/cData? → Check page source, add to API call
Preguntas frecuentes
¿Cuánto duran las fichas Turnstile?
Normalmente 300 segundos (5 minutos). Algunas implementaciones establecen un vencimiento más corto. Envíe el token a los pocos segundos de recibirlo.
¿Es Turnstile lo mismo que Cloudflare Challenge?
No. Turnstile es un widget integrado (como reCAPTCHA). Cloudflare Challenge es un intersticial de página completa. Utilizan diferentes métodos CaptchaAI: turnstile vs cloudflare_challenge.
¿Por qué mi token funciona en Postman pero no en mi script?
Es posible que el cartero esté enviando encabezados o cookies diferentes. Haga coincidir los encabezados de su secuencia de comandos y el estado de la sesión con lo que envía el navegador.
Resolver CAPTCHA de torniquete en CaptchaAI
Obtenga una solución confiable de torniquetes encaptchaai.com.
Guías relacionadas
- Cómo resolver Cloudflare Turnstile usando API
- El token expiró antes del envío
- Cloudflare Turnstile 403 Después de la corrección del token
- Configuraciones de tiempo de espera personalizadas por tipo CAPTCHA
Configuración recomendada para su pipeline
Use exactamente la misma configuración de navegador en todos sus entornos de QA, staging y CI. Esto evita que un test funcione en local y falle en CI sin razón aparente.
from selenium import webdriver
def make_driver(headless: bool = True) -> webdriver.Chrome:
options = webdriver.ChromeOptions()
if headless:
options.add_argument('--headless=new')
options.add_argument('--window-size=1280,800')
options.add_argument('--lang=es-ES')
return webdriver.Chrome(options=options)
Mantener viewport, idioma y user-agent por defecto idénticos en todos los runners reduce la varianza y facilita comparar resultados entre ejecuciones de su propio QA.
Cómo se integra CaptchaAI en su pipeline propio
El patrón de integración con CaptchaAI siempre es el mismo, independientemente del lenguaje o framework de pruebas que use:
- Su test detecta el widget de CAPTCHA en la página de su propia aplicación (formulario de QA, landing de staging, endpoint de preproducción).
- Su test envía a CaptchaAI los datos públicos del widget (
sitekey, URL de la página, tipo de CAPTCHA). - CaptchaAI devuelve un token válido para esa página.
- Su test inyecta ese token en el campo correspondiente y envía el formulario.
- Su backend verifica el token con el proveedor de CAPTCHA, exactamente igual que con un usuario real.
Este flujo se aplica únicamente a integraciones que usted controla. No se utiliza para sortear protecciones de sitios de terceros.
Métricas y observabilidad
Incluya métricas específicas para los pasos relacionados con CAPTCHA en sus pipelines de QA. Esto le permite detectar regresiones en su propia integración antes de que lleguen a producción:
- Tiempo de resolución por intento — desde la solicitud a CaptchaAI hasta la entrega del token.
- Tasa de éxito por endpoint propio — cuántas verificaciones backend pasan respecto al total de intentos.
- Distribución de errores — agrupados por código (
ERROR_*, timeouts internos, fallos de red). - Latencia extremo a extremo — incluyendo render de la página, resolución de CAPTCHA y respuesta de su backend.
Conserve trazas (logs, capturas, HAR) durante un período razonable para poder reproducir incidentes en su entorno QA cuando un test falle de forma intermitente.
Buenas prácticas en su entorno QA
- Pruebe siempre sobre su propia aplicación o sobre entornos explícitamente autorizados.
- Mantenga una API key de CaptchaAI separada para QA, distinta de la de producción, para no mezclar métricas.
- Defina timeouts y reintentos razonables (
backoffexponencial) para no acumular trabajos pendientes en CaptchaAI durante caídas. - Versione sus snapshots de configuración (sitekey, action, umbrales) junto al código de los tests.
- Revise periódicamente el changelog de su proveedor de CAPTCHA para anticipar cambios que afecten a su propia integración.
Solución de problemas
| Síntoma | Acción recomendada |
|---|---|
| El test no detecta el widget | Revise selectores y tiempos en su entorno staging |
CaptchaAI devuelve ERROR_NO_SLOT_AVAILABLE |
Reintente con backoff en su pipeline interna |
| La validación backend rechaza el token | Compare action/sitekey con su configuración real |
| El test funciona en local pero falla en CI | Iguale viewport, idioma y user-agent en ambos entornos |
| Tiempos de resolución muy variables | Revise concurrencia y límites de su API key de CaptchaAI |
Valide sus integraciones CAPTCHA en entornos propios con CaptchaAI.