Saltar al contenido principal

KYC Magic Link

Contrato regional separado

Este caso de uso no utiliza el endpoint de Unico POST /v1/process ni el contrato API/TCA. La integración es con Trully.ai (host api.trully.ai), con autenticación mediante x-api-key en lugar de Bearer JWT, y un esquema de respuesta propietario. Para otros países, use Onboarding (Global).

Qué resuelve este caso de uso

KYC Magic Link aborda el desafío de ejecutar el proceso de identificación en México, recopilando documentos de identidad nacionales (INE) y biometría facial. Con un journey alojado por Unico, se elimina la fricción de desarrollo front-end mediante un enlace enviado a través de sus propios canales (WhatsApp, SMS, correo electrónico).

Use este caso de uso cuando:

  • Opera en México y el documento de identidad utilizado es el INE (obligatorio).

No use este caso de uso cuando:

  • El usuario está fuera de México o utiliza otros documentos → consulte los otros casos de uso de onboarding.

Capacidades involucradas

Pipeline ejecutado dentro de un único proceso:

CapacidadObligatoriaRol en el flujo
Captura de DocumentoObligatoriaCaptura la imagen del documento INE. La reutilización de documentos no está disponible en este caso de uso — cada sesión requiere una nueva captura.
LivenessObligatoriaVerificación de vida — selfie obligatoria que ancla el proceso.
Clasificación de RiesgoObligatoriaCruza señales de comportamiento para marcar el riesgo de fraude asociado al CPF.
Verificación de IdentidadOpcional (si contratada)Verifica si el rostro de la transacción pertenece al titular del identificador gubernamental proporcionado, usando la base de identidad de Unico y señales adicionales.

Prerequisitos

  • API key — aprovisionada por su Project Manager de Onboarding en Unico. Se envía en el encabezado x-api-key.
  • Endpoint HTTPS público para recibir webhooks (opcional, pero recomendado).
  • Configuración CORS — permita los orígenes https://verification.unico.app (producción) y https://verification.uat.unico.app (sandbox) en el servidor que recibe el webhook.

Implementación paso a paso

A diferencia de otros casos de uso, Magic Link no tiene campo flow — la integración es directa con la API de Trully. El endpoint crea un enlace de verificación único que usted distribuye al usuario a través de su propio canal.

1. Crear el Magic Link

Endpoint: POST https://sandbox.trully.ai/v2/magic-link

Encabezados:

EncabezadoObligatorioDescripción
x-api-keyAPI key aprovisionada por su Project Manager de Onboarding en Unico.
Content-Typeapplication/json

Cuerpo (application/json):

CampoTipoObligatorioDescripción
external_idstringNoUn identificador externo para la solicitud, utilizado para seguimiento y referencia.
metadataobjectNoContenedor para los parámetros de configuración.
metadata.phonestringNoNúmero de teléfono del usuario en formato internacional (p. ej., 521234567890).
metadata.redirect_urlstringNoURL a la que redirigir al usuario una vez completado el proceso KYC.
metadata.webhook_urlstringNoURL a la que enviar los datos del proceso KYC una vez completado. Este webhook se invocará del lado del cliente. Por razones de seguridad, el endpoint debe usar HTTPS. El componente esperará un minuto a que su servidor webhook responda — después de eso, interrumpirá la comunicación. El proceso no se verá afectado de ninguna manera por la comunicación del webhook. Asegúrese de permitir https://verification.unico.app y https://verification.uat.unico.app en su configuración CORS para producción y sandbox respectivamente.
metadata.track_webhook_urlstringNoURL a la que enviar cada paso KYC procesado por el usuario (consulte los eventos de webhook a continuación). Este webhook se invocará del lado del cliente. Por razones de seguridad, el endpoint debe usar HTTPS. El componente esperará un minuto a que su servidor webhook responda — después de eso, interrumpirá la comunicación. El proceso no se verá afectado de ninguna manera por la comunicación del webhook. Asegúrese de permitir https://verification.unico.app y https://verification.uat.unico.app en su configuración CORS para producción y sandbox respectivamente.

Valores posibles para data.step (enviados a track_webhook_url):

PasoDescripción
form_startEl usuario está escaneando el documento.
form_document_frontEl usuario ya capturó el frente del INE.
form_document_backEl usuario ya capturó el reverso del INE.
form_documentEl proceso está actualmente en el paso de selfie.
form_selfieEl usuario llegó al paso final de la operación.
form_decision_makerLa operación devuelve la respuesta del sistema.

Ejemplo de solicitud:

curl -X POST https://sandbox.trully.ai/v2/magic-link \
-H "x-api-key: $TRULLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-mx-12345",
"metadata": {
"phone": "521234567890",
"redirect_url": "https://app.client.com.mx/kyc-done",
"webhook_url": "https://app.client.com.mx/webhook/result",
"track_webhook_url": "https://app.client.com.mx/webhook/track"
}
}'
2. Recibir el token y la URL del enlace

Campos de la respuesta:

CampoTipoDescripción
data.external_idstring (nullable)Un identificador externo para la solicitud, utilizado para seguimiento y referencia.
data.created_onstring (date-time)La fecha en que se creó el magic link.
data.is_activebooleanSi es true, el magic link está activo.
data.tokenstringEl token del magic link que se usará para vincular los procesos KYC al magic link.
data.magic_link_urlstring (URI)La URL del magic link para iniciar el proceso KYC.
data.metadata.redirect_urlstring (nullable)URL a la que redirigir al usuario una vez completado el proceso KYC.
data.metadata.webhook_urlstring (nullable)URL a la que enviar los datos del proceso KYC una vez completado. Este webhook se invocará del lado del cliente.
data.metadata.track_webhook_urlstring (nullable)URL a la que enviar cada paso KYC procesado por el usuario. Este webhook se invocará del lado del cliente.
data.versionstringLa versión del magic link.
versionstringLa versión de la API que procesó la solicitud, útil para rastrear cambios y compatibilidad.
statusstringRepresentación textual del estado de la respuesta, indicando éxito o fallo de la operación.
status_codeintegerEl código de estado HTTP de la respuesta, proporcionando un indicador estandarizado del resultado de la solicitud.
request_datestring (date-time)La fecha y hora en que se realizó la solicitud, en formato ISO 8601.
request.metadata.redirect_urlstring (nullable)URL a la que redirigir al usuario una vez completado el proceso KYC (eco de la solicitud).
request.metadata.webhook_urlstring (nullable)URL a la que enviar los datos del proceso KYC una vez completado (eco de la solicitud).
request.metadata.track_webhook_urlstring (nullable)URL a la que enviar cada paso KYC procesado por el usuario (eco de la solicitud).

Ejemplo de respuesta:

{
"data": {
"external_id": null,
"created_on": "2025-07-28T18:11:54.430048399Z",
"is_active": true,
"token": "3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"magic_link_url": "https://verification.uat.unico.app/link/v2/3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"metadata": {
"redirect_url": null,
"webhook_url": null,
"track_webhook_url": null
},
"version": "v2"
},
"version": "v1.4.2",
"status": "ok",
"status_code": 200,
"request_date": "2025-07-28T18:11:54+0000",
"request": {
"metadata": {
"redirect_url": null,
"webhook_url": null,
"track_webhook_url": null
}
}
}
Respuestas de error — POST /v2/magic-link
CódigoMensajeDescripción
400 Bad Requestdata provided in the field is invalidEstructura de datos o valores de campo inválidos en el payload de la solicitud. Verifique los campos obligatorios y sus formatos.
403 ForbiddenForbiddenAPI key ausente, expirada o sin permiso. Verifique el encabezado x-api-key.
500 Internal Server Errorinternal server errorFallo de procesamiento en el servidor. Reintente con backoff exponencial. Si persiste, repórtelo al soporte.

Ejemplo de respuesta 400:

{
"data": {
"error": "data provided in the field is invalid"
},
"version": "v1.4.2",
"status": "bad request",
"status_code": 400,
"request_date": "2025-07-28T20:22:29+0000",
"request": {
"metadata": null
}
}
3. Distribuir magic_link_url al usuario

Envíe por WhatsApp, SMS, correo electrónico o incrústelo. El usuario accede al enlace desde su propio dispositivo y completa el journey alojado.

4. Recibir el resultado
  • Polling mediante GET (obligatorio) — llame a GET /v2/history/request?magic_link_token={token} periódicamente hasta que unico.result esté poblado. Consulte Polling mediante GET a continuación.
  • Webhook (opcional) — configúrelo con su PM de Onboarding para recibir eventos automáticamente. Consulte Webhook a continuación.

Polling mediante GET

Endpoint: GET https://sandbox.trully.ai/v2/history/request

Parámetros de consulta:

ParámetroTipoObligatorioDescripción
magic_link_tokenstringToken devuelto al crear el Magic Link.

Encabezados:

EncabezadoObligatorioDescripción
x-api-keyAPI key aprovisionada por su Project Manager de Onboarding en Unico.

Ejemplo de solicitud:

curl "https://sandbox.trully.ai/v2/history/request?magic_link_token=$TOKEN" \
-H "x-api-key: $TRULLY_API_KEY"

Ejemplo de respuesta:

{
"data": {
"images": {
"document_image": "/9j/4ASu7bmV[...]fyPjOKfgif//Z",
"document_image_back": "/9j/4ASu7bmV[...]fyPjOKfgif//Z",
"selfie": "/9j/4ASu7bmV[...]fyPjOKfgif//Z"
},
"response": {
"curp": {
"age": 58,
"curp": "GOCJ850627HDFRRL09",
"date_of_birth": "14/11/1956",
"deceased": false,
"gender": "M",
"government_name": "LUKE SKYWALKER",
"government_valid": true,
"is_mexican": true,
"name_to_CURP_valid": true,
"state_iso": "MX-NLE",
"state_of_birth": "Nuevo León"
},
"document": {
"back": {
"cic": "237457894",
"citizen_id": "237457894",
"mrz": "IDMEX999999999999<9 VADER<SKYWALKER<<LUKE"
},
"details": {
"detected": true,
"document_id": 229928,
"forensics": { "is_valid": "no" }
},
"front": {
"face_analysis": {
"face_id": 237437,
"face_id_v2": 199068,
"first_seen": "12/22/2022, 18:54:09",
"inquiry_date": "07/28/2025, 20:53:12",
"last_seen": "07/28/2025, 18:47:46",
"last_seen_by_your_company": "07/24/2025, 21:38:21",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 46,
"times_seen_by_your_company": 3,
"times_seen_last_month": 111,
"unique_face_id_v2": 126880,
"warnings": {
"external_id": "User found in the company with other external_ids: ['abc-123']"
}
},
"information": {
"address": { "text": "DOMICILIO/ADDRESS, HARLINGEN, TX 78552", "valid": false },
"birthdate": { "text": "14/11/1956", "valid": true },
"complete_name": { "text": "LUKE SKYWALKER", "valid": true },
"curp": { "text": "GOCJ850627HDFRRL09", "valid": true },
"electoral_key": { "text": "GRCRSN82031007M500", "valid": true },
"last_name": { "text": "SKYWALKER", "valid": true },
"mother_last_name": { "text": "ORGANA", "valid": true },
"name": { "text": "LUKE", "valid": true },
"registration_year": { "text": "1998", "valid": true },
"sex": { "text": "H", "valid": true },
"valid_thru": { "text": "2027", "valid": true }
}
}
},
"face_match": false,
"label": null,
"reason": null,
"request_id": "d1kxp9ah8f0s71uv9zx0",
"selfie": {
"face_id": 237436,
"face_id_v2": 4378,
"first_seen": "02/05/2025, 02:36:19",
"first_seen_image": true,
"inquiry_date": "07/28/2025, 20:52:49",
"last_seen": "07/28/2025, 20:52:51",
"last_seen_by_your_company": "07/23/2025, 18:14:27",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 2,
"times_seen_by_your_company": 2,
"times_seen_last_month": 7,
"unique_face_id_v2": 494,
"warnings": {}
},
"unico": {
"process_id": "d333dfac-9ddb-4066-8e2c-44eaf4c86b4a",
"result": "PROCESS_RESULT_LIVE"
}
},
"user_id": ""
},
"request_date": "2025-07-28T20:53:38",
"status": "Request fulfilled, document follows",
"status_code": 200,
"version": "v3.6.0"
}

Campos de la respuesta:

Nivel raíz:

CampoTipoDescripción
statusstringRepresentación textual del estado de la respuesta.
status_codeintegerCódigo de estado HTTP.
request_datestring (date-time)La fecha y hora en que se realizó la solicitud.
versionstringVersión de la API que procesó la solicitud.
data.user_idstringEl ID de usuario establecido en la solicitud original.

data.images — Imágenes capturadas en Base64:

CampoTipoDescripción
data.images.document_imagestringImagen en Base64 del frente del documento.
data.images.document_image_backstringImagen en Base64 del reverso del documento.
data.images.selfiestringImagen de selfie en Base64 capturada durante la verificación.

data.response.unico — Veredicto consolidado:

CampoTipoDescripción
data.response.unico.process_idstring (UUID)Identificador interno relacionado con el proceso de verificación.
data.response.unico.resultstringResultado del proceso. Los valores posibles se describen a continuación.

Valores posibles para data.response.unico.result:

El valor del resultado codifica una de tres dimensiones de evaluación:

  • Evaluación de identidad — si el rostro capturado pertenece al titular del documento (PROCESS_RESULT_VERIFIED, PROCESS_RESULT_NOT_APPROVED).
  • Comportamiento de fraude — si las señales de comportamiento o de red indican riesgo de fraude (PROCESS_RESULT_LIVE, PROCESS_RESULT_HIGH_RISK, PROCESS_RESULT_CRITICAL_RISK, PROCESS_RESULT_NOT_APPROVED).
  • Liveness — si se detectó un rostro vivo en el momento de la captura (PROCESS_RESULT_NOT_LIVE).
ResultadoRecomendaciónSignificadoSeñal
PROCESS_RESULT_ERRORRechazarEl proceso finalizó con error.Sistema
PROCESS_RESULT_VERIFIEDAceptarEl usuario estaba activo en el momento de la captura; es el rostro del titular del documento y no se encontró evidencia relacionada con fraude.Identidad: confirmada
PROCESS_RESULT_LIVERevisar / AceptarEl usuario estaba activo en el momento de la captura; no encontramos evidencia suficiente para garantizar que es el titular del documento y no hay evidencia de fraude.Identidad: no concluyente · Fraude: ninguno
PROCESS_RESULT_HIGH_RISKRecomienda rechazoEncontramos al menos una evidencia sólida de fraude. La decisión final es suya.Comportamiento de fraude: 1 señal fuerte
PROCESS_RESULT_CRITICAL_RISKRecomienda rechazoEncontramos al menos 2 evidencias sólidas de fraude. La decisión final es suya.Comportamiento de fraude: 2+ señales fuertes
PROCESS_RESULT_NOT_APPROVEDRechazarSe recomienda el rechazo ya que se detectaron múltiples indicios de fraude.Identidad: rechazada · Comportamiento de fraude: múltiples señales
PROCESS_RESULT_NOT_LIVEPermitir hasta 2 reintentosEl usuario no estaba vivo en el momento de la captura, aunque no encontramos otros indicios de fraude.Liveness: rostro no vivo
nota

PROCESS_RESULT_VERIFIED requiere activación. Por defecto, este resultado no está activo — consulte con su Project Manager de Unico si desea habilitarlo.

Señales auxiliares para su decisión:

Para los casos LIVE, HIGH_RISK o CRITICAL_RISK, complemente su decisión con estos campos:

CampoTipoSignificado
face_matchbooleanEstado de coincidencia facial entre documento y selfie.
document.front.face_analysis.match_fraud_flagbooleanSi el rostro del documento ha sido asociado con actividad fraudulenta.
selfie.match_fraud_flagbooleanSi el rostro de la selfie ha sido asociado con actividad fraudulenta.
warnings.external_idstringAdvertencia que indica que el rostro del usuario está asociado con múltiples IDs externos.

data.response — Señales de resultado de nivel superior:

CampoTipoDescripción
data.response.face_matchbooleanSi el rostro de la selfie coincide con el rostro del documento.
data.response.labelstring (nullable)Reservado para resultados de sub-procesos específicos; null si no aplica.
data.response.reasonstring (nullable)Razones para la etiqueta asignada.
data.response.request_idstringIdentificador único para la solicitud de API.

data.response.curp — Validación del CURP contra RENAPO:

CampoTipoDescripción
curpstringLa cadena CURP que se está analizando.
government_validbooleanSi el CURP es válido según RENAPO.
government_namestringNombre completo asociado al CURP en la base de datos oficial.
name_to_CURP_validbooleanSi el nombre proporcionado es consistente con el CURP.
is_mexicanbooleanSi el CURP corresponde a un ciudadano mexicano.
deceasedbooleanSi el CURP está marcado como fallecido en la base de datos oficial.
date_of_birthstringFecha de nacimiento decodificada del CURP (DD/MM/AAAA).
ageintegerEdad calculada del usuario.
genderstringGénero decodificado del CURP (M o F).
state_of_birthstringEstado de nacimiento decodificado del CURP.
state_isostringCódigo ISO 3166-2 del estado de nacimiento.

data.response.document.details — Detección y análisis forense del documento:

CampoTipoDescripción
detectedbooleanSi se detectó un documento exitosamente en la imagen.
document_idintegerIdentificador único del documento procesado.
forensics.is_validstringResultado del análisis forense: yes, no o inconclusive.

data.response.document.front.information — Campos extraídos por OCR del frente del INE. Cada campo contiene text (valor extraído) y valid (si pudo ser validado estructuralmente):

CampoDescripción
nameNombre(s).
last_nameApellido paterno.
mother_last_nameApellido materno.
complete_nameNombre completo.
birthdateFecha de nacimiento (DD/MM/AAAA).
sexSexo/género (H o M).
curpCURP extraído del documento.
electoral_keyClave de elector.
addressDomicilio.
registration_yearAño de registro del documento.
valid_thruAño de vencimiento del documento.

data.response.document.front.face_analysis — Análisis del rostro encontrado en el INE:

CampoTipoDescripción
face_idintegerIdentificador único de esta instancia de rostro.
face_id_v2integerIdentificador único (versión 2).
unique_face_id_v2integerIdentificador persistente para este rostro físico en todas las consultas.
first_seenstringMarca de tiempo de la primera vez que se vio este rostro en el sistema.
last_seenstringMarca de tiempo de la última vez que se vio este rostro en la red.
last_seen_by_your_companystringLa vez más reciente que este rostro fue visto en una consulta de su empresa.
inquiry_datestringMarca de tiempo de la consulta de verificación actual.
matchbooleanSi este rostro es una posible coincidencia con otros rostros en la base de datos.
match_fraud_flagbooleanSi este rostro ha sido asociado con actividad fraudulenta.
seen_by_your_companybooleanSi este rostro fue visto anteriormente por su empresa.
seen_different_companiesintegerNúmero de otras empresas en la red que han visto este rostro.
times_seen_by_your_companyintegerTotal de veces que este rostro fue visto en consultas de su empresa.
times_seen_last_monthintegerNúmero de veces visto el último mes en toda la red.
warnings.external_idstringAdvertencia si el rostro del usuario está asociado con múltiples IDs externos.

data.response.document.back — Datos MRZ del reverso del INE:

CampoTipoDescripción
mrzstringCadena completa de la Zona de Lectura Mecánica (MRZ).
cicstringNúmero CIC extraído del MRZ.
citizen_idstringNúmero de identificación ciudadana del MRZ.

data.response.selfie — Análisis de la selfie capturada:

CampoTipoDescripción
face_idintegerIdentificador único de la instancia del rostro en la selfie.
face_id_v2integerIdentificador único (versión 2).
unique_face_id_v2integerIdentificador persistente para este rostro físico en todas las consultas.
first_seenstringPrimera vez que el rostro de esta selfie fue visto en el sistema.
first_seen_imagebooleanSi es la primera vez que se ve esta imagen exacta.
last_seenstringLa vez más reciente que este rostro fue visto en la red.
last_seen_by_your_companystringLa vez más reciente que este rostro fue visto por su empresa.
inquiry_datestringMarca de tiempo de la consulta de verificación actual.
matchbooleanSi el rostro de la selfie coincide con otros rostros en la base de datos.
match_fraud_flagbooleanSi el rostro de la selfie está asociado con actividad fraudulenta.
seen_by_your_companybooleanSi este rostro fue visto anteriormente por su empresa.
seen_different_companiesintegerNúmero de otras empresas en la red que han visto este rostro.
times_seen_by_your_companyintegerTotal de veces que este rostro fue visto en consultas de su empresa.
times_seen_last_monthintegerNúmero de veces visto el último mes en toda la red.
warningsobjectAdvertencias específicas relacionadas con el análisis de la selfie (misma estructura que face_analysis del documento).

Use polling con backoff exponencial — no llame en un bucle cerrado.

Respuestas de error — GET /v2/history/request
CódigoMensajeDescripción
400 Bad RequestInput should be a valid UUID, invalid group length...El parámetro magic_link_token está malformado o no tiene un formato UUID válido.
404 Not FoundThis magic link have no requests associatedEl token proporcionado existe pero no tiene procesos KYC completados vinculados a él. Es posible que el usuario no haya terminado el journey.
500 Internal Server Errorinternal server errorFallo de procesamiento en el servidor. Reintente con backoff exponencial. Si persiste, repórtelo al soporte.

Ejemplo de respuesta 400:

{
"data": {
"error": [
{
"attribute": ["magic_link_token"],
"message": "Input should be a valid UUID, invalid group length in group 4: expected 12, found 11",
"type": "uuid_parsing"
}
]
},
"request_date": "2025-07-28T20:43:34",
"status": "There are some errors in the request",
"status_code": 400,
"version": "v3.6.0"
}

Ejemplo de respuesta 404:

{
"data": {
"error": "This magic link have no requests associated"
},
"request_date": "2025-07-28T20:40:50",
"status": "Nothing matches the given URI",
"status_code": 404,
"version": "v3.6.0"
}

Ejemplo de respuesta 500:

{
"data": {
"error": "internal server error"
},
"version": "v1.4.2",
"status": "bad request",
"status_code": 400,
"request_date": "2025-07-28T20:22:29+0000",
"request": {
"metadata": null
}
}

Webhook

Hay tres eventos de webhook disponibles. Para activarlos, solicite la configuración a su Project Manager de Onboarding proporcionando: URL del endpoint (HTTPS obligatorio), tipo de autenticación (basic_auth, api_key, oauth2 o NoAuth), configuración de autenticación, intentos máximos de reintento, intervalo de reintento (s) y tiempo de espera (s).

MAGIC_LINK_RESULTS

Este evento se envía al final del flujo, cuando el Decision Maker ha terminado de procesar la información enviada.

{
"data": {
"images": {
"document_image": "base64str",
"document_image_back": "base64str",
"selfie": "base64str"
},
"response": {
"document": {
"details": {
"detected": true,
"forensics": {
"is_valid": "yes"
},
"document_id": 123
},
"front": {
"information": {
"birthdate": { "text": "14/11/1956", "valid": true },
"sex": { "text": "H", "valid": true },
"registration_year": { "text": "1998", "valid": true },
"name": { "text": "LUKE", "valid": true },
"mother_last_name": { "text": "ORGANA", "valid": true },
"last_name": { "text": "SKYWALKER", "valid": true },
"electoral_key": { "text": "GRCRSN82031007M500", "valid": true },
"curp": { "text": "GOCJ850627HDFRRL09", "valid": true },
"address": { "text": "DOMICILIO/ADDRESS, HARLINGEN, TX 78552", "valid": false },
"complete_name": { "text": "LUKE SKYWALKER", "valid": true },
"valid_thru": { "text": "2027", "valid": true }
},
"face_analysis": {
"face_id": 237437,
"first_seen": "12/22/2022, 18:54:09",
"unique_face_id_v2": 126880,
"face_id_v2": 199068,
"inquiry_date": "07/28/2025, 20:53:12",
"last_seen": "07/28/2025, 18:47:46",
"last_seen_by_your_company": "07/24/2025, 21:38:21",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 46,
"times_seen_by_your_company": 3,
"times_seen_last_month": 111,
"warnings": {
"external_id": "User found in the company with other external_ids: ['abc-123']"
}
}
},
"back": {
"mrz": "IDMEX999999999999<9 VADER<SKYWALKER<<LUKE",
"cic": "237457894"
}
},
"selfie": {
"face_id": 237436,
"first_seen": "02/05/2025, 02:36:19",
"unique_face_id_v2": 494,
"face_id_v2": 4378,
"inquiry_date": "07/28/2025, 20:52:49",
"last_seen": "07/28/2025, 20:52:51",
"last_seen_by_your_company": "07/23/2025, 18:14:27",
"match": true,
"match_fraud_flag": true,
"seen_by_your_company": true,
"seen_different_companies": 2,
"times_seen_by_your_company": 2,
"times_seen_last_month": 7,
"warnings": {
"external_id": "User found in the company with other external_ids: ['abc-123']"
},
"first_seen_image": true
},
"face_match": false,
"curp": {
"curp": "GOCJ850627HDFRRL09",
"state_of_birth": "Nuevo León",
"state_iso": "MX-NLE",
"date_of_birth": "14/11/1956",
"age": 58,
"gender": "M",
"is_mexican": true,
"name_to_CURP_valid": true,
"government_valid": true,
"government_name": "LUKE SKYWALKER",
"deceased": false
},
"unico": {
"process_id": "d333dfac-9ddb-4066-8e2c-44eaf4c86b4a",
"result": "PROCESS_RESULT_LIVE"
},
"label": null,
"reason": null,
"request_id": "d1kxp9ah8f0s71uv9zx0"
},
"user_id": null
},
"event": "MAGIC_LINK_RESULTS",
"magic_link_token": "3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"user_id": null,
"date": "2025-10-03T21:15:41.299815"
}
MAGIC_LINK_TRACK

Estos eventos se reciben cuando el usuario completó una acción. Por ejemplo, form_start se recibirá cuando el usuario esté tomando el frente del documento, lo que significa que el usuario hizo clic y completó la primera pantalla.

{
"data": {
"completed_on": "Fri, 03 Oct 2025 21:15:35 GMT",
"started_on": "Fri, 03 Oct 2025 21:15:30 GMT",
"step": "form_start",
"user_id": null
},
"event": "MAGIC_LINK_TRACK",
"magic_link_token": "3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"user_id": null,
"date": "2025-10-03T21:15:41.299815"
}
CampoTipoDescripción
data.stepstringNombre del paso completado.
data.user_idstring (nullable)ID externo establecido en el magic link.
data.started_ondatetimeHora de inicio del paso en zona horaria UTC.
data.completed_ondatetimeHora de finalización del paso en zona horaria UTC.
eventstringIdentificador del tipo de evento.
magic_link_tokenuuidToken único del magic link.
user_idstring (nullable)Identificador externo.
datedatetimeMarca de tiempo del evento.

Pasos compatibles:

PasoDescripción
form_startEl usuario hizo clic en el botón inicial del magic link.
form_document_frontEl usuario completó la captura del frente del INE.
form_document_backEl usuario completó la captura del reverso del INE.
form_documentEl usuario completó los procesos del frente y el reverso.
form_selfieEl usuario completó el proceso de liveness.
form_decision_makerEl usuario completó el flujo completo.
MAGIC_LINK_DOCUMENT_RETAKE_REASONS

Este evento se envía cuando se requiere una nueva captura del documento, ya sea durante el proceso del frente o del reverso. Indica que no se pudo leer información crítica del INE.

{
"data": {
"document_type": "ine_front",
"invalid_back_ocr": false,
"invalid_curp": false,
"invalid_document": true
},
"event": "MAGIC_LINK_DOCUMENT_RETAKE_REASONS",
"magic_link_token": "3f6dbcc1-49ba-4935-be90-dd8dd59b5530",
"user_id": null,
"date": "2025-10-03T21:12:00.000Z"
}
CampoTipoDescripción
data.document_typestringCara del documento: ine_front o ine_back.
data.invalid_documentbooleantrue si la imagen capturada no es un INE válido (cualquier cara).
data.invalid_curpbooleantrue si el CURP no pudo ser leído (solo ine_front).
data.invalid_back_ocrbooleantrue si el código MRZ no pudo ser leído (solo ine_back).
eventstringIdentificador del tipo de evento.
magic_link_tokenuuidToken único del magic link.
user_idstring (nullable)Identificador externo.
datedatetimeMarca de tiempo del evento.

El payload está diseñado para que solo se reciba un error (true) por cada cara del documento.

Escenarios de fallo — frente del INE:

  • Documento inválido → solo invalid_document: true
  • Fallo en lectura del CURP → solo invalid_curp: true

Escenarios de fallo — reverso del INE:

  • Documento inválido → solo invalid_document: true
  • Fallo en lectura del MRZ → solo invalid_back_ocr: true
Compatibilidad V1 / V2

Si todavía envía webhook_url en los metadata de la solicitud (Webhook V1), esa configuración tiene prioridad sobre la V2 global. Para migrar, elimine webhook_url de metadata y configure V2 con su PM de Onboarding.


Personalizaciones

La página del Magic Link alojado no admite personalización visual por parte del cliente — sigue la identidad visual predeterminada de Unico/Trully. Para personalizar el journey (logo, colores, textos), use Onboarding (Global) con SDK o Web.

Disponibilidad: México · Endpoint: POST https://api.trully.ai/v2/magic-link · Documento: INE · Auth: x-api-key (Trully)