API de datos de Prevención de fraude
La API de datos es la contraparte del lado del servidor del Web SDK. Úsala para extraer veredictos, agregar estadísticas y exportar datos para informes y conciliación — obteniendo las cifras sobre las que tus propios sistemas se ponen de acuerdo.
URL base
https://verify.captcha.laAutenticación
Todas las solicitudes a la API de datos se autentican con las credenciales de tu aplicación de Prevención de fraude, enviadas como cabeceras:
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRETWARNING
X-App-Secret es solo del lado del servidor. Nunca lo expongas a navegadores, aplicaciones móviles ni repositorios públicos. El SDK de página solo usa el appKey público.
Endpoints
Obtener un veredicto
Recupera el veredicto de una sola visita (p. ej. para conciliar una visita específica). Pasa exactamente un identificador: verdict_id (del veredicto que recibió la página) o cid (el id de clic, para tráfico con token de clic).
GET /v1/bot/verdict?verdict_id=VERDICT_ID
GET /v1/bot/verdict?cid=CID_OF_THE_VISIT
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRETfound indica si se encontró un veredicto. Cuando es true, data contiene los campos del veredicto descritos en la Referencia del veredicto:
{
"found": true,
"data": {
"cid": null,
"verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
"is_bot": true,
"score": 87,
"level": "high",
"action": "flag",
"reasons": ["automation", "network"],
"consistency": { "ok": false },
"degraded": false,
"created_at": "2026-06-25 00:00:00"
}
}Si no hay coincidencias, la respuesta es {"found": false}. Una solicitud sin verdict_id ni cid se rechaza con HTTP 400.
TIP
Los veredictos se almacenan unos segundos después de producirse, por lo que una consulta hecha justo después de la visita puede devolver found: false. Para comprobar una visita en tiempo real, usa en su lugar Verificar un token de veredicto.
Verificar un token de veredicto
Comprueba un verdict_token que tu página recibió del Web SDK. Úsalo para proteger contenido en tu servidor (consulta Verificación del lado del servidor). La comprobación se responde de inmediato y no depende de datos almacenados.
POST /v1/bot/verdict/verify
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json
{ "token": "vt1.eyJ2Ijoi...", "ip": "203.0.113.7", "consume": false }| Parámetro | Obligatorio | Descripción |
|---|---|---|
token | sí | El verdict_token del veredicto. |
ip | no | La dirección IP del visitante tal como la ve tu servidor. Si se indica, el token debe proceder de la misma red que la visita. Recomendado. |
consume | no | true = el token solo puede usarse una vez; una segunda comprobación devuelve already_used. Por defecto false: el token puede comprobarse de nuevo hasta que caduque. |
{
"valid": true,
"error": null,
"verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
"expired": false,
"expires_at": 1767225600,
"ip_match": true,
"verdict": {
"is_bot": false,
"level": "low",
"action": "record_only",
"score": 12,
"degraded": false,
"reasons": [],
"issued_at": 1767225000
}
}| Campo | Descripción |
|---|---|
valid | true cuando el token es auténtico, pertenece a tu app, no ha caducado, coincide con ip (si se indicó) y, con consume, no se ha usado. valid solo indica que el token es genuino. No indica que el visitante sea humano, así que comprueba también verdict. |
error | null, o el motivo por el que el token no es válido: malformed, bad_signature, expired, ip_mismatch, already_used, unavailable (no se pudo completar la comprobación de un solo uso; reintenta). |
expired / expires_at | Estado de caducidad y hora de caducidad (segundos Unix). |
ip_match | true / false cuando se indicó ip; en caso contrario, null. |
verdict | El veredicto firmado: is_bot, level, action, score, degraded, reasons, issued_at. null cuando no se pudo leer el token. |
Un control típico sirve el contenido cuando valid es true y verdict.is_bot es false. Decide tú cómo tratar verdict.degraded y las solicitudes que no traen ningún token. Si dejas pasar en caso de fallo, los visitantes reales siguen accediendo durante una caída. Si bloqueas en caso de fallo, nada pasa sin un token válido.
Los tokens caducan a los 10 minutos por defecto. Vuelve a ejecutar el SDK (por ejemplo en la siguiente carga de página) para obtener uno nuevo.
Estadísticas agregadas
Extrae recuentos en un rango temporal (totales, bots y el desglose por level y por día) para paneles e informes de calidad.
GET /v1/bot/stats?from=2026-06-01&to=2026-06-30
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET{
"from": "2026-06-01",
"to": "2026-06-30",
"cleaned": true,
"total": 124500,
"bots": 18230,
"by_level": { "low": 100300, "medium": 16900, "high": 6200, "critical": 1100 },
"by_day": [
{ "date": "2026-06-01", "total": 4100, "bots": 590 }
]
}from / to abarcan por defecto los últimos 7 días.
Exportación
Exporta filas de veredicto por visita para un rango temporal, para conciliación offline. Las filas se devuelven de la más reciente a la más antigua, por páginas.
GET /v1/bot/export?from=2026-06-01&to=2026-06-30&limit=1000
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET| Parámetro | Descripción |
|---|---|
from / to | Rango de fechas (YYYY-MM-DD). Opcional. |
limit | Filas por página, 1–5000 (por defecto 1000). |
cursor | Pasa el next_cursor de la página anterior para obtener la siguiente. |
{
"rows": [
{
"id": 1042, "cid": null, "verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
"is_bot": false, "score": 12, "level": "low", "action": "record_only",
"reasons": [], "consistency": { "ok": true }, "degraded": false,
"created_at": "2026-06-25 00:00:00", "rescored": false
}
],
"next_cursor": 1042
}Cada fila lleva los identificadores de la visita, la marca de tiempo y los campos del veredicto, para que puedas vincularla de vuelta con tus propios registros. next_cursor es null en la última página.
Cifras depuradas
Las estadísticas y exportaciones se reportan por defecto sobre una base depurada: el tráfico que posteriormente se identifica como inválido se reevalúa de forma continua y se elimina de las cifras. Esto ocurre de forma asíncrona, por lo que las cifras de ventanas muy recientes aún pueden ajustarse ligeramente. Pasa ?raw=1 para ver las cifras sin depurar; en export, cada fila además incluye un indicador rescored.
Conciliación por clic
Para escenarios de tráfico de pago, una sola visita se puede vincular de vuelta a un clic entregado concreto para que dos partes liquiden sobre él. Eso usa un token de clic y se cubre en la guía de Fraude publicitario.
Referencia del token de clic (para proveedores de tráfico)
Un proveedor de tráfico firma un token de clic en su propio servidor y lo añade a la URL de destino, de modo que el veredicto de la visita resultante se atribuye de vuelta al proveedor. La firma es offline: no requiere ninguna llamada a la API.
Obtén tus credenciales de firma
En el panel, abre tu aplicación → Prevención de fraude → Emitir clave de firma. Recibes:
bot_kid— el id de tu clave pública (se incluye en el token comopkid).bot_hmac_secret— tu secreto de firma, mostrado una sola vez. Guárdalo en el servidor.
Formato del token
ct.<base64url(payload)>.<base64url(HMAC_SHA256(body, bot_hmac_secret))>body es el base64url del payload JSON; la firma se calcula sobre esa cadena body.
Campos del payload
| campo | obligatorio | descripción |
|---|---|---|
pkid | sí | tu bot_kid; el backend lo usa para localizar tu secreto y verificar la firma |
cid | sí | id único de este clic; la clave de conciliación. Genera un valor nuevo y único por clic |
aud | no | el app_key del anunciante de destino. Cuando se establece, el token solo se acepta en la página de ese anunciante. Omítelo para permitir que cualquier página de anunciante lo acepte |
click_ts | no | segundos unix del momento en que se produjo el clic |
exp | no | segundos unix de caducidad; los tokens caducados se rechazan |
Añádelo al enlace
Añade el token como el parámetro de consulta _ctk en la URL de destino del anunciante:
https://advertiser.example/lp?_ctk=ct.<...>.<...>El SDK del anunciante lee _ctk automáticamente (configurable mediante tokenParam). Cada cid está protegido contra repetición: que el mismo visitante recargue la página no es problema, pero un token reutilizado en otro lugar se marca. Consulta el Modelo de seguridad.
Ejemplo (pseudocódigo)
const payload = { pkid, cid, aud: advertiserAppKey, click_ts: now, exp: now + 900 }
const body = base64url(JSON.stringify(payload))
const sig = base64url(hmacSha256(body, botHmacSecret))
const token = `ct.${body}.${sig}`
const url = `${destination}?_ctk=${encodeURIComponent(token)}`Postback (servidor a servidor)
En lugar de consultar periódicamente la API de datos, puedes hacer que los veredictos se envíen a tu propio endpoint a medida que se producen — útil para trackers de afiliación y back-ends de anunciantes que quieren registrar o conciliar cada visita en tiempo real.
Actívalo
En el panel, abre tu aplicación → Prevención de fraude → configura la URL de postback (bot_postback_url). Una vez configurada, cada veredicto se envía por POST a esa URL poco después de producirse. La entrega es asíncrona y aislada — un endpoint lento o con fallos nunca afecta al veredicto ya devuelto al SDK de la página.
Cuándo se dispara
En cada verificación que produce un veredicto para la aplicación. La entrega es de mejor esfuerzo con algunos reintentos automáticos; trátala como at-least-once y deduplica por verdict_id.
Solicitud
POST <your bot_postback_url>
Content-Type: application/json
X-Bot-Signature: t=<unix_ts>,v=<hex>Cuerpo (JSON):
{
"cid": "CID_OF_THE_VISIT",
"verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
"is_bot": 1,
"score": 87,
"level": "high",
"action": "flag",
"advertiser_app_id": 12,
"provider_app_id": 34,
"created_at": "2026-06-25 00:00:00"
}| campo | descripción |
|---|---|
cid | clave de conciliación de la visita (puede ser null si no había token de clic) |
verdict_id | id del veredicto; el mismo valor que recibió la página |
is_bot | 1 / 0 |
score | puntuación de riesgo |
level | low / medium / high / critical |
action | acción autoritativa del servidor (record_only / flag / challenge / deny) |
advertiser_app_id | id de la aplicación para la que se ejecutó la verificación |
provider_app_id | id del proveedor de tráfico cuando se atribuye mediante un token de clic; si no, null |
created_at | hora del veredicto (UTC) |
Verifica la firma
La cabecera X-Bot-Signature te permite confirmar que la solicitud procede realmente de nosotros. Tiene la forma t=<unix_ts>,v=<hex>, donde:
hex = HMAC_SHA256( "<unix_ts>." + raw_request_body , bot_hmac_secret )bot_hmac_secret es el mismo secreto de firma que emites en Prevención de fraude → Emitir clave de firma. Para verificar, recalcula el HMAC sobre el cuerpo sin procesar que recibiste (no vuelvas a serializar el JSON) y compara en tiempo constante. Opcionalmente, rechaza las solicitudes cuyo t esté demasiado lejos de tu reloj para acotar la reproducción.
// Express example
const [tsPart, vPart] = req.get('X-Bot-Signature').split(',')
const ts = tsPart.slice(2) // "t=" prefix
const v = vPart.slice(2) // "v=" prefix
const expected = crypto
.createHmac('sha256', BOT_HMAC_SECRET)
.update(ts + '.' + rawBody) // rawBody is the unparsed request body
.digest('hex')
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v))Próximos pasos
- Referencia del veredicto — los campos devueltos por estos endpoints
- Web SDK — recopila veredictos en tu página