---
title: KYC Magic Link
description: Ejecuta el proceso de identificación en México, recopilando documentos de identidad nacionales (INE) y biometría facial a través de un journey alojado distribuido mediante un enlace único.
canonical: https://developer.unico.io/es/dual-api/products/sign-up/kyc-magic-link/index
locale: es
generated_by: markdown-export
---

- [/es/](/es/)
- [Construir](/es/dual-api/products/)
- Guía Regional Mexicana
- KYC Magic Link

**En esta página# KYC Magic Link

Contrato regional separadoEste caso de uso **no utiliza** el endpoint de Unico `POST /v1/process` ni el contrato API. 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:
[Captura de Documento (INE)](/es/capabilities/document-reuse-and-capture)[Liveness](/es/capabilities/liveness)[Clasificación de Riesgo](/es/capabilities/fraud-risk-classification)[Verificación de Identidad](/es/capabilities/identity-verification)
CapacidadObligatoriaRol en el flujo**Captura de Documento**ObligatoriaCaptura 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.**Liveness**ObligatoriaVerificación de vida — selfie obligatoria que ancla el proceso.**Clasificación de Riesgo**ObligatoriaCruza señales de comportamiento para marcar el riesgo de fraude asociado al CPF.**Verificación de Identidad**Opcional (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.**[Verificación RENAPO](/es/capabilities/renapo-verification)**Opcional (si contratada)Consulta RENAPO, el registro nacional de población de México, con la CURP del usuario y devuelve el registro junto con el resultado de Verificación de Identidad.
### 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-key`SíAPI key aprovisionada por su Project Manager de Onboarding en Unico.`Content-Type`Sí`application/json`
**Cuerpo (application/json):**
CampoTipoObligatorioDescripción`external_id`stringNoUn identificador externo para la solicitud, utilizado para seguimiento y referencia.`metadata`objectNoContenedor para los parámetros de configuración.`metadata.phone`stringNoNúmero de teléfono del usuario en formato internacional (p. ej., `521234567890`).`metadata.redirect_url`stringNoURL a la que redirigir al usuario una vez completado el proceso KYC.`metadata.webhook_url`stringNoURL 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_url`stringNoURL 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.
`data.step` (enviado a `track_webhook_url`) reporta los mismos pasos rastreados por Webhook V2 — consulte la [tabla de pasos compatibles](#webhook-v2) a continuación.
**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_id`string (nullable)Un identificador externo para la solicitud, utilizado para seguimiento y referencia.`data.created_on`string (date-time)La fecha en que se creó el magic link.`data.is_active`booleanSi es `true`, el magic link está activo.`data.token`stringEl token del magic link que se usará para vincular los procesos KYC al magic link.`data.magic_link_url`string (URI)La URL del magic link para iniciar el proceso KYC.`data.metadata.redirect_url`string (nullable)URL a la que redirigir al usuario una vez completado el proceso KYC.`data.metadata.webhook_url`string (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_url`string (nullable)URL a la que enviar cada paso KYC procesado por el usuario. Este webhook se invocará del lado del cliente.`data.version`stringLa versión del magic link.`version`stringLa versión de la API que procesó la solicitud, útil para rastrear cambios y compatibilidad.`status`stringRepresentación textual del estado de la respuesta, indicando éxito o fallo de la operación.`status_code`integerEl código de estado HTTP de la respuesta, proporcionando un indicador estandarizado del resultado de la solicitud.`request_date`string (date-time)La fecha y hora en que se realizó la solicitud, en formato ISO 8601.`request.metadata.redirect_url`string (nullable)URL a la que redirigir al usuario una vez completado el proceso KYC (eco de la solicitud).`request.metadata.webhook_url`string (nullable)URL a la que enviar los datos del proceso KYC una vez completado (eco de la solicitud).`request.metadata.track_webhook_url`string (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 Request``data provided in the field is invalid`Estructura de datos o valores de campo inválidos en el payload de la solicitud. Verifique los campos obligatorios y sus formatos.`403 Forbidden``Forbidden`API key ausente, expirada o sin permiso. Verifique el encabezado `x-api-key`.`500 Internal Server Error``internal server error`Fallo 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.
Si prefiere incrustar el journey dentro de su propia app en lugar de abrir el enlace en el navegador, puede hacerlo mediante WebView o CustomTab. PoCs de referencia:

**Android/Kotlin:** [TrullyAi-AndroidMagicLink](https://github.com/unico-labs/TrullyAi-AndroidMagicLink)
**React Native:** [TrullyAI-ReactNativeMagicLink](https://github.com/unico-labs/TrullyAI-ReactNativeMagicLink)

### 4. Recibir el resultado​

Tiene total flexibilidad para decidir cómo recibir el resultado final del proceso KYC — elija la estrategia que mejor se adapte a la arquitectura de su sistema. Puede consultar activamente el resultado (GET) o recibirlo de forma pasiva mediante notificaciones (Webhook).
**Opción A — Polling activo mediante GET**
Obtenga el resultado llamando a `GET /v2/history/request?magic_link_token={token}` (consulte [Polling mediante GET](#polling-via-get) a continuación). La decisión final se completa en `data.response.unico.result`.
Buenas prácticas para GETEn lugar de hacer polling periódicamente desde el momento en que se crea el enlace, use los webhooks de seguimiento (consulte [Webhook V2](#webhook-v2) a continuación) para saber exactamente cuándo consultar. Una vez que reciba el paso `form_decision_maker`, ese es el momento exacto y seguro para disparar esta llamada GET.
**Opción B — Recepción automática mediante Webhook**
Haga que su sistema sea notificado automáticamente en cuanto el resultado final esté listo (consulte [Webhook V2](#webhook-v2) a continuación). Hay dos versiones disponibles:

**Webhook V1** — recibe el resultado en la URL enviada en `metadata.webhook_url` al crear el token.
**Webhook V2** — configurado previamente con su PM de Onboarding. Recibe el veredicto final escuchando el evento `MAGIC_LINK_RESULTS`.

Resiliencia — fallbackSi Webhook (Opción B) es su método principal, implemente también la consulta GET (Opción A) como fallback. Esto le permite recuperar el resultado mediante rutinas de reconciliación en caso de fallas de red, caídas temporales del servidor, o un webhook que no logre procesarse correctamente.

### Polling mediante GET​

**Endpoint:** `GET https://sandbox.trully.ai/v2/history/request`
**Parámetros de consulta:**
ParámetroTipoObligatorioDescripción`magic_link_token`stringSíToken devuelto al crear el Magic Link.
**Encabezados:**
EncabezadoObligatorioDescripción`x-api-key`SíAPI 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`status`stringRepresentación textual del estado de la respuesta.`status_code`integerCódigo de estado HTTP.`request_date`string (date-time)La fecha y hora en que se realizó la solicitud.`version`stringVersión de la API que procesó la solicitud.`data.user_id`stringEl ID de usuario establecido en la solicitud original.
**`data.images`** — Imágenes capturadas en Base64:
CampoTipoDescripción`data.images.document_image`stringImagen en Base64 del frente del documento.`data.images.document_image_back`stringImagen en Base64 del reverso del documento.`data.images.selfie`stringImagen de selfie en Base64 capturada durante la verificación.
**`data.response.unico`** — Veredicto consolidado:
CampoTipoDescripción`data.response.unico.process_id`string (UUID)Identificador interno relacionado con el proceso de verificación.`data.response.unico.result`stringResultado 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_ERROR`**Rechazar**El proceso finalizó con error.Sistema`PROCESS_RESULT_VERIFIED`**Aceptar**El 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_LIVE`**Revisar / Aceptar**El 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_RISK`**Recomienda rechazo**Encontramos al menos una evidencia sólida de fraude. La decisión final es suya.Comportamiento de fraude: 1 señal fuerte`PROCESS_RESULT_CRITICAL_RISK`**Recomienda rechazo**Encontramos al menos 2 evidencias sólidas de fraude. La decisión final es suya.Comportamiento de fraude: 2+ señales fuertes`PROCESS_RESULT_NOT_APPROVED`**Rechazar**Se recomienda el rechazo ya que se detectaron múltiples indicios de fraude.Identidad: rechazada · Comportamiento de fraude: múltiples señales`PROCESS_RESULT_NOT_LIVE`**Permitir hasta 2 reintentos**El 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_match`booleanEstado de coincidencia facial entre documento y selfie.`document.front.face_analysis.match_fraud_flag`booleanSi el rostro del documento ha sido asociado con actividad fraudulenta.`selfie.match_fraud_flag`booleanSi el rostro de la selfie ha sido asociado con actividad fraudulenta.`warnings.external_id`stringAdvertencia 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_match`booleanSi el rostro de la selfie coincide con el rostro del documento.`data.response.label`string (nullable)Reservado para resultados de sub-procesos específicos; `null` si no aplica.`data.response.reason`string (nullable)Razones para la etiqueta asignada.`data.response.request_id`stringIdentificador único para la solicitud de API.
**`data.response.curp`** — Validación del CURP contra RENAPO:
CampoTipoDescripción`curp`stringLa cadena CURP que se está analizando.`government_valid`booleanSi el CURP es válido según RENAPO.`government_name`stringNombre completo asociado al CURP en la base de datos oficial.`name_to_CURP_valid`booleanSi el nombre proporcionado es consistente con el CURP.`is_mexican`booleanSi el CURP corresponde a un ciudadano mexicano.`deceased`booleanSi el CURP está marcado como fallecido en la base de datos oficial.`date_of_birth`stringFecha de nacimiento decodificada del CURP (DD/MM/AAAA).`age`integerEdad calculada del usuario.`gender`stringGénero decodificado del CURP (`M` o `F`).`state_of_birth`stringEstado de nacimiento decodificado del CURP.`state_iso`stringCódigo ISO 3166-2 del estado de nacimiento.
**`data.response.document.details`** — Detección y análisis forense del documento:
CampoTipoDescripción`detected`booleanSi se detectó un documento exitosamente en la imagen.`document_id`integerIdentificador único del documento procesado.`forensics.is_valid`stringResultado 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`name`Nombre(s).`last_name`Apellido paterno.`mother_last_name`Apellido materno.`complete_name`Nombre completo.`birthdate`Fecha de nacimiento (DD/MM/AAAA).`sex`Sexo/género (`H` o `M`).`curp`CURP extraído del documento.`electoral_key`Clave de elector.`address`Domicilio.`registration_year`Año de registro del documento.`valid_thru`Año de vencimiento del documento.
**`data.response.document.front.face_analysis`** — Análisis del rostro encontrado en el INE:
CampoTipoDescripción`face_id`integerIdentificador único de esta instancia de rostro.`face_id_v2`integerIdentificador único (versión 2).`unique_face_id_v2`integerIdentificador persistente para este rostro físico en todas las consultas.`first_seen`stringMarca de tiempo de la primera vez que se vio este rostro en el sistema.`last_seen`stringMarca de tiempo de la última vez que se vio este rostro en la red.`last_seen_by_your_company`stringLa vez más reciente que este rostro fue visto en una consulta de su empresa.`inquiry_date`stringMarca de tiempo de la consulta de verificación actual.`match`booleanSi este rostro es una posible coincidencia con otros rostros en la base de datos.`match_fraud_flag`booleanSi este rostro ha sido asociado con actividad fraudulenta.`seen_by_your_company`booleanSi este rostro fue visto anteriormente por su empresa.`seen_different_companies`integerNúmero de otras empresas en la red que han visto este rostro.`times_seen_by_your_company`integerTotal de veces que este rostro fue visto en consultas de su empresa.`times_seen_last_month`integerNúmero de veces visto el último mes en toda la red.`warnings.external_id`stringAdvertencia si el rostro del usuario está asociado con múltiples IDs externos.
**`data.response.document.back`** — Datos MRZ del reverso del INE:
CampoTipoDescripción`mrz`stringCadena completa de la Zona de Lectura Mecánica (MRZ).`cic`stringNúmero CIC extraído del MRZ.`citizen_id`stringNúmero de identificación ciudadana del MRZ.
**`data.response.selfie`** — Análisis de la selfie capturada:
CampoTipoDescripción`face_id`integerIdentificador único de la instancia del rostro en la selfie.`face_id_v2`integerIdentificador único (versión 2).`unique_face_id_v2`integerIdentificador persistente para este rostro físico en todas las consultas.`first_seen`stringPrimera vez que el rostro de esta selfie fue visto en el sistema.`first_seen_image`booleanSi es la primera vez que se ve esta imagen exacta.`last_seen`stringLa vez más reciente que este rostro fue visto en la red.`last_seen_by_your_company`stringLa vez más reciente que este rostro fue visto por su empresa.`inquiry_date`stringMarca de tiempo de la consulta de verificación actual.`match`booleanSi el rostro de la selfie coincide con otros rostros en la base de datos.`match_fraud_flag`booleanSi el rostro de la selfie está asociado con actividad fraudulenta.`seen_by_your_company`booleanSi este rostro fue visto anteriormente por su empresa.`seen_different_companies`integerNúmero de otras empresas en la red que han visto este rostro.`times_seen_by_your_company`integerTotal de veces que este rostro fue visto en consultas de su empresa.`times_seen_last_month`integerNúmero de veces visto el último mes en toda la red.`warnings`objectAdvertencias 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 Request``Input 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 Found``This magic link have no requests associated`El 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 Error``internal server error`Fallo 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 V2​

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.step`stringNombre del paso completado.`data.user_id`string (nullable)ID externo establecido en el magic link.`data.started_on`datetimeHora de inicio del paso en zona horaria UTC.`data.completed_on`datetimeHora de finalización del paso en zona horaria UTC.`event`stringIdentificador del tipo de evento.`magic_link_token`uuidToken único del magic link.`user_id`string (nullable)Identificador externo.`date`datetimeMarca de tiempo del evento.
**Pasos compatibles:**
PasoDescripción`form_start`El usuario hizo clic en el botón inicial del magic link.`form_document_front`El usuario completó la captura del frente del INE.`form_document_back`El usuario completó la captura del reverso del INE.`form_document`El usuario completó los procesos del frente y el reverso.`form_selfie`El usuario completó el proceso de liveness.`form_decision_maker`El 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_type`stringCara del documento: `ine_front` o `ine_back`.`data.invalid_document`boolean`true` si la imagen capturada no es un INE válido (cualquier cara).`data.invalid_curp`boolean`true` si el CURP no pudo ser leído (solo `ine_front`).`data.invalid_back_ocr`boolean`true` si el código MRZ no pudo ser leído (solo `ine_back`).`event`stringIdentificador del tipo de evento.`magic_link_token`uuidToken único del magic link.`user_id`string (nullable)Identificador externo.`date`datetimeMarca 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 / V2Si 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)Última actualización el 8 oct 2026**