API de verificación
URL base: https://kyc.menteia.com/api/v1. Autentícate con el header x-api-key. Pide tu llave en contacto@menteia.com.
1 · Crear verificación
POST /api/v1/verifications
{
"reference": "cliente-1024", // requerido: tu id interno
"metadata": { "canal": "whatsapp" }, // opcional
"expected_details": { // opcional: validación cruzada
"first_name": "Ana", "last_name": "López", "date_of_birth": "1990-04-12"
}
}
201 → { "id": "uuid", "url": "https://kyc.menteia.com/v/?id=uuid", "status": "Not Started" }
Envía el url a tu usuario (liga por WhatsApp, redirect o iframe con allow="camera; microphone; fullscreen").
2 · Consultar resultado
GET /api/v1/verifications/{id} // ?full=1 incluye el detalle completo de cada validación
GET /api/v1/verifications?reference=cliente-1024
200 → {
"id": "uuid", "reference": "cliente-1024",
"status": "Approved", "approved": true,
"result": {
"document": { "type": "Identity Card", "number": "…", "personal_number": "CURP…",
"first_name": "…", "last_name": "…", "date_of_birth": "…", "expiration_date": "…" },
"liveness": { "status": "Approved", "score": 97 },
"face_match": { "status": "Approved", "score": 94 }
},
"registry": { // fuentes de autoridades
"verdict": "valid", // valid | invalid | inconclusive | not_applicable
"ine_lista_nominal": { "result": "valid" },
"curp_renapo": { "result": "valid" },
"dob_mismatch": false // fecha de nacimiento RENAPO ≠ documento
}
}
Bloque ip
"ip": {
"ip": "187.202.209.183", "country": "MX", "asn": 8151, "org": "Uninet S.A. de C.V.",
"tor": false, "hosting": false,
"risk": "low", // low | medium | high
"flags": [] // tor, hosting_o_vpn, fuera_de_mexico
}
Se analiza la conexión del dispositivo que abre el enlace. Una conexión desde Tor (risk: high) envía la verificación a In Review; hosting/VPN y conexiones fuera de México se reportan como alerta. Geolocalización IP por DB-IP.
Una verificación queda Approved solo si el documento, la prueba de vida y la comparación facial pasan y la credencial está vigente en la Lista Nominal del INE y la CURP es válida en RENAPO. Si un registro de gobierno no responde, queda In Review.
Consultas individuales
Cada consulta es un POST con x-api-key, responde en segundos y devuelve {"id", "servicio", "estado", …}. estado es ok, invalid o unavailable (HTTP 503: la fuente oficial no respondió; reintente). Puede enviar reference para su conciliación.
| Endpoint | Cuerpo | Devuelve |
|---|---|---|
POST /api/v1/curp | {"curp"} | Datos de RENAPO y estatus de la CURP |
POST /api/v1/curp/constancia | {"curp"} | archivo: URL del PDF oficial, descargable 30 días con su x-api-key |
POST /api/v1/ine/lista-nominal | {"cic", "identificador_ciudadano"} | Vigencia de la credencial |
POST /api/v1/vehiculos/repuve | {"placa"} | Marca, modelo, año, NIV y reporte de robo |
POST /api/v1/aml/offshore | {"nombre"} | Coincidencias en las 5 bases de filtraciones del ICIJ |
POST /api/v1/dominios | {"dominio"} | Fechas de registro, antigüedad en días, registrador y correo MX |
curl -X POST https://kyc.menteia.com/api/v1/curp/constancia -H "x-api-key: $KYC_KEY" -H "Content-Type: application/json" -d '{"curp":"XXXX000000XXXXXX00","reference":"cliente-1024"}'
200 → { "id": "uuid", "servicio": "curp/constancia", "estado": "ok",
"archivo": "https://kyc.menteia.com/api/v1/archivos/uuid.pdf" }
Log de procesamiento
Cada paso de cada verificación, captura o consulta queda registrado como un evento: creación, apertura, fotos, lecturas, MRZ, rostro, fuentes oficiales, decisión y webhook, con motor, resultado y duración. No contiene datos personales en claro (CURP parcial, IP truncada, sin nombres ni imágenes).
GET /api/v1/logs?reference=cliente-1024 // filtros: id, reference, tipo, desde, hasta, despues_de, limite (máx. 1000)
200 → { "eventos": [
{ "seq": 812, "fecha": "2026-09-24T15:48:48.113Z", "tipo": "verificacion", "referencia_id": "uuid",
"reference": "cliente-1024", "paso": "abierta", "estado": "low", "motor": "ip_propio", "ms": null,
"detalle": { "portal": "menteia", "ip": "189.236.104.0/24", "pais": "MX", "riesgo": "low" } }
], "siguiente": null }
Con portal en su propio dominio, el mismo log se replica en su servidor en segundos y se consulta ahí con GET https://<su-portal>/log-api/eventos y el encabezado Authorization: Bearer <token del log>, con los mismos filtros.
3 · Webhook (opcional)
Si registras una URL, te enviamos un POST en cada cambio de estado con {"event":"verification.updated","data":{…}} (el mismo objeto que el GET). Verifica la firma:
firma = HMAC_SHA256(tu_api_key, X-KYC-Timestamp + "." + body_crudo) // hex // compárala con X-KYC-Signature y rechaza timestamps con más de 5 min
Estados
| status | Significado |
|---|---|
Not Started | Sesión creada; el usuario aún no abre el enlace. |
In Progress | El usuario está completando el flujo. |
In Review | Requiere revisión manual. |
Approved | Identidad verificada. |
Declined | Rechazada (documento inválido, rostro no coincide, suplantación…). |
Resubmitted | Se pidió repetir un paso. |
Abandoned / Expired | No se completó o expiró el enlace. |
Kyc Expired | La verificación caducó por política de retención. |
Toma la decisión de negocio solo con Approved. El redirect del usuario no es prueba de aprobación.