---
title: KYC Magic Link
description: Exécute le processus d'identification au Mexique, en collectant les documents d'identité nationaux (INE) et les données biométriques faciales via un parcours hébergé distribué par un lien unique.
canonical: https://developer.unico.io/fr/dual-api/products/sign-up/kyc-magic-link/index
locale: fr
generated_by: markdown-export
---

- [/fr/](/fr/)
- [Construire](/fr/dual-api/products/)
- Guide régional
- KYC Magic Link

**Sur cette page# KYC Magic Link

Contrat régional séparéCe cas d'usage **n'utilise pas** l'endpoint Unico `POST /v1/process` ni le contrat API. L'intégration se fait avec **Trully.ai** (host `api.trully.ai`), avec **authentification via `x-api-key`** au lieu de Bearer JWT, et un **schéma de réponse propriétaire**. Pour les autres pays, utilisez Onboarding (Global).
### Ce que ce cas d'usage résout​

KYC Magic Link répond au défi d'exécuter le processus d'identification au Mexique, en collectant les documents d'identité nationaux (INE) et les données biométriques faciales. Avec un parcours hébergé par Unico, vous éliminez la friction de développement front-end grâce à un lien envoyé via vos propres canaux (WhatsApp, SMS, e-mail).
**Utilisez ce cas d'usage lorsque :**

Vous opérez au **Mexique** et le document d'identité utilisé est l'**INE (obligatoire)**.

**N'utilisez pas ce cas d'usage lorsque :**

L'utilisateur est en dehors du Mexique ou utilise d'autres documents → consultez les autres cas d'usage d'onboarding.

### Capacités impliquées​

Pipeline exécuté au sein d'un seul processus :
[Capture de document (INE)](/fr/capabilities/document-reuse-and-capture)[Liveness](/fr/capabilities/liveness)[Classification des risques](/fr/capabilities/fraud-risk-classification)[Vérification d'identité](/fr/capabilities/identity-verification)
CapacitéObligatoireRôle dans le flux**Capture de document**ObligatoireCapture l'image du document INE. La réutilisation de document **n'est pas disponible** dans ce cas d'usage — chaque session nécessite une nouvelle capture.**Liveness**ObligatoireVérification de vivacité — selfie obligatoire qui ancre le processus.**Classification des risques**ObligatoireCroise les signaux comportementaux pour signaler le risque de fraude associé au CPF.**Vérification d'identité**Optionnel (si contracté)Vérifie si le visage de la transaction appartient au titulaire de l'identifiant gouvernemental fourni, en utilisant la base d'identité d'Unico et des signaux supplémentaires.**[RENAPO Verification](/fr/capabilities/renapo-verification)**Optionnel (si contracté)Interroge le RENAPO, le registre national de la population du Mexique, avec la CURP de l'utilisateur et retourne l'enregistrement du registre en plus du résultat de la Vérification d'identité.
### Prérequis​

**Clé API** — provisionnée par votre Chef de projet Onboarding chez Unico. Envoyée dans l'en-tête `x-api-key`.
**Endpoint HTTPS public** pour recevoir les webhooks (optionnel, mais recommandé).
**Configuration CORS** — autoriser les origines `https://verification.unico.app` (production) et `https://verification.uat.unico.app` (sandbox) sur le serveur qui reçoit le webhook.

### Implémentation étape par étape​

Contrairement aux autres cas d'usage, Magic Link **ne possède pas de champ `flow`** — l'intégration se fait directement avec l'API Trully. L'endpoint crée un lien de vérification unique que vous distribuez à l'utilisateur via votre propre canal.
### 1. Créer le Magic Link​

**Endpoint :** `POST https://sandbox.trully.ai/v2/magic-link`
**En-têtes :**
En-têteObligatoireDescription`x-api-key`OuiClé API provisionnée par votre Chef de projet Onboarding chez Unico.`Content-Type`Oui`application/json`
**Corps (application/json) :**
ChampTypeObligatoireDescription`external_id`stringNonIdentifiant externe pour la requête, utilisé à des fins de suivi et de référence.`metadata`objectNonConteneur pour les paramètres de configuration.`metadata.phone`stringNonNuméro de téléphone de l'utilisateur au format international (ex. : `521234567890`).`metadata.redirect_url`stringNonURL de redirection de l'utilisateur une fois le processus KYC terminé.`metadata.webhook_url`stringNonURL pour envoyer les données du processus KYC une fois terminé. Ce webhook sera appelé côté client. Pour des raisons de sécurité, l'endpoint doit utiliser HTTPS. Le composant attendra une minute que votre serveur webhook réponde — après quoi, il abandonnera la communication. Le processus ne sera en aucun cas affecté par la communication webhook. Assurez-vous d'autoriser `https://verification.unico.app` et `https://verification.uat.unico.app` dans votre configuration CORS pour la production et le sandbox respectivement.`metadata.track_webhook_url`stringNonURL pour envoyer chaque étape KYC traitée par l'utilisateur (voir les événements webhook ci-dessous). Ce webhook sera appelé côté client. Pour des raisons de sécurité, l'endpoint doit utiliser HTTPS. Le composant attendra une minute que votre serveur webhook réponde — après quoi, il abandonnera la communication. Le processus ne sera en aucun cas affecté par la communication webhook. Assurez-vous d'autoriser `https://verification.unico.app` et `https://verification.uat.unico.app` dans votre configuration CORS pour la production et le sandbox respectivement.
`data.step` (envoyée à `track_webhook_url`) rapporte les mêmes étapes que celles suivies par le Webhook V2 — voir le [tableau des étapes prises en charge](#webhook-v2) ci-dessous.
**Exemple de requête :**
```
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. Recevoir le token et l'URL du lien​

**Champs de la réponse :**
ChampTypeDescription`data.external_id`string (nullable)Identifiant externe pour la requête, utilisé à des fins de suivi et de référence.`data.created_on`string (date-time)Date de création du magic link.`data.is_active`booleanSi `true`, le magic link est actif.`data.token`stringToken du magic link qui sera utilisé pour associer les processus KYC au magic link.`data.magic_link_url`string (URI)L'URL du magic link pour démarrer le processus KYC.`data.metadata.redirect_url`string (nullable)URL de redirection de l'utilisateur une fois le processus KYC terminé.`data.metadata.webhook_url`string (nullable)URL pour envoyer les données du processus KYC une fois terminé. Ce webhook sera appelé côté client.`data.metadata.track_webhook_url`string (nullable)URL pour envoyer chaque étape KYC traitée par l'utilisateur. Ce webhook sera appelé côté client.`data.version`stringVersion du magic link.`version`stringVersion de l'API qui a traité la requête, utile pour le suivi des modifications et la compatibilité.`status`stringReprésentation textuelle du statut de la réponse, indiquant le succès ou l'échec de l'opération.`status_code`integerCode de statut HTTP de la réponse, fournissant un indicateur standardisé du résultat de la requête.`request_date`string (date-time)Date et heure de la requête, au format ISO 8601.`request.metadata.redirect_url`string (nullable)URL de redirection de l'utilisateur une fois le processus KYC terminé (écho de la requête).`request.metadata.webhook_url`string (nullable)URL pour envoyer les données du processus KYC après complétion (écho de la requête).`request.metadata.track_webhook_url`string (nullable)URL pour envoyer chaque étape KYC traitée par l'utilisateur (écho de la requête).
**Exemple de réponse :**
```
{  "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    }  }}
```

**Réponses d'erreur — POST /v2/magic-link**CodeMessageDescription`400 Bad Request``data provided in the field is invalid`Structure de données ou valeurs de champ invalides dans la charge utile de la requête. Vérifiez les champs obligatoires et les formats.`403 Forbidden``Forbidden`Clé API manquante, expirée ou sans permission. Vérifiez l'en-tête `x-api-key`.`500 Internal Server Error``internal server error`Échec de traitement côté serveur. Réessayez avec un backoff exponentiel. Si le problème persiste, contactez le support.**Exemple de réponse 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. Distribuer magic_link_url à l'utilisateur​

Envoyez via WhatsApp, SMS, e-mail ou intégrez dans votre interface. L'utilisateur accède au lien depuis son propre appareil et complète le parcours hébergé.
Si vous préférez intégrer le parcours directement dans votre propre application plutôt que d'ouvrir le lien dans le navigateur, vous pouvez le faire via WebView ou CustomTab. PoCs de référence :

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

### 4. Recevoir le résultat​

Vous avez toute la flexibilité pour décider comment recevoir le résultat final du processus KYC — choisissez la stratégie la mieux adaptée à l'architecture de votre système. Vous pouvez interroger activement le résultat (GET) ou le recevoir passivement via des notifications (Webhook).
**Option A — Polling actif via GET**
Récupérez le résultat en appelant `GET /v2/history/request?magic_link_token={token}` (voir [Polling via GET](#polling-via-get) ci-dessous). La décision finale est renseignée dans `data.response.unico.result`.
Bonne pratique pour le GETPlutôt que d'interroger périodiquement dès la création du lien, utilisez les webhooks de suivi (voir [Webhook V2](#webhook-v2) ci-dessous) pour savoir exactement quand interroger. Dès que vous recevez l'étape `form_decision_maker`, c'est le moment précis et sûr pour déclencher cet appel GET.
**Option B — Réception automatique via Webhook**
Faites en sorte que votre système soit notifié automatiquement dès que le résultat final est prêt (voir [Webhook V2](#webhook-v2) ci-dessous). Deux versions sont disponibles :

**Webhook V1** — vous recevez le résultat à l'URL envoyée dans `metadata.webhook_url` lors de la création du token.
**Webhook V2** — configuré au préalable avec votre Chef de projet Onboarding. Vous recevez le verdict final en écoutant l'événement `MAGIC_LINK_RESULTS`.

Résilience — solution de repliSi le Webhook (Option B) est votre méthode principale, mettez également en œuvre la requête GET (Option A) comme solution de repli. Cela vous permet de récupérer le résultat via des routines de réconciliation en cas de défaillances réseau, d'indisponibilités temporaires du serveur, ou d'un webhook qui ne parvient pas à traiter correctement.

### Polling via GET​

**Endpoint :** `GET https://sandbox.trully.ai/v2/history/request`
**Paramètres de requête :**
ParamètreTypeObligatoireDescription`magic_link_token`stringOuiToken retourné lors de la création du Magic Link.
**En-têtes :**
En-têteObligatoireDescription`x-api-key`OuiClé API provisionnée par votre Chef de projet Onboarding chez Unico.
**Exemple de requête :**
```
curl "https://sandbox.trully.ai/v2/history/request?magic_link_token=$TOKEN" \  -H "x-api-key: $TRULLY_API_KEY"
```

**Exemple de réponse :**
```
{  "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"}
```

**Champs de la réponse :**
**Niveau racine :**
ChampTypeDescription`status`stringReprésentation textuelle du statut de la réponse.`status_code`integerCode de statut HTTP.`request_date`string (date-time)Date et heure de la requête.`version`stringVersion de l'API qui a traité la requête.`data.user_id`stringID utilisateur défini dans la requête originale.
**`data.images`** — Images capturées encodées en Base64 :
ChampTypeDescription`data.images.document_image`stringImage encodée en Base64 du recto du document.`data.images.document_image_back`stringImage encodée en Base64 du verso du document.`data.images.selfie`stringImage de selfie encodée en Base64 capturée lors de la vérification.
**`data.response.unico`** — Verdict consolidé :
ChampTypeDescription`data.response.unico.process_id`string (UUID)Identifiant interne lié au processus de vérification.`data.response.unico.result`stringRésultat du processus. Valeurs possibles décrites ci-dessous.
**Valeurs possibles pour `data.response.unico.result` :**
La valeur de résultat encode l'une des trois dimensions d'évaluation :

**Évaluation de l'identité** — si le visage capturé appartient au titulaire du document (`PROCESS_RESULT_VERIFIED`, `PROCESS_RESULT_NOT_APPROVED`).
**Comportement frauduleux** — si des signaux comportementaux ou réseau indiquent un risque de fraude (`PROCESS_RESULT_LIVE`, `PROCESS_RESULT_HIGH_RISK`, `PROCESS_RESULT_CRITICAL_RISK`, `PROCESS_RESULT_NOT_APPROVED`).
**Liveness** — si un visage vivant a été détecté au moment de la capture (`PROCESS_RESULT_NOT_LIVE`).

RésultatRecommandationSignificationSignal`PROCESS_RESULT_ERROR`**Rejeter**Le processus s'est terminé avec une erreur.Système`PROCESS_RESULT_VERIFIED`**Accepter**L'utilisateur était actif au moment de la capture ; c'est le visage du titulaire de la pièce d'identité et aucune preuve de fraude n'a été trouvée.Identité : confirmée`PROCESS_RESULT_LIVE`**Réviser / Accepter**L'utilisateur était actif au moment de la capture ; nous n'avons pas trouvé de preuves suffisantes pour garantir qu'il est le titulaire de la pièce d'identité et aucune preuve de fraude.Identité : non concluante · Fraude : aucune`PROCESS_RESULT_HIGH_RISK`**Recommander le rejet**Nous avons trouvé au moins une preuve solide de fraude. La décision finale vous appartient.Comportement frauduleux : 1 signal fort`PROCESS_RESULT_CRITICAL_RISK`**Recommander le rejet**Nous avons trouvé au moins 2 preuves solides de fraude. La décision finale vous appartient.Comportement frauduleux : 2+ signaux forts`PROCESS_RESULT_NOT_APPROVED`**Rejeter**Rejet recommandé car de multiples indications de fraude ont été détectées.Identité : rejetée · Comportement frauduleux : signaux multiples`PROCESS_RESULT_NOT_LIVE`**Autoriser jusqu'à 2 tentatives**L'utilisateur n'était pas en vie au moment de la capture, bien qu'aucune autre indication de fraude n'ait été trouvée.Liveness : visage non vivant
remarque`PROCESS_RESULT_VERIFIED` **nécessite une activation**. Par défaut, ce résultat n'est **pas actif** — consultez votre Chef de projet Unico si vous souhaitez l'activer.
**Signaux auxiliaires pour votre décision :**
Pour les cas `LIVE`, `HIGH_RISK` ou `CRITICAL_RISK`, complétez votre décision avec ces champs :
ChampTypeSignification`face_match`booleanStatut de correspondance faciale entre le document et le selfie.`document.front.face_analysis.match_fraud_flag`booleanSi le visage du document a été associé à une activité frauduleuse.`selfie.match_fraud_flag`booleanSi le visage du selfie a été associé à une activité frauduleuse.`warnings.external_id`stringAvertissement indiquant que le visage de l'utilisateur est associé à plusieurs identifiants externes.
**`data.response`** — Signaux de résultat de niveau supérieur :
ChampTypeDescription`data.response.face_match`booleanSi le visage du selfie correspond au visage du document.`data.response.label`string (nullable)Réservé aux résultats de sous-processus spécifiques ; `null` si non applicable.`data.response.reason`string (nullable)Raisons du label attribué.`data.response.request_id`stringIdentifiant unique de la requête API.
**`data.response.curp`** — Validation CURP contre RENAPO :
ChampTypeDescription`curp`stringLa chaîne CURP analysée.`government_valid`booleanSi le CURP est valide selon RENAPO.`government_name`stringNom complet associé au CURP dans la base de données officielle.`name_to_CURP_valid`booleanSi le nom fourni est cohérent avec le CURP.`is_mexican`booleanSi le CURP correspond à un citoyen mexicain.`deceased`booleanSi le CURP est marqué comme décédé dans la base de données officielle.`date_of_birth`stringDate de naissance décodée depuis le CURP (JJ/MM/AAAA).`age`integerÂge calculé de l'utilisateur.`gender`stringGenre décodé depuis le CURP (`M` ou `F`).`state_of_birth`stringÉtat de naissance décodé depuis le CURP.`state_iso`stringCode ISO 3166-2 de l'état de naissance.
**`data.response.document.details`** — Détection de document et analyse forensique :
ChampTypeDescription`detected`booleanSi un document a été détecté avec succès dans l'image.`document_id`integerIdentifiant unique du document traité.`forensics.is_valid`stringRésultat de l'analyse forensique : `yes`, `no` ou `inconclusive`.
**`data.response.document.front.information`** — Champs extraits par OCR du recto de l'INE. Chaque champ contient `text` (valeur extraite) et `valid` (si une validation structurelle a pu être effectuée) :
ChampDescription`name`Prénom(s).`last_name`Nom de famille paternel.`mother_last_name`Nom de famille maternel.`complete_name`Nom complet.`birthdate`Date de naissance (JJ/MM/AAAA).`sex`Sexe/genre (`H` ou `M`).`curp`CURP extrait du document.`electoral_key`Clé électorale.`address`Adresse.`registration_year`Année d'enregistrement du document.`valid_thru`Année d'expiration du document.
**`data.response.document.front.face_analysis`** — Analyse du visage trouvé sur l'INE :
ChampTypeDescription`face_id`integerIdentifiant unique pour cette instance de visage.`face_id_v2`integerIdentifiant unique (version 2).`unique_face_id_v2`integerIdentifiant persistant pour ce visage physique dans toutes les demandes.`first_seen`stringHorodatage de la première fois que ce visage a été vu dans le système.`last_seen`stringHorodatage de la dernière fois que ce visage a été vu dans le réseau.`last_seen_by_your_company`stringDernière fois que ce visage a été vu dans une demande de votre entreprise.`inquiry_date`stringHorodatage de la demande de vérification actuelle.`match`booleanSi ce visage est une correspondance potentielle avec d'autres visages dans la base de données.`match_fraud_flag`booleanSi ce visage a été associé à une activité frauduleuse.`seen_by_your_company`booleanSi ce visage a déjà été vu par votre entreprise.`seen_different_companies`integerNombre d'autres entreprises dans le réseau ayant vu ce visage.`times_seen_by_your_company`integerNombre total de fois où ce visage a été vu dans les demandes de votre entreprise.`times_seen_last_month`integerNombre de fois vu le mois dernier dans le réseau.`warnings.external_id`stringAvertissement si le visage de l'utilisateur est associé à plusieurs identifiants externes.
**`data.response.document.back`** — Données MRZ du verso de l'INE :
ChampTypeDescription`mrz`stringChaîne complète de la Zone de Lecture Automatique (MRZ).`cic`stringNuméro CIC extrait du MRZ.`citizen_id`stringNuméro d'identification du citoyen extrait du MRZ.
**`data.response.selfie`** — Analyse du selfie capturé :
ChampTypeDescription`face_id`integerIdentifiant unique pour l'instance du visage du selfie.`face_id_v2`integerIdentifiant unique (version 2).`unique_face_id_v2`integerIdentifiant persistant pour ce visage physique dans toutes les demandes.`first_seen`stringPremière fois que le visage de ce selfie a été vu dans le système.`first_seen_image`booleanSi c'est la première fois que cette image exacte est vue.`last_seen`stringDernière fois que ce visage a été vu dans le réseau.`last_seen_by_your_company`stringDernière fois que ce visage a été vu par votre entreprise.`inquiry_date`stringHorodatage de la demande de vérification actuelle.`match`booleanSi le visage du selfie correspond à d'autres visages dans la base de données.`match_fraud_flag`booleanSi le visage du selfie est associé à une activité frauduleuse.`seen_by_your_company`booleanSi ce visage a déjà été vu par votre entreprise.`seen_different_companies`integerNombre d'autres entreprises dans le réseau ayant vu ce visage.`times_seen_by_your_company`integerNombre total de fois où ce visage a été vu dans les demandes de votre entreprise.`times_seen_last_month`integerNombre de fois vu le mois dernier dans le réseau.`warnings`objectAvertissements spécifiques liés à l'analyse du selfie (même structure que document face_analysis).
Utilisez le polling avec un **backoff exponentiel** — n'appelez pas en boucle serrée.
**Réponses d'erreur — GET /v2/history/request**CodeMessageDescription`400 Bad Request``Input should be a valid UUID, invalid group length...`Le paramètre `magic_link_token` est mal formé ou n'est pas un format UUID valide.`404 Not Found``This magic link have no requests associated`Le token fourni existe mais n'a aucun processus KYC complété associé. L'utilisateur n'a peut-être pas encore terminé le parcours.`500 Internal Server Error``internal server error`Échec de traitement côté serveur. Réessayez avec un backoff exponentiel. Si le problème persiste, contactez le support.**Exemple de réponse 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"}
```

**Exemple de réponse 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"}
```

**Exemple de réponse 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​

Trois événements webhook sont disponibles. Pour les activer, demandez la configuration à votre Chef de projet Onboarding en fournissant : **URL** de l'endpoint (HTTPS obligatoire), **type d'authentification** (`basic_auth`, `api_key`, `oauth2` ou `NoAuth`), **configuration d'authentification**, **nombre maximum de tentatives**, **intervalle de tentative (s)** et **délai d'attente (s)**.
MAGIC_LINK_RESULTS
Cet événement est envoyé à la fin du flux, lorsque le Decision Maker a terminé le traitement des informations envoyées.
```
{  "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
Ces événements sont reçus lorsque l'utilisateur a complété une action. Par exemple, `form_start` sera reçu lorsque l'utilisateur capture le recto du document, ce qui signifie qu'il a cliqué et complété le premier écran.
```
{  "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"}
```

ChampTypeDescription`data.step`stringNom de l'étape complétée.`data.user_id`string (nullable)Identifiant externe défini dans le magic link.`data.started_on`datetimeHeure de début de l'étape (fuseau UTC).`data.completed_on`datetimeHeure de fin de l'étape (fuseau UTC).`event`stringIdentifiant du type d'événement.`magic_link_token`uuidToken unique du magic link.`user_id`string (nullable)Identifiant externe.`date`datetimeHorodatage de l'événement.
**Étapes supportées :**
ÉtapeDescription`form_start`L'utilisateur a cliqué sur le bouton initial du magic link.`form_document_front`L'utilisateur a complété la capture du recto de l'INE.`form_document_back`L'utilisateur a complété la capture du verso de l'INE.`form_document`L'utilisateur a complété les processus recto et verso.`form_selfie`L'utilisateur a complété le processus de liveness.`form_decision_maker`L'utilisateur a complété l'intégralité du flux.
MAGIC_LINK_DOCUMENT_RETAKE_REASONS
Cet événement est envoyé lorsqu'une nouvelle capture de document est requise, soit lors du processus recto, soit lors du processus verso. Il indique que des données critiques de l'INE n'ont pas pu être lues.
```
{  "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"}
```

ChampTypeDescription`data.document_type`stringCôté du document : `ine_front` ou `ine_back`.`data.invalid_document`boolean`true` si l'image capturée n'est pas un INE valide (recto ou verso).`data.invalid_curp`boolean`true` si le CURP n'a pas pu être lu (`ine_front` uniquement).`data.invalid_back_ocr`boolean`true` si le code MRZ n'a pas pu être lu (`ine_back` uniquement).`event`stringIdentifiant du type d'événement.`magic_link_token`uuidToken unique du magic link.`user_id`string (nullable)Identifiant externe.`date`datetimeHorodatage de l'événement.
La charge utile est conçue de sorte qu'une **seule** erreur (`true`) soit reçue pour chaque côté du document.
**Scénarios d'échec — recto INE :**

Document invalide → uniquement `invalid_document: true`
Échec de lecture du CURP → uniquement `invalid_curp: true`

**Scénarios d'échec — verso INE :**

Document invalide → uniquement `invalid_document: true`
Échec de lecture du MRZ → uniquement `invalid_back_ocr: true`

Compatibilité V1 / V2Si vous envoyez encore `webhook_url` dans les `metadata` de la requête (Webhook V1), cette configuration **prend la priorité** sur la V2 globale. Pour migrer, supprimez `webhook_url` des `metadata` et configurez la V2 avec votre Chef de projet Onboarding.

### Personnalisations​

La page Magic Link hébergée **ne prend pas en charge la personnalisation visuelle** par le client — elle suit l'identité visuelle Unico/Trully par défaut. Pour personnaliser le parcours (logo, couleurs, textes), utilisez Onboarding (Global) avec SDK ou Web.
**Disponibilité :** Mexique · **Endpoint :** `POST https://api.trully.ai/v2/magic-link` · **Document :** INE · **Auth :** `x-api-key` (Trully)Dernière mise à jour le 8 oct. 2026**