Documentación
.md
Instalación, integración HTML, verificación server-side, MCP, Adaptive Pace y más. Documentación completa también descargable como Markdown.
Quickstart
- Crea una cuenta gratis.
- En el dashboard, registra tu dominio y copia tu
sitekeyysecret_key. - Pega el snippet HTML donde quieras el captcha.
- En tu backend, valida el token con
POST /siteverify.
Integración HTML
Pega esto en tu formulario, donde quieras que aparezca el captcha:
<script src="https://captcha.softwalabs.com/v1/api.js" async defer></script>
<form method="post" action="/login">
<input name="email" type="email">
<input name="password" type="password">
<div class="softwacap" data-sitekey="TU_SITEKEY"></div>
<button type="submit">Entrar</button>
</form>
El widget inyecta automáticamente un <textarea name="g-recaptcha-response"> en el formulario. Tu backend recibirá el token en ese campo.
Atributos de configuración
| Atributo | Tipo | Descripción |
|---|---|---|
data-sitekey | string | Tu clave pública (obligatorio). |
data-callback | string | Nombre de función JS global a llamar al éxito (recibe el token). |
data-expired-callback | string | Nombre de función JS al expirar el token. |
data-error-callback | string | Nombre de función JS si falla la verificación. |
data-response-field-name | string | Nombre del input hidden (default: g-recaptcha-response). |
Verificación server-side
En tu backend, valida el token con una petición POST. Compatible drop-in con reCAPTCHA siteverify.
POST https://captcha.softwalabs.com/siteverify
Content-Type: application/x-www-form-urlencoded
secret=TU_SECRET_KEY&response=TOKEN_DEL_FORMULARIO&remoteip=IP_USUARIO
Respuesta:
{
"success": true,
"score": 0.85,
"challenge_ts": "2026-04-26T10:30:00Z",
"hostname": "midominio.com"
}
Si success es true, el usuario es humano. score va de 0 a 1; típicamente acepta > 0.5.
Migración desde reCAPTCHA
Si ya usas reCAPTCHA v2/v3, cambias 2 líneas:
1. Frontend
// Antes
<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="..."></div>
// Después — dos opciones
// Opción A: cambiar src y clase
<script src="https://captcha.softwalabs.com/v1/api.js"></script>
<div class="softwacap" data-sitekey="..."></div>
// Opción B: solo cambiar src (mantenemos g-recaptcha)
<script src="https://captcha.softwalabs.com/v1/api.js"></script>
<div class="g-recaptcha" data-sitekey="..."></div>
2. Backend
Cambia el endpoint:
// Antes
https://www.google.com/recaptcha/api/siteverify
// Después
https://captcha.softwalabs.com/siteverify
El formato de la petición y de la respuesta JSON es idéntico. Tu lógica de validación no cambia.
Referencia API JS
El widget expone una API global compatible con grecaptcha:
// Renderizar manualmente
var widgetId = softwacap.render('mi-div', {
sitekey: 'pk_swl_...',
callback: function (token) { console.log(token); }
});
// Obtener el token actual
var token = softwacap.getResponse(widgetId);
// Resetear (forzar nuevo challenge)
softwacap.reset(widgetId);
// Esperar a que esté listo
softwacap.ready(function () { /* widget cargado */ });
Ejemplos por lenguaje
PHP
$response = $_POST['g-recaptcha-response'] ?? '';
$ch = curl_init('https://captcha.softwalabs.com/siteverify');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'secret' => $_ENV['SOFTWACAP_SECRET'],
'response' => $response,
'remoteip' => $_SERVER['REMOTE_ADDR'] ?? '',
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($result['success']) && ($result['score'] ?? 0) > 0.5) {
// Es humano — procesar el formulario
} else {
// Bloquear o pedir verificación adicional
}
Node.js
const verify = async (token, ip) => {
const r = await fetch('https://captcha.softwalabs.com/siteverify', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
secret: process.env.SOFTWACAP_SECRET,
response: token,
remoteip: ip,
}),
});
const data = await r.json();
return data.success && data.score > 0.5;
};
Python
import requests
r = requests.post('https://captcha.softwalabs.com/siteverify', data={
'secret': os.environ['SOFTWACAP_SECRET'],
'response': token,
'remoteip': request.remote_addr,
})
data = r.json()
if data.get('success') and data.get('score', 0) > 0.5:
pass # humano
Códigos de error
| Código | Significado |
|---|---|
missing-input-secret | No se envió el parámetro secret. |
invalid-input-secret | El secret no coincide con ningún sitio. |
missing-input-response | No se envió el parámetro response. |
invalid-input-response | Token inválido, mal firmado o expirado. |
timeout-or-duplicate | Token ya usado (one-time-use). |
quota-exceeded | Has superado tu cuota mensual. |
rate-limited | Demasiadas peticiones desde tu IP. |
Tema (claro / oscuro / auto)
Tres modos por sitio. Default auto: sigue el prefers-color-scheme del visitante.
<!-- Auto (default) -->
<div class="softwacap" data-sitekey="..." data-theme="auto"></div>
<!-- Forzar claro -->
<div class="softwacap" data-sitekey="..." data-theme="light"></div>
<!-- Forzar oscuro -->
<div class="softwacap" data-sitekey="..." data-theme="dark"></div>
Si no pones data-theme en el HTML, se aplica el tema configurado en /dashboard/sites → editar → Tema del widget.
Checkbox "No soy un robot"
Tres modos. Default off (reto stellar directo). Configurable por sitio o por HTML.
| Modo | Comportamiento |
|---|---|
off | Reto stellar directo, sin checkbox. |
click | Caja con checkbox. Al pulsarlo evaluamos signals + fingerprint; si convence (score ≥ 0.6, en hard ≥ 0.7), tick verde sin reto. Si no, abre el reto stellar. |
auto | Igual que click pero también evaluamos al cargar la página. Si los signals iniciales son fuertes, marcamos solo sin que el visitante toque nada. |
<div class="softwacap" data-sitekey="..." data-checkbox-mode="auto"></div>
Doc completa con umbrales por dificultad: descarga el .md §7.5.
MCP server Pro+
Opera SoftwaCAP desde Claude Desktop, Claude Code u otros clientes IA.
El servidor MCP está en https://captcha.softwalabs.com/mcp y habla JSON-RPC 2.0 sobre HTTP (Streamable transport). Soporta los métodos initialize, tools/list, tools/call, ping.
1. Crea una API key personal
En /dashboard/settings → API Keys (MCP) genera una key con scope read (y write si quieres operaciones de escritura). La key se muestra una sola vez; cópiala.
2. Verifica tu key con curl (recomendado)
Antes de tocar el cliente, prueba que la key responde:
curl -s -X POST https://captcha.softwalabs.com/mcp \
-H "Authorization: Bearer ak_swl_TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_sites","arguments":{}}}'
Si devuelve un JSON con tus sitios, la key está OK. Si responde Unauthorized, revisa que esté completa (39 caracteres con prefijo ak_swl_) y que no esté revocada.
3. Configura tu cliente MCP
Claude Code (CLI)
Comando único:
claude mcp add softwacap https://captcha.softwalabs.com/mcp \
--transport http \
--header "Authorization: Bearer ak_swl_TU_API_KEY"
O editando ~/.claude.json (Linux/macOS) / %USERPROFILE%\.claude.json (Windows):
{
"mcpServers": {
"softwacap": {
"type": "http",
"url": "https://captcha.softwalabs.com/mcp",
"headers": {
"Authorization": "Bearer ak_swl_TU_API_KEY"
}
}
}
}
Reinicia Claude Code. Verifica con /mcp que softwacap aparece como conectado.
Claude Desktop
Edita ~/.config/claude/claude_desktop_config.json (Linux/macOS) o %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"softwacap": {
"url": "https://captcha.softwalabs.com/mcp",
"headers": {
"Authorization": "Bearer ak_swl_TU_API_KEY"
}
}
}
}
Reinicia Claude Desktop. El asistente verá las tools de SoftwaCAP automáticamente.
Otros clientes MCP
Cualquier cliente MCP-compatible funciona apuntando al endpoint https://captcha.softwalabs.com/mcp con header Authorization: Bearer ak_swl_.... Transporte: Streamable HTTP (JSON-RPC 2.0 sobre POST). No necesita SSE.
3. Tools disponibles
Lectura (Pro+)
| Tool | Descripción |
|---|---|
list_sites | Lista todos tus sitios |
get_site | Detalles de un sitio (incluye secret_key) |
get_quota | Uso actual del mes y límite del plan |
get_stats | Estadísticas agregadas (total, % éxito, scores) |
recent_verifications | Últimas verificaciones (filtrable por site / sólo fallos) |
get_billing_info | Plan, ciclo, fecha de renovación |
Escritura (Pro+, scope write)
| Tool | Descripción |
|---|---|
create_site | Crea un sitio nuevo y devuelve sitekey + secret_key |
update_site | Modifica nombre, dominios, dificultad o estado activo |
rotate_secret | Invalida el secret_key actual y genera uno nuevo |
delete_site | Elimina un sitio definitivamente |
Avanzadas Business+
| Tool | Descripción |
|---|---|
simulate_verify | Simula una verificación con perfil human / bot / borderline y devuelve el score |
bulk_export_csv | Exporta hasta 50.000 verificaciones como CSV |
4. Ejemplo de prompts
Tú: Lista mis sitios y dime cuáles tuvieron mayor tasa de fallo este mes.
Tú: Crea un sitio nuevo para midominio.com en dificultad easy con Adaptive Pace activado.
Tú: Simula una verificación con perfil bot y otra con perfil humano para ver la diferencia de scores.
Tú: Exporta a CSV las verificaciones fallidas de los últimos 7 días del sitio #3.
Adaptive Pace Pro+
Captcha que se ajusta solo al ritmo de tus humanos.
Por defecto un sitio tiene una dificultad fija (easy, normal o hard). Con Adaptive Pace activo,
el motor recalcula los timings reales (velocidad de flash, pausa entre estrellas, longitud de la secuencia) en función
de la tasa de éxito de las sesiones humanas en los últimos 7 días.
Cómo decide el ajuste
- Sólo cuenta verificaciones con
behavior_score ≥ 0.6Yai_score ≥ 0.5. Los bots no envenenan la métrica. - Necesita al menos 30 muestras humanas en los últimos 7 días. Mientras tanto usa el baseline.
- Si la tasa de éxito humano < 60% → relaja: +20% al flash, +20% al gap, −1 a la secuencia (mínimo 3).
- Si > 95% → endurece: −10% al flash, −10% al gap, +1 a la secuencia (máximo 5).
- Recálculo cada 5 minutos. Cache en BD por sitio.
Cómo activarlo
En /dashboard/sites:
- Al crear un sitio nuevo: marca el checkbox Adaptive Pace en el modal.
- En sitios existentes: usa el botón Activar/Desactivar en la sección Adaptive Pace de cada sitio.
Alternativa MCP: update_site con adaptive_pace: true.
Proof-of-Work Business+
Capa adicional anti-scraping a escala.
El navegador del visitante debe resolver un sha256 con N bits a cero antes de que el server emita el token. Sube el coste por solve a un atacante que automatiza miles de captchas.
| Modo | Bits | Tiempo cliente típico |
|---|---|---|
off | 0 | Sin PoW (default) |
lite | 16 | ~10–50 ms |
medium | 20 | ~150–500 ms |
hard | 24 | ~2–10 s |
Activación
Solo plan Business o Enterprise. /dashboard/sites → editar → Proof-of-Work → elegir modo. También vía MCP con update_site y campo pow_mode.
Aviso importante
Si tu sitio combina checkbox_mode: auto con pow_mode != off, el visitante pierde el auto-pase: el precheck inicial llega antes de que el PoW esté resuelto. Solo tras pulsar el checkbox el widget tiene tiempo de calcular y emitir el token. Si quieres mantener el auto-pase, deja pow_mode = off.
¿Algo no funciona? Escribe a info@heramarth.com o usa el chat de soporte cuando estés logueado.