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.
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 :
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/143.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();
})();
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:
Recomendaciones de Arkose
Flujo general
Paso 1. Integración del lado del cliente
En el navegador (Arkose Bot Manager):
Client API:
client-api.arkoselabs.com<company>-api.arkoselabs.comRequisitos principales
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
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
<?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:
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.