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.

EndpointCuerpoDevuelve
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

statusSignificado
Not StartedSesión creada; el usuario aún no abre el enlace.
In ProgressEl usuario está completando el flujo.
In ReviewRequiere revisión manual.
ApprovedIdentidad verificada.
DeclinedRechazada (documento inválido, rostro no coincide, suplantación…).
ResubmittedSe pidió repetir un paso.
Abandoned / ExpiredNo se completó o expiró el enlace.
Kyc ExpiredLa 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.