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/senders/{personId}/kycSession
Autenticación: A nivel de tenant (x-api-key)
La ruta heredada
POST /v2/people/{personId}/kycSessionsigue funcionando para integraciones en migración, pero las nuevas integraciones deben usar/v2/senders.
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, país emisor), 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/sendersdocuments[]) antes de poder abrir una sesión — de lo contrario la solicitud devuelve422 NO_VERIFIABLE_DOCUMENT.
Cuerpo de la Solicitud
Ambos campos son requeridos:
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
language | string | Sí | Idioma del widget, xx o xx-XX (p. ej. en, es, pt-BR) |
redirectUrl | string (URL) | Sí | A dónde enviar al usuario cuando termine el flujo del widget |
curl --request POST \
--url https://{FQDN}/organizations/$TENANT/v2/senders/$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:
drivers_licensepassport- 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
- Crea la sesión y abre
widgetUrlpara tu usuario (enlace, redirección o webview — vea Entrega del widget). - El usuario fotografía su documento y toma una selfie en el widget.
- Inyo recibe directamente el resultado de verificación firmado — tú no manejas ninguna imagen de documento.
- 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). - Lea el resultado en ese webhook.
verificationStatusesVERIFIEDcuando la sesión fue aprobada,REJECTEDcuando fue rechazada yPENDINGcuando quedó retenida para revisión — en ese caso un segundo evento llega después con la decisión del revisor. Eliddel 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: PENDING → VERIFIED, REJECTED, PENDING_REVIEW, SUPERSEDED, FAILED o EXPIRED.
PENDING_REVIEW significa que el resultado no alcanzó un veredicto automático frente a los umbrales de aprobación y rechazo configurados para su tenant, por lo que queda retenido para un revisor de Inyo. Es un reporte de progreso, no un resultado: un segundo evento llega cuando la revisión concluye. En sandbox toda sesión que alcanza un veredicto llega aquí, porque allí no hay umbrales configurados, y nadie revisa sus remitentes de prueba — así que usted mismo resuelve cada una con Resolver una sesión KYC retenida. SUPERSEDED, FAILED y EXPIRED son terminales y no concluyen nada sobre el documento — vea Cuando una sesión termina sin veredicto. Una sesión que el remitente no terminó termina en EXPIRED 49 horas después de su creación por defecto; su enlace deja de abrirse a las 48.
Errores
| HTTP | Error | Causa |
|---|---|---|
404 | NOT_FOUND | Persona no encontrada en tu tenant |
422 | NO_VERIFIABLE_DOCUMENT | La persona no tiene en su registro un documento verificable por KYC y no vencido — declara uno vía POST /v2/senders (documents[]) primero |
422 | VALIDATION_ERROR | language o redirectUrl faltante o mal formado |
422 | KYC_UNAVAILABLE | La 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/senders/{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/senders/$PERSON_ID/kycSession/$SESSION_ID \
--header "x-api-key: $API_KEY"
| Campo | Notas |
|---|---|
sessionId | El mismo valor que lleva el id de DocumentUpdatedEvents |
status | PENDING, VERIFIED, REJECTED, PENDING_REVIEW, SUPERSEDED, FAILED, EXPIRED u ORPHANED |
result | El 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. |
completedAt | Nulo mientras no esté decidida, y para PENDING_REVIEW — que reporta progreso, no un resultado. Definido para todo estado terminal, incluidos los que no concluyeron nada. Este marca cuándo la verificación llegó a su resultado; el completedAt dentro de result, cuando está presente, es el de la sesión KYC, definido cuando terminó la evaluación — incluso mientras este sigue nulo durante PENDING_REVIEW. |
createdAt | Cuándo se creó la sesión |
widgetUrl | Solo 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ón | Valor(es) canónico(s) | Descripción |
|---|---|---|
passport | PASSPORT | Pasaporte |
driversLicense | DRIVERS_LICENSE | Licencia de conducir |
nationalId | DNI, CC, ID | Documento nacional — DNI (España/Argentina/Perú), CC (cédula de Colombia) o documento de identidad genérico |
cpf | CPF | CPF (Brasil) |
consularId | CONSULAR_ID | Identificación consular (matrícula consular) |
voterId | VOTER_ID | Credencial de elector |
ssn | SSN | Tarjeta de Seguro Social de EE. UU. |
itin | ITIN | ITIN de EE. UU. (IRS) |
other | OTHER | Otro documento emitido por el gobierno |
Las tres variantes de documento nacional (
DNI,CC,ID) se agrupan en el único valor de transmisiónnationalId, 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
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
file | file | Sí | La imagen del documento — pdf, jpg, jpeg o png, máx. 10 MB |
idNumber | string | No | El número impreso en el documento |
issuer | string | No | Autoridad o estado emisor |
expirationDate | string | No | Formato 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.
La carga llega como PENDING y la verifica el OCR con IA donde está habilitado, o el equipo de cumplimiento de Inyo. Hasta que se verifique no cuenta para ningún nivel de cumplimiento. En sandbox no ocurre ninguna de las dos cosas por sí sola — resuélvala usted mismo con Resolver una revisión de documento pendiente.
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 devuelven404. Lea el resultado de una sesión en el webhookDocumentUpdatedEvents, y el veredicto resultante enkycVerdicten 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
| Estado | Descripción |
|---|---|
PENDING | Documento cargado, en espera de verificación |
VERIFIED | Documento aceptado — el nivel de cumplimiento puede subir |
REJECTED | Documento 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
idNumberyexpirationDatecuando 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 aGET /participants/{id}/complianceLevelspara ver si el remitente subió de nivel. - Maneja los rechazos con cuidado — muestra el
reasondel rechazo y solicita al usuario que vuelva a cargar el documento. - Usa webhooks en lugar de polling — regístrate a
DocumentUpdatedEventspara recibir notificaciones de inmediato.
Datos de Prueba
Para pruebas en sandbox, vea Pruebas en Sandbox — números de documento reservados que dictan un resultado de verificación, un endpoint para resolver una sesión retenida, y los valores del remitente sobre los que actúa la red de payout.
