Inyo

Verificación de Documentos

Para avanzar un remitente a niveles de cumplimiento más altos (Nivel 2 en adelante), sus documentos de identidad deben ser verificados. Hay dos formas de lograrlo:

  • Sesión de Verificación KYC (recomendado) — crea una sesión y entrega a tu usuario la URL de un widget alojado. El widget captura las fotos del documento y una selfie, las verifica, y el resultado fluye automáticamente al registro del remitente.
  • Carga directa de documentos (obsoleto) — envía tú mismo los archivos de imagen del documento y espera la revisión por OCR/manual.

⚠️ Los endpoints de carga directa están obsoletos. Las nuevas integraciones deben usar Sesiones de Verificación KYC. Las integraciones de carga existentes siguen funcionando, pero el flujo de sesión agrega prueba de vida con selfie, comparación facial con el retrato del documento y defensa contra ataques de presentación, algo que la carga simple de archivos no puede ofrecer.


Sesiones de Verificación KYC (Recomendado)

Endpoint: POST /organizations/{tenant}/v2/people/{personId}/kycSession
Autenticación: A nivel de tenant (x-api-key)

Crea una sesión de Verificación de Identidad Inyo360 para la persona. Solo proporcionas parámetros de presentación del widget — el documento a verificar se resuelve automáticamente a partir de los documentos declarados de la persona, y la sesión se precarga con los datos del registro (nombre, fecha de nacimiento, número de documento, estado emisor, nacionalidad), de modo que el usuario solo tiene que capturar su documento y selfie.

Declara el documento primero. La persona debe tener en su registro un documento verificable por KYC y no vencido (agregado vía POST /v2/people documents[]) antes de poder abrir una sesión — de lo contrario la solicitud devuelve 422 NO_VERIFIABLE_DOCUMENT.

Cuerpo de la Solicitud

Ambos campos son requeridos:

CampoTipoRequeridoDescripción
languagestringIdioma del widget, xx o xx-XX (p. ej. en, es, pt-BR)
redirectUrlstring (URL)A dónde enviar al usuario cuando termine el flujo del widget
curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/v2/people/$PERSON_ID/kycSession \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --data '{
  "language": "es",
  "redirectUrl": "https://your-app.example/kyc/done"
}'

Cómo se Selecciona el Documento

Inyo recorre los documentos declarados de la persona en orden de prioridad y verifica el primero que califique:

  1. drivers_license
  2. passport
  3. La familia de documentos de identidad, del más específico al más genérico: dni, cc, cpf, consular_id, voter_id, id

Los documentos con fecha de vencimiento en el pasado se omiten (una persona con licencia de conducir vencida y pasaporte vigente usa el pasaporte); los documentos sin fecha de vencimiento registrada se aceptan. ssn, itin y other nunca se seleccionan — no corresponden al vocabulario de documentos de KYC.

La verificación cruzada de datos está siempre activa: la capa KYC compara los datos extraídos del documento capturado contra el registro precargado de la persona.

Respuesta (201):

{
  "sessionId": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
  "status": "pending",
  "widgetUrl": "https://{FQDN}/verify/8Kd2mQ..."
}

El Flujo

  1. Crea la sesión y abre widgetUrl para tu usuario (enlace, redirección o webview — vea Entrega del widget).
  2. El usuario fotografía su documento y toma una selfie en el widget.
  3. Inyo recibe directamente el resultado de verificación firmado — tú no manejas ninguna imagen de documento.
  4. Con un resultado verificado, los registros de documentos de la persona se crean/actualizan automáticamente con el veredicto de verificación, y se dispara el webhook DocumentUpdatedEvents (webhooks).
  5. Lea el resultado en ese webhook. verificationStatus es VERIFIED cuando la sesión fue aprobada, REJECTED cuando fue rechazada y PENDING cuando fue enviada a revisión manual — en ese caso un segundo evento llega después con la decisión del analista. El id del evento es el id de la sesión en ambos, por lo que los dos se correlacionan.

El webhook es el canal más rápido, y consultar la sesión es el recurso cuando se pierde una entrega. Suscribirse a DocumentUpdatedEvents sigue siendo lo que hace el flujo orientado a eventos en lugar de basado en polling. El veredicto también se graba en el documento de la persona como kycVerdict (legible vía GET /people/{personId}): VERIFIED para una sesión aprobada, REJECTED para una rechazada. Una sesión aún en revisión deja el documento mostrando lo que la verificación del documento declarado registró al crear la persona — lo cual no es una afirmación sobre esta sesión. Lea el webhook para el resultado de la propia sesión.

Las sesiones pasan por estos estados del lado de Inyo: PENDINGVERIFIED, REJECTED, PENDING_REVIEW (revisión manual en la capa KYC) o EXPIRED.

Errores

HTTPErrorCausa
404NOT_FOUNDPersona no encontrada en tu tenant
422NO_VERIFIABLE_DOCUMENTLa persona no tiene en su registro un documento verificable por KYC y no vencido — declara uno vía POST /v2/people (documents[]) primero
422VALIDATION_ERRORlanguage o redirectUrl faltante o mal formado
422KYC_UNAVAILABLELa verificación KYC no pudo completarse — el servicio no estaba disponible, o KYC no está configurado para tu tenant. Reintenta con backoff; si persiste, contacta al soporte de Inyo.

Consultar una Sesión de Verificación

Endpoint: GET /organizations/{tenant}/v2/people/{personId}/kycSession/{sessionId}
Autenticación: Nivel de tenant

Consulte una sesión — el recurso para cuando se pierde una entrega de webhook. Usted siempre tiene el id: se devuelve al crear la sesión y acompaña a cada DocumentUpdatedEvents como id.

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/v2/people/$PERSON_ID/kycSession/$SESSION_ID \
  --header "x-api-key: $API_KEY"
CampoNotas
sessionIdEl mismo valor que lleva el id de DocumentUpdatedEvents
statusPENDING, VERIFIED, REJECTED, PENDING_REVIEW, EXPIRED u ORPHANED
resultEl resultado normalizado completo, incluyendo checks[]. Nulo hasta que llega el primer resultado, por lo que una sesión PENDING devuelve un estado y ningún resultado.
completedAtNulo mientras no esté decidida, y para PENDING_REVIEW — que reporta progreso, no un resultado
createdAtCuándo se creó la sesión
widgetUrlSolo mientras la sesión no está decidida. El token está en la ruta de la URL, así que no se devuelve uno ya gastado.

404 cuando el id de la sesión es desconocido, pertenece a otra persona o pertenece a otra organización.

Legado: Carga Directa de Documentos (Obsoleto)

⚠️ Obsoleto. Usa las Sesiones de Verificación KYC en su lugar. Estos endpoints permanecen disponibles para integraciones existentes. Los documentos cargados se verifican con OCR de IA (cuando está habilitado para tu tenant) o por el equipo de cumplimiento de Inyo.


Documentos de Identidad

Endpoint: POST /organizations/{tenant}/people/{personId}/documents/documentId/{subtype}/upload
Autenticación: Nivel de tenant (x-api-key)
Content-Type: multipart/form-data

El segmento de ruta {subtype} es el tipo de documento. Se aceptan tanto el formato de transmisión (passport, driversLicense, ...) como el formato canónico en mayúsculas (PASSPORT, DRIVERS_LICENSE, ...). El conjunto completo:

Valor de transmisiónValor(es) canónico(s)Descripción
passportPASSPORTPasaporte
driversLicenseDRIVERS_LICENSELicencia de conducir
nationalIdDNI, CC, IDDocumento nacional — DNI (España/Argentina/Perú), CC (cédula de Colombia) o documento de identidad genérico
cpfCPFCPF (Brasil)
consularIdCONSULAR_IDIdentificación consular (matrícula consular)
voterIdVOTER_IDCredencial de elector
ssnSSNTarjeta de Seguro Social de EE. UU.
itinITINITIN de EE. UU. (IRS)
otherOTHEROtro documento emitido por el gobierno

Las tres variantes de documento nacional (DNI, CC, ID) se agrupan en el único valor de transmisión nationalId, para que los clientes no tengan que manejar nombres específicos por país.

Un subtipo desconocido devuelve 422 INVALID_SUBTYPE con la lista allowed en la respuesta. PROOF_OF_FUNDS deliberadamente no se acepta aquí — use el endpoint dedicado de origen de fondos.

Campos del Formulario

CampoTipoRequeridoDescripción
filefileLa imagen del documento — pdf, jpg, jpeg o png, máx. 10 MB
idNumberstringNoEl número impreso en el documento
issuerstringNoAutoridad o estado emisor
expirationDatestringNoFormato YYYY-MM-DD
curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents/documentId/PASSPORT/upload \
  --header "x-api-key: $API_KEY" \
  --form "file=@/path/to/passport.jpg" \
  --form "idNumber=AB1234567" \
  --form "expirationDate=2030-12-31"

Respuesta (201):

{
  "id": "4ec66735-216b-4ab4-b1d7-00558baa6d85",
  "subtype": "PASSPORT",
  "fileName": "passport.jpg",
  "verificationStatus": "PENDING",
  "createdAt": "2026-08-04T12:00:00+00:00",
  "idNumber": "AB1234567",
  "issuer": null,
  "expirationDate": "2030-12-31"
}

Origen de Fondos

Comprobante del origen de fondos del remitente (estado de cuenta bancario, recibo de nómina), requerido para los niveles de cumplimiento más altos.

Endpoint: POST /organizations/{tenant}/people/{personId}/documents/sourceOfFunds/upload
Autenticación: Nivel de tenant (x-api-key)
Content-Type: multipart/form-data

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents/sourceOfFunds/upload \
  --header "x-api-key: $API_KEY" \
  --form "file=@/path/to/bank-statement.pdf"

Aplican las mismas reglas de archivo que para los documentos de identidad (pdf/jpg/jpeg/png, máx. 10 MB). La carga se almacena bajo el tipo PROOF_OF_FUNDS.


Estado de Verificación de Documentos

Después de la carga, los documentos se verifican de forma asíncrona — mediante OCR con IA (si está habilitado para tu tenant) en cuestión de minutos, o de lo contrario por el equipo de cumplimiento.

Estos endpoints cubren únicamente documentos cargados. Resuelven {documentId} como una carga, por lo que un documento verificado mediante una sesión de verificación KYC no tiene registro aquí y ambas rutas devuelven 404. Lea el resultado de una sesión en el webhook DocumentUpdatedEvents, y el veredicto resultante en kycVerdict en el documento de la persona.

Obtener el Estado de Verificación Actual

Endpoint: GET /organizations/{tenant}/documents/{documentId}/verificationStatus/current
Autenticación: Nivel de tenant

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/documents/$DOCUMENT_ID/verificationStatus/current \
  --header "x-api-key: $API_KEY"

Obtener el Historial de Estados de Verificación

Endpoint: GET /organizations/{tenant}/documents/{documentId}/verificationStatus
Autenticación: Nivel de tenant

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/documents/$DOCUMENT_ID/verificationStatus \
  --header "x-api-key: $API_KEY"

Devuelve entradas con status, reason, verifiedBy y createdAt — el campo reason explica los rechazos para que puedas guiar al usuario a volver a cargar el documento.

Listar los Documentos de una Persona

Lista cargas, por lo que una persona cuyos documentos se verificaron todos mediante sesiones KYC devuelve un arreglo vacío. Sus documentos declarados y veredictos están en el registro de la persona.

Endpoint: GET /organizations/{tenant}/people/{personId}/documents
Autenticación: Nivel de tenant

curl --request GET \
  --url https://{FQDN}/organizations/$TENANT/people/$PERSON_ID/documents \
  --header "x-api-key: $API_KEY"

Estados de Verificación

EstadoDescripción
PENDINGDocumento cargado, en espera de verificación
VERIFIEDDocumento aceptado — el nivel de cumplimiento puede subir
REJECTEDDocumento rechazado — revisa el reason y vuelve a cargar

Notificaciones por Webhook

Regístrate al webhook DocumentUpdatedEvents para recibir notificaciones cuando el estado de verificación de un documento cambie — un evento al cargar (PENDING) y otro cuando la verificación finaliza (VERIFIED/REJECTED). Ver Webhooks para la referencia del payload.


Mejores Prácticas

  • Carga imágenes de alta calidad — las imágenes borrosas o recortadas serán rechazadas.
  • Envía idNumber y expirationDate cuando los tengas — enriquecen el registro de cumplimiento y aceleran la revisión.
  • Verifica el nivel de cumplimiento después de la verificación — una vez que un documento esté VERIFIED, llama a GET /participants/{id}/complianceLevels para ver si el remitente subió de nivel.
  • Maneja los rechazos con cuidado — muestra el reason del rechazo y solicita al usuario que vuelva a cargar el documento.
  • Usa webhooks en lugar de polling — regístrate a DocumentUpdatedEvents para recibir notificaciones de inmediato.

Datos de Prueba

Para pruebas en sandbox, ver Datos de Prueba y Pruebas en Sandbox — ciertas combinaciones de nombre/dirección activan comportamientos de cumplimiento específicos (aprobación, retención, rechazo).