KYC Bio Único

Endpoint de Verificación Biométrica KYC


Endpoint de Verificación Biométrica KYC

Descripción General

El endpoint /api/v1/kyc/verify permite procesar verificaciones biométricas completas combinando detección de vida (liveness), comparación facial y validación de documentos de identidad. Este endpoint es flexible y acepta diferentes combinaciones de datos según las necesidades de tu flujo de verificación.


Paso 1: Validación de Licencia

Antes de utilizar el endpoint de verificación biométrica, debes validar tu licencia y obtener un token de acceso (access_token).

Endpoint de Validación

URL: /api/v1/license/validate
Método: POST
Tipo de contenido: application/json

Request Body

{
  "license": "string",
  "product": "string",
  "product_version": "string",
  "app_id": "string",
  "origin": "string",
  "challenge": "string",
  "attestation_token": "string",
  "integrity_token": "string",
  "metadata": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}

Parámetros Requeridos

  • license (string): Código de licencia proporcionado por JAAK
  • product (string): Nombre del producto (ej: "KYC")
  • product_version (string): Versión del producto
  • app_id (string): Identificador de la aplicación
  • origin (string): Origen de la solicitud

Parámetros Opcionales

  • challenge (string): Token de desafío para validación adicional
  • attestation_token (string): Token de attestation para verificación de integridad
  • integrity_token (string): Token de integridad
  • metadata (object): Metadatos adicionales

Headers Opcionales

  • traceparent (string): W3C Trace Context para trazabilidad E2E
    Formato: 00-<trace-id>-<span-id>-<flags>
    Ejemplo: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

Respuesta Exitosa (200)

Headers de Respuesta:

  • traceparent (string): W3C Trace Context ID que debe ser enviado en todas las peticiones subsecuentes
{
  "access_token": "string",
  "token_type": "string",
  "expires_at": "string",
  "session_id": "string",
  "jti": "string",
  "license": "string",
  "step": 0,
  "document": "string",
  "assets": {
    "document": "string",
    "liveness": "string"
  }
}

Campos de la Respuesta

  • access_token: Token JWT que usarás como Bearer Token en las siguientes solicitudes
  • token_type: Tipo de token (generalmente "Bearer")
  • expires_at: Fecha y hora de expiración del token
  • session_id: ID de sesión (shortkey) creado para el flujo KYC
  • jti: ID único del token JWT
  • license: Código de licencia validado
  • step: Paso actual del flujo (0 = inicio)
  • document: Tipo de documento esperado
  • assets: URLs o referencias a recursos necesarios

Ejemplo de Llamada

curl -X POST https://api.jaak.mx/api/v1/license/validate \
  -H "Content-Type: application/json" \
  -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" \
  -d '{
    "license": "TU_CODIGO_DE_LICENCIA",
    "product": "KYC",
    "product_version": "1.0",
    "app_id": "mi-app-id",
    "origin": "https://mi-app.com"
  }'

⚠️ Importante sobre el Token y Traceparent

  • Cada llamada a /api/v1/license/validate consume un token de la cuota de tu licencia
  • El access_token recibido debe ser utilizado en todas las llamadas subsecuentes al endpoint de verificación
  • CRÍTICO: El header traceparent retornado en la respuesta debe ser enviado en todos los endpoints subsecuentes para mantener la trazabilidad distribuida de las peticiones

Paso 2: Verificación Biométrica

Una vez validada tu licencia y obtenido el access_token, procede con la verificación biométrica.

Endpoint

URL: /api/v1/kyc/verify
Método: POST
Tipo de contenido: application/json


Autenticación

Este endpoint requiere autenticación mediante Bearer Token utilizando el access_token obtenido del endpoint de validación de licencia.

Header de Autorización

Authorization: Bearer {ACCESS_TOKEN}

⚠️ Importante:

  • El Bearer Token es el access_token recibido en el paso de validación de licencia
  • El header traceparent debe ser enviado en todas las peticiones para trazabilidad distribuida
  • El Session ID se extrae automáticamente del token JWT y se utiliza para actualizar el estado de la sesión en Redis

Headers

HeaderTipoRequeridoDescripción
AuthorizationstringBearer token con el access_token obtenido del endpoint de validación de licencia
traceparentstringW3C Trace Context ID obtenido del header de respuesta del endpoint de validación de licencia
LanguagestringNoIdioma de respuesta. Valores: en, es. Default: en

Ejemplo de Headers

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Language: es

Parámetros del Request Body

Todos los campos son opcionales, lo que permite realizar diferentes combinaciones de verificación según tu caso de uso.

Estructura del Request

{
  "document": {
    "front": "string",
    "back": "string",
    "force": true
  },
  "face": {
    "image": "string",
    "force": true
  },
  "liveness": {
    "video": "string",
    "force": true
  },
  "location": {
    "latitude": 0,
    "longitude": 0,
    "force": true
  }
}

Descripción de Parámetros

document (objeto, opcional)

Imágenes del documento de identidad.

  • front (string): Imagen en base64 del frente del documento
  • back (string): Imagen en base64 del reverso del documento
  • force (boolean): Forzar procesamiento aunque ya exista en sesión

face (objeto, opcional)

Imagen facial para comparación.

  • image (string): Imagen facial en base64
  • force (boolean): Forzar procesamiento aunque ya exista en sesión

liveness (objeto, opcional)

Video para detección de vida.

  • video (string): Video en base64 para prueba de vida
  • force (boolean): Forzar procesamiento aunque ya exista en sesión

location (objeto, opcional)

Coordenadas geográficas de la verificación.

  • latitude (number): Latitud de la ubicación
  • longitude (number): Longitud de la ubicación
  • force (boolean): Forzar procesamiento aunque ya exista en sesión

Respuestas

200 - Verificación Exitosa

La respuesta incluye los resultados de todos los procesos de verificación ejecutados:

{
  "liveness": {
    "status": "string",
    "score": 0,
    "message": "string",
    "error": "string",
    "cached": true,
    "results": {},
    "details": {}
  },
  "face": {
    "status": "string",
    "score": 0,
    "message": "string",
    "error": "string",
    "cached": true,
    "results": {},
    "details": {}
  },
  "document": {
    "extract": {
      "status": "string",
      "score": 0,
      "message": "string",
      "results": {},
      "details": {}
    },
    "verify": {
      "status": "string",
      "score": 0,
      "message": "string",
      "results": {},
      "details": {}
    }
  },
  "blacklist": {
    "ine": {},
    "renapo": {},
    "sat": {},
    "interpol": {},
    "ofac": {}
  },
  "oto": {
    "status": "string",
    "score": 0,
    "results": {}
  },
  "location": {
    "status": "string",
    "results": {}
  },
  "summary": {
    "is_complete": true,
    "finish_called": true,
    "missing_processes": []
  }
}

Campos de la Respuesta

  • liveness: Resultado de la prueba de vida
  • face: Resultado de la comparación facial
  • document: Extracción y verificación del documento
  • blacklist: Consultas en listas negras (INE, RENAPO, SAT, Interpol, OFAC)
  • oto: Verificación One-to-One (1:1)
  • location: Validación de ubicación
  • summary: Resumen del estado de la verificación
    • is_complete: Indica si el proceso está completo
    • missing_processes: Lista de procesos faltantes

400 - Bad Request

{
  "statusCode": 400,
  "message": "string",
  "errorCode": "string",
  "eventId": "string"
}

Causas comunes:

  • Session ID no encontrado en el token
  • Formato de datos inválido
  • Campos requeridos faltantes

401 - Unauthorized

{
  "statusCode": 401,
  "message": "Unauthorized - requires valid access token",
  "errorCode": "string",
  "eventId": "string"
}

Causas comunes:

  • Access token inválido o expirado
  • Bearer token no proporcionado
  • Access token no obtenido correctamente del endpoint de validación de licencia

500 - Internal Server Error

{
  "statusCode": 500,
  "message": "string",
  "errorCode": "string",
  "eventId": "string"
}

Ejemplos de Uso

Nota: En todos los ejemplos, ACCESS_TOKEN_FROM_LICENSE_VALIDATION es el access_token obtenido del endpoint /api/v1/license/validate.

Ejemplo 1: Verificación Completa

curl -X POST https://api.jaak.mx/api/v1/kyc/verify \
  -H "Authorization: Bearer ACCESS_TOKEN_FROM_LICENSE_VALIDATION" \
  -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" \
  -H "Language: es" \
  -H "Content-Type: application/json" \
  -d '{
    "liveness": {
      "video": "base64_video_string",
      "force": false
    },
    "face": {
      "image": "base64_image_string",
      "force": false
    },
    "document": {
      "front": "base64_front_image",
      "back": "base64_back_image",
      "force": false
    },
    "location": {
      "latitude": 19.4326,
      "longitude": -99.1332,
      "force": false
    }
  }'

Ejemplo 2: Solo Liveness y Face Match

curl -X POST https://api.jaak.mx/api/v1/kyc/verify \
  -H "Authorization: Bearer ACCESS_TOKEN_FROM_LICENSE_VALIDATION" \
  -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" \
  -H "Language: es" \
  -H "Content-Type: application/json" \
  -d '{
    "liveness": {
      "video": "base64_video_string"
    },
    "face": {
      "image": "base64_image_string"
    }
  }'

Ejemplo 3: Solo Documento

curl -X POST https://api.jaak.mx/api/v1/kyc/verify \
  -H "Authorization: Bearer ACCESS_TOKEN_FROM_LICENSE_VALIDATION" \
  -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" \
  -H "Language: es" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "front": "base64_front_image",
      "back": "base64_back_image"
    }
  }'

Notas Importantes

  1. Flexibilidad: Puedes enviar cualquier combinación de parámetros según tu flujo de verificación
  2. Caché: El sistema utiliza caché para optimizar procesos repetidos. Usa force: true para forzar un nuevo procesamiento
  3. Session ID: Se extrae automáticamente del token, no es necesario enviarlo como parámetro
  4. Formato Base64: Todas las imágenes y videos deben estar codificados en base64
  5. Estado de Sesión: Cada llamada actualiza el estado de la sesión en Redis
  6. Traceparent: El header traceparent obtenido de la validación de licencia debe ser enviado en todas las peticiones para trazabilidad E2E

Casos de Uso Comunes

Caso de UsoParámetros Requeridos
Onboarding completoliveness, face, document
Re-verificación biométricaliveness, face
Actualización de documentodocument
Verificación con geolocalizaciónCualquier combinación + location

Paso 3:Consulta detalles de session

A continuación, te mostramos cómo visualizar las sesiones KYC realizadas mediante API.

Puedes utilizar la siguiente URL para buscar

Endpoint

URL: /api/v1/kyc/session/<sessionID>
Método: GET
Tipo de contenido: application/json

El parámetro <sessionID> en la URL de arriba, corresponde con el parámetro sessionID de una Sesión KYC. Este parámetro sessionID se puede encontrar dentro de las propiedades preliminares al listar las sesiones KYC

Autenticación

Este endpoint requiere autenticación mediante Bearer Token de tipo API Key, el cual se obtiene desde el Dashboard de JAAK.

Authorization: Bearer {API_KEY_FROM_DASHBOARD}

⚠️ Nota importante: Este Bearer Token es diferente al access_token del endpoint de validación de licencia. Este debe ser una API Key obtenida directamente desde tu dashboard de JAAK.


Headers Requeridos

HeaderTipoRequeridoDescripción
AuthorizationstringBearer token con tu API Key del dashboard
Origin-DevicestringOrigen del dispositivo. Valores: web, android, ios

Ejemplo de Headers

Authorization: Bearer sk_live_abc123xyz789...
Origin-Device: web

Respuestas

200 - OK

Retorna el token JWT de sesión junto con los assets procesados (documento y liveness).

Headers de Respuesta:

  • X-Trace-ID (string): OpenTelemetry trace ID para distributed tracing
{
  "sessionId": "string",
  "accessToken": "string",
  "step": 0,
  "document": "string",
  "assets": {
    "document": {
      "status": true,
      "message": "string",
      "requestId": "string",
      "eventId": "string",
      "processingTime": "string",
      "documentType": {
        "type": "UNDEFINED",
        "country": "UNDEFINED"
      },
      "documentMetadata": "string",
      "documentData": {
        "mechanicalReadingZone": "string",
        "generalData": {
          "type": "string",
          "name": "string",
          "secondName": "string",
          "surname": "string",
          "motherSurname": "string",
          "gender": "string",
          "birthDate": "string",
          "country": "string",
          "validUntil": "string",
          "address": {
            "street": "string",
            "externalNumber": "string",
            "internalNumber": "string",
            "neighborhood": "string",
            "city": "string",
            "council": "string",
            "state": "string",
            "zipCode": "string",
            "fullAddress": "string"
          },
          "documentImage": {
            "photo": "string",
            "position": {
              "top": 0,
              "left": 0,
              "bottom": 0,
              "right": 0
            }
          }
        },
        "specificData": [
          {
            "label": "string",
            "value": "string"
          }
        ]
      },
      "state": {
        "supportedDocument": true,
        "isExpired": true,
        "isUnderAge": true,
        "message": "string"
      }
    },
    "liveness": {
      "requestId": "string",
      "eventId": "string",
      "score": 0,
      "processTime": 0,
      "bestFrame": "string",
      "state": {
        "isRealPerson": true,
        "message": "string"
      }
    }
  }
}

Campos de la Respuesta

Campos Principales:

  • sessionId (string): ID de la sesión KYC
  • accessToken (string): Token JWT de sesión
  • step (number): Paso actual del flujo KYC
  • document (string): Tipo de documento procesado

Assets - Document:

  • status (boolean): Estado del procesamiento del documento
  • message (string): Mensaje descriptivo del resultado
  • documentType: Tipo y país del documento procesado
  • documentData: Datos extraídos del documento
    • generalData: Información general (nombre, apellidos, género, fecha de nacimiento, dirección, etc.)
    • mechanicalReadingZone: Zona de lectura mecánica (MRZ)
    • specificData: Datos específicos del documento (CURP, CIC, etc.)
  • state: Estado del documento
    • supportedDocument: Si el documento es soportado
    • isExpired: Si el documento está vencido
    • isUnderAge: Si la persona es menor de edad

Assets - Liveness:

  • score (number): Puntuación de la prueba de vida (0-100)
  • bestFrame (string): Mejor frame capturado en base64
  • state: Estado de la prueba
    • isRealPerson: Si se detectó una persona real
    • message: Mensaje descriptivo del resultado

400 - Bad Request

{
  "statusCode": 400,
  "message": "string",
  "errorCode": "string",
  "eventId": "string"
}

Causas comunes:

  • Headers faltantes (Short-Key u Origin-Device)
  • Shortkey expirado o inválido
  • Estado de sesión inválido

500 - Internal Server Error

{
  "statusCode": 500,
  "message": "string",
  "errorCode": "string",
  "eventId": "string"
}

Ejemplo de Uso

curl -X GET https://api.jaak.mx/api/v1/kyc/session \
  -H "Authorization: Bearer sk_live_abc123xyz789..." \
  -H "Short-Key: 7f3e4d2c1b9a8f6e5d4c3b2a1" \
  -H "Origin-Device: web"

Respuesta Ejemplo

HTTP/1.1 200 OK
X-Trace-ID: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Content-Type: application/json

{
  "sessionId": "sess_abc123",
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "step": 2,
  "document": "INE",
  "assets": {
    "document": {
      "status": true,
      "message": "Documento procesado exitosamente",
      ...
    },
    "liveness": {
      "score": 95,
      "state": {
        "isRealPerson": true,
        "message": "Persona real detectada"
      },
      ...
    }
  }
}

Flujo de Uso Típico

  1. Crear un flow KYC mediante POST /api/v1/kyc/flow y obtener el shortkey
  2. Intercambiar el shortkey usando este endpoint para obtener el JWT de sesión
  3. Utilizar el accessToken devuelto para consultas subsecuentes o para obtener los assets procesados

Notas Importantes

  1. API Key vs Access Token: No confundir el Bearer Token de este endpoint (API Key del dashboard) con el access_token del endpoint de validación de licencia
  2. Shortkey válido: El shortkey debe ser válido y no haber expirado
  3. Distributed Tracing: El header X-Trace-ID en la respuesta permite el seguimiento distribuido de la petición
  4. Origin Device: Es obligatorio especificar el origen del dispositivo (web, android, ios)
  5. Assets disponibles: Los assets (documento y liveness) solo estarán disponibles si ya fueron procesados en la sesión

Soporte

Si tienes dudas o necesitas asistencia con la integración, contacta a nuestro equipo de soporte: