En este artículo hemos intentado responder a todas las preguntas clave. Para empezar a resolver la tarea, primero hay que determinar qué sistema de protección se está utilizando. Para ello, puedes consultar la lista de captchas y sistemas de protección antibot más populares, donde se muestran ejemplos visuales y señales clave que te ayudarán a identificar rápidamente con qué estás tratando.
Si descubres que tu sitio web utiliza FunCaptcha (Arkose Labs CAPTCHA), el siguiente paso será analizar con más detalle sus propiedades y su funcionamiento. En este mismo artículo también puedes consultar la guía de integración de FunCaptcha (Arkose Labs CAPTCHA) para comprender por completo cómo funciona en tu sitio. Esto te permitirá no solo entender la protección actual, sino también planificar correctamente su mantenimiento.
Cómo resolver FunCaptcha con CapMonster Cloud
- Abra la página con el formulario y asegúrese de que el captcha se muestre.
- Intente enviar el formulario sin resolver el captcha; el servidor debería devolver un error.
- Después de resolver correctamente el captcha, el formulario debería enviarse sin errores.
Trabajar con CapMonster Cloud mediante la API suele implicar los siguientes pasos:
type - FunCaptchaTask
websiteURL - la URL de la página donde se resuelve el captcha;
websitePublicKey - la clave de FunCaptcha (valor de public key o pk);
data - un parámetro adicional, obligatorio si en el sitio se utiliza data[blob];
funcaptchaApiJSSubdomain - el subdominio de Arkose Labs (valor surl). Indíquelo solo si difiere del estándar: client-api.arkoselabs.com
userAgent - User-Agent del navegador. Envíe solo un UA actual de un sistema operativo Windows.
Para esta tarea también es necesario utilizar sus propios proxies:
proxyType :
- http: proxy HTTP/HTTPS estándar;
- https: pruebe esta opción si «http» no funciona (requerido para algunos proxies personalizados);
- socks4: proxy de tipo SOCKS4;
- socks5: proxy de tipo SOCKS5.
proxyAddress - Dirección IP del proxy (IPv4/IPv6).
proxyPort - Puerto del proxy.
proxyLogin - Usuario del servidor proxy.
proxyPassword - Contraseña del servidor proxy.
https://api.capmonster.cloud/createTask
{
"clientKey": "API_KEY",
"task": {
"type": "FunCaptchaTask",
"websiteURL": "https://www.example.com",
"websitePublicKey": "EX72CCFB-26EX-40E5-91E6-85EX70BE98ED",
"funcaptchaApiJSSubdomain": "example-api.arkoselabs.com",
"data": "{\"blob\":\"nj9UbL+yio7goOlTQ/b64t.ayrrBnP6kPgzlKYCP/kv491lKS...Wot/7gjpyIxs7VYb0+QuRcfQ/t6bzh5pXDkOFSskA/V/ITSVZSAlglIplLcdreZ4PE8skfMU6k1Q\"}",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36",
"proxyType": "http", // Agregue un proxy si es necesario
"proxyAddress": "8.8.8.8",
"proxyPort": 8080,
"proxyLogin": "proxyLoginHere",
"proxyPassword": "proxyPasswordHere"
}
}
{
"errorId":0,
"taskId":407533072
}https://api.capmonster.cloud/getTaskResult{
"clientKey":"API_KEY",
"taskId": 407533072
}
{
"errorId": 0,
"errorCode": null,
"errorDescription": null,
"solution": {
"token": "337187b9f57678923.5060184402|r=us-west-2|lang=en|pk=EX72CCFB-26EX-40E5-91E6-85EX70BE98ED|at=40|ag=101|cdn_url=https%3A%2F%2Fclient-api.arkoselabs.com%2Fcdn%2Ffc|surl=https%3A%2F%2Fclient-api.arkoselabs.com|smurl=https%3A%2F%2Fclient-api.arkoselabs.com%2Fcdn%2Ffc%2Fassets%2Fstyle-manager",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
},
"status": "ready"
}
// npm install playwright
const { chromium } = require("playwright");
const WEBSITE_URL = "https://example.com";
// token recibido de CapMonster Cloud
const FUN_CAPTCHA_TOKEN = "PUT_YOUR_FUN_CAPTCHA_TOKEN_HERE";
(async () => {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
/**
* Interceptor universal de Arkose (v1 / v2)
* Se ejecuta antes de cargar la página
*/
await page.addInitScript(() => {
const callbacks = [];
function captureCallback(cb, source) {
if (typeof cb === "function") {
callbacks.push(cb);
console.log("[Arkose] callback captured from", source);
}
}
function patchRender(obj, name) {
if (!obj || typeof obj.render !== "function") return;
const originalRender = obj.render;
obj.render = function (container, options = {}) {
captureCallback(options.callback, name + ".render");
return originalRender.apply(this, arguments);
};
}
// Intercepción mediante Object.defineProperty (usado frecuentemente por Arkose)
const originalDefineProperty = Object.defineProperty;
Object.defineProperty = function (target, prop, descriptor) {
if (
(prop === "FunCaptcha" || prop === "ArkoseEnforcement") &&
descriptor &&
typeof descriptor.value === "object"
) {
patchRender(descriptor.value, prop);
}
return originalDefineProperty.apply(this, arguments);
};
// Fallback: comprobación periódica de objetos globales
const interval = setInterval(() => {
if (window.FunCaptcha) patchRender(window.FunCaptcha, "FunCaptcha");
if (window.ArkoseEnforcement)
patchRender(window.ArkoseEnforcement, "ArkoseEnforcement");
if (callbacks.length > 0) clearInterval(interval);
}, 200);
// Punto universal para pasar el token
window.__arkoseSolve = function (token) {
if (callbacks.length > 0) {
callbacks.forEach((cb) => cb(token));
console.log("[Arkose] token delivered via captured callbacks");
return true;
}
// Opciones alternativas
if (typeof window.arkoseCallback === "function") {
window.arkoseCallback(token);
console.log("[Arkose] token delivered via arkoseCallback");
return true;
}
// Fallback
window._arkoseToken = token;
console.log("[Arkose] token stored in window._arkoseToken");
return false;
};
});
/**
* Abrir la página
*/
console.log("Opening page...");
await page.goto(WEBSITE_URL, { waitUntil: "domcontentloaded" });
/**
* Aquí el sitio debe inicializar FunCaptcha
* (registro, inicio de sesión, botón, formulario, etc.)
*/
/**
* Pasar el token listo
*/
console.log("Injecting FunCaptcha token...");
await page.evaluate((token) => {
if (!window.__arkoseSolve) {
console.log("[Arkose] solver not ready");
return;
}
window.__arkoseSolve(token);
}, FUN_CAPTCHA_TOKEN);
/**
* Dar tiempo a la página para procesar el resultado
*/
await page.waitForTimeout(5000);
console.log("Done.");
await browser.close();
})();
- Regístrese en Arkose Labs y obtenga acceso al Arkose Command Center (puede contactarlos por el chat y enviar sus datos en el formulario, por ejemplo aquí o aquí).
Después de obtener acceso, reciba dos claves (Public / Private) en la sección Settings → Keys.

Si es necesario, contacte a su Customer Success Manager (CSM) para:
- obtener dominios API personalizados;
- recibir los esquemas de solicitudes y respuestas de la Verify API.
Recomendaciones de Arkose
- Utilice una Development Key para pruebas.
- Utilice una Production Key independiente para cada flujo (inicio de sesión, registro, compra, etc.).
- Utilice claves diferentes para sitios web diferentes.
Flujo general
- El cliente recopila datos y muestra un desafío si es necesario.
- El cliente recibe un token de un solo uso.
- El servidor verifica el token mediante la Arkose Verify API.
Paso 1. Integración del lado del cliente
En el navegador (Arkose Bot Manager):
- analiza el comportamiento del usuario;
- muestra un Enforcement Challenge si es necesario;
- devuelve un token de sesión de un solo uso.
Client API:
- Para pruebas se puede utilizar:
client-api.arkoselabs.com - Para producción, se recomienda especificar un dominio personalizado:
<company>-api.arkoselabs.com
Requisitos principales
- El script del cliente de Arkose debe cargarse solo una vez por página
- Debe definirse un callback global
- Es obligatorio llamar a setConfig()
- Según el resultado, se toma una decisión (permitir o rechazar la acción).
El resultado del trabajo del cliente es un token que debe enviarse al servidor.
<html>
<head>
<!--
Incluya la API de Arkose Labs en el <head> de la página. En el ejemplo siguiente, asegúrese de:
- reemplazar <YOUR PUBLIC KEY> por la public key proporcionada por Arkose Labs;
- reemplazar <YOUR CALLBACK> por el nombre de la función callback global que definirá a continuación.
Ejemplo:
<script src="//client-api.arkoselabs.com/v2/<YOUR PUBLIC KEY>/api.js"
data-callback="setupDetect"></script>
-->
<script src="//client-api.arkoselabs.com/v2/<YOUR PUBLIC KEY>/api.js" data-callback="<YOUR CALLBACK>"></script>
<link rel="shortcut icon" href="#">
<meta charset="UTF-8">
</head>
<body>
<!--
El elemento disparador puede ubicarse en cualquier lugar de la página y puede añadirse al DOM en cualquier momento.
-->
<button id="arkose-trigger">
elemento disparador
</button>
<!--
Para configurar Arkose (modo detection o enforcement), coloque el script antes de la etiqueta de cierre </body> y defina la función callback como global.
-->
<script>
/*
Esta función global se llamará cuando la API de Arkose esté lista. El nombre de la función debe coincidir con el valor del atributo data-callback de la etiqueta script que carga la API de Arkose.
*/
function setupArkose(myArkose) {
myArkose.setConfig({
selector: '#arkose-trigger',
onCompleted: function(response) {
// Token de un solo uso que debe enviarse al servidor
console.log(response.token);
}
});
}
</script>
</body>
</html>
Paso 2. Verificación del lado del servidor
En el servidor, el token se verifica mediante la Arkose Verify API.
Verify API endpoint
https://<company>-verify.arkoselabs.com/api/v4/verify/Parámetros obligatorios de la solicitud
- private_key — clave privada de Arkose
- session_token — token obtenido en el cliente
Ejemplo del cuerpo de una solicitud POST
{
"private_key": "_PRIVATE_KEY_HERE_",
"session_token": "_SESSION_TOKEN_HERE_",
"log_data": "_LOG_DATA_HERE_"
}
La respuesta de la API contiene información de la sesión y el resultado de la verificación.
Puntos clave
- Public Key — solo cliente
- Private Key — solo servidor
- El token es de un solo uso
- Sin verificación del lado del servidor, el captcha se considera inválido
- Arkose puede funcionar de forma oculta y mostrar el desafío solo cuando existe riesgo
<?php
$private_key = 'SU_PRIVATE_KEY';
$verify_url = 'https://<company>-verify.arkoselabs.com/api/v4/verify/';
$input = json_decode(file_get_contents('php://input'), true);
$session_token = $input['session_token'] ?? null;
$log_data = $input['log_data'] ?? '';
$email_address = $input['email_address'] ?? '';
if (!$session_token) {
http_response_code(400);
echo json_encode(['error' => 'Falta el token de sesión']);
exit;
}
$data = [
'private_key' => $private_key,
'session_token' => $session_token,
'log_data' => $log_data,
'email_address' => $email_address
];
$options = [
'http' => [
'header' => "Content-Type: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data),
],
];
$context = stream_context_create($options);
$result = file_get_contents($verify_url, false, $context);
if ($result === FALSE) {
http_response_code(500);
echo json_encode(['error' => 'Error en la verificación del captcha']);
exit;
}
echo $result;
?>
Cómo funciona:
- El cliente resuelve el captcha en el sitio web y recibe un token de sesión.
- El cliente envía el token a su servidor mediante una solicitud POST.
- El servidor llama a la Arkose Verify API con la clave privada y el token de sesión
- Arkose devuelve un JSON con información de la sesión y el estado de la verificación.
- El servidor comprueba el resultado (result.success) y decide si permite acciones adicionales.
Captchas compatibles
Si has heredado un sitio web que ya tiene un captcha u otro sistema de protección instalado y no tienes acceso al código, no pasa nada. Identificar qué tecnología se está utilizando es bastante sencillo. Para comprobar que todo funciona correctamente, puedes usar el servicio de reconocimiento CapMonster Cloud en un entorno de pruebas aislado, para asegurarte de que el mecanismo de procesamiento de tokens y la lógica de verificación funcionan correctamente.
En el caso de FunCaptcha, basta con detectar el sistema, analizar su comportamiento y confirmar que la protección funciona correctamente. En el artículo hemos mostrado cómo identificar FunCaptcha y dónde encontrar las instrucciones para su integración o reconfiguración, de modo que puedas mantener la protección con confianza y controlar su funcionamiento.