Aller au contenu principal

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/TCA. 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 :

CapacitéObligatoireRôle dans le flux
Capture de documentObligatoireCapture 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.
LivenessObligatoireVérification de vivacité — selfie obligatoire qui ancre le processus.
Classification des risquesObligatoireCroise 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.

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-keyOuiClé API provisionnée par votre Chef de projet Onboarding chez Unico.
Content-TypeOuiapplication/json

Corps (application/json) :

ChampTypeObligatoireDescription
external_idstringNonIdentifiant externe pour la requête, utilisé à des fins de suivi et de référence.
metadataobjectNonConteneur pour les paramètres de configuration.
metadata.phonestringNonNuméro de téléphone de l'utilisateur au format international (ex. : 521234567890).
metadata.redirect_urlstringNonURL de redirection de l'utilisateur une fois le processus KYC terminé.
metadata.webhook_urlstringNonURL 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_urlstringNonURL 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.

Valeurs possibles pour data.step (envoyées à track_webhook_url) :

ÉtapeDescription
form_startL'utilisateur est en train de scanner le document.
form_document_frontL'utilisateur a déjà capturé le recto de l'INE.
form_document_backL'utilisateur a déjà capturé le verso de l'INE.
form_documentLe processus est actuellement à l'étape du selfie.
form_selfieL'utilisateur a atteint l'étape finale de l'opération.
form_decision_makerL'opération retourne la réponse du système.

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_idstring (nullable)Identifiant externe pour la requête, utilisé à des fins de suivi et de référence.
data.created_onstring (date-time)Date de création du magic link.
data.is_activebooleanSi true, le magic link est actif.
data.tokenstringToken du magic link qui sera utilisé pour associer les processus KYC au magic link.
data.magic_link_urlstring (URI)L'URL du magic link pour démarrer le processus KYC.
data.metadata.redirect_urlstring (nullable)URL de redirection de l'utilisateur une fois le processus KYC terminé.
data.metadata.webhook_urlstring (nullable)URL pour envoyer les données du processus KYC une fois terminé. Ce webhook sera appelé côté client.
data.metadata.track_webhook_urlstring (nullable)URL pour envoyer chaque étape KYC traitée par l'utilisateur. Ce webhook sera appelé côté client.
data.versionstringVersion du magic link.
versionstringVersion de l'API qui a traité la requête, utile pour le suivi des modifications et la compatibilité.
statusstringReprésentation textuelle du statut de la réponse, indiquant le succès ou l'échec de l'opération.
status_codeintegerCode de statut HTTP de la réponse, fournissant un indicateur standardisé du résultat de la requête.
request_datestring (date-time)Date et heure de la requête, au format ISO 8601.
request.metadata.redirect_urlstring (nullable)URL de redirection de l'utilisateur une fois le processus KYC terminé (écho de la requête).
request.metadata.webhook_urlstring (nullable)URL pour envoyer les données du processus KYC après complétion (écho de la requête).
request.metadata.track_webhook_urlstring (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 Requestdata provided in the field is invalidStructure 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 ForbiddenForbiddenClé API manquante, expirée ou sans permission. Vérifiez l'en-tête x-api-key.
500 Internal Server Errorinternal 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é.

4. Recevoir le résultat
  • Polling via GET (obligatoire) — appelez GET /v2/history/request?magic_link_token={token} périodiquement jusqu'à ce que unico.result soit renseigné. Voir Polling via GET ci-dessous.
  • Webhook (optionnel) — configurez avec votre Chef de projet Onboarding pour recevoir les événements automatiquement. Voir Webhook ci-dessous.

Polling via GET

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

Paramètres de requête :

ParamètreTypeObligatoireDescription
magic_link_tokenstringOuiToken retourné lors de la création du Magic Link.

En-têtes :

En-têteObligatoireDescription
x-api-keyOuiClé 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
statusstringReprésentation textuelle du statut de la réponse.
status_codeintegerCode de statut HTTP.
request_datestring (date-time)Date et heure de la requête.
versionstringVersion de l'API qui a traité la requête.
data.user_idstringID utilisateur défini dans la requête originale.

data.images — Images capturées encodées en Base64 :

ChampTypeDescription
data.images.document_imagestringImage encodée en Base64 du recto du document.
data.images.document_image_backstringImage encodée en Base64 du verso du document.
data.images.selfiestringImage de selfie encodée en Base64 capturée lors de la vérification.

data.response.unico — Verdict consolidé :

ChampTypeDescription
data.response.unico.process_idstring (UUID)Identifiant interne lié au processus de vérification.
data.response.unico.resultstringRé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_ERRORRejeterLe processus s'est terminé avec une erreur.Système
PROCESS_RESULT_VERIFIEDAccepterL'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_LIVERéviser / AccepterL'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_RISKRecommander le rejetNous avons trouvé au moins une preuve solide de fraude. La décision finale vous appartient.Comportement frauduleux : 1 signal fort
PROCESS_RESULT_CRITICAL_RISKRecommander le rejetNous avons trouvé au moins 2 preuves solides de fraude. La décision finale vous appartient.Comportement frauduleux : 2+ signaux forts
PROCESS_RESULT_NOT_APPROVEDRejeterRejet recommandé car de multiples indications de fraude ont été détectées.Identité : rejetée · Comportement frauduleux : signaux multiples
PROCESS_RESULT_NOT_LIVEAutoriser jusqu'à 2 tentativesL'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_matchbooleanStatut de correspondance faciale entre le document et le selfie.
document.front.face_analysis.match_fraud_flagbooleanSi le visage du document a été associé à une activité frauduleuse.
selfie.match_fraud_flagbooleanSi le visage du selfie a été associé à une activité frauduleuse.
warnings.external_idstringAvertissement 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_matchbooleanSi le visage du selfie correspond au visage du document.
data.response.labelstring (nullable)Réservé aux résultats de sous-processus spécifiques ; null si non applicable.
data.response.reasonstring (nullable)Raisons du label attribué.
data.response.request_idstringIdentifiant unique de la requête API.

data.response.curp — Validation CURP contre RENAPO :

ChampTypeDescription
curpstringLa chaîne CURP analysée.
government_validbooleanSi le CURP est valide selon RENAPO.
government_namestringNom complet associé au CURP dans la base de données officielle.
name_to_CURP_validbooleanSi le nom fourni est cohérent avec le CURP.
is_mexicanbooleanSi le CURP correspond à un citoyen mexicain.
deceasedbooleanSi le CURP est marqué comme décédé dans la base de données officielle.
date_of_birthstringDate de naissance décodée depuis le CURP (JJ/MM/AAAA).
ageintegerÂge calculé de l'utilisateur.
genderstringGenre décodé depuis le CURP (M ou F).
state_of_birthstringÉtat de naissance décodé depuis le CURP.
state_isostringCode ISO 3166-2 de l'état de naissance.

data.response.document.details — Détection de document et analyse forensique :

ChampTypeDescription
detectedbooleanSi un document a été détecté avec succès dans l'image.
document_idintegerIdentifiant unique du document traité.
forensics.is_validstringRé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
namePrénom(s).
last_nameNom de famille paternel.
mother_last_nameNom de famille maternel.
complete_nameNom complet.
birthdateDate de naissance (JJ/MM/AAAA).
sexSexe/genre (H ou M).
curpCURP extrait du document.
electoral_keyClé électorale.
addressAdresse.
registration_yearAnnée d'enregistrement du document.
valid_thruAnnée d'expiration du document.

data.response.document.front.face_analysis — Analyse du visage trouvé sur l'INE :

ChampTypeDescription
face_idintegerIdentifiant unique pour cette instance de visage.
face_id_v2integerIdentifiant unique (version 2).
unique_face_id_v2integerIdentifiant persistant pour ce visage physique dans toutes les demandes.
first_seenstringHorodatage de la première fois que ce visage a été vu dans le système.
last_seenstringHorodatage de la dernière fois que ce visage a été vu dans le réseau.
last_seen_by_your_companystringDernière fois que ce visage a été vu dans une demande de votre entreprise.
inquiry_datestringHorodatage de la demande de vérification actuelle.
matchbooleanSi ce visage est une correspondance potentielle avec d'autres visages dans la base de données.
match_fraud_flagbooleanSi ce visage a été associé à une activité frauduleuse.
seen_by_your_companybooleanSi ce visage a déjà été vu par votre entreprise.
seen_different_companiesintegerNombre d'autres entreprises dans le réseau ayant vu ce visage.
times_seen_by_your_companyintegerNombre total de fois où ce visage a été vu dans les demandes de votre entreprise.
times_seen_last_monthintegerNombre de fois vu le mois dernier dans le réseau.
warnings.external_idstringAvertissement si le visage de l'utilisateur est associé à plusieurs identifiants externes.

data.response.document.back — Données MRZ du verso de l'INE :

ChampTypeDescription
mrzstringChaîne complète de la Zone de Lecture Automatique (MRZ).
cicstringNuméro CIC extrait du MRZ.
citizen_idstringNuméro d'identification du citoyen extrait du MRZ.

data.response.selfie — Analyse du selfie capturé :

ChampTypeDescription
face_idintegerIdentifiant unique pour l'instance du visage du selfie.
face_id_v2integerIdentifiant unique (version 2).
unique_face_id_v2integerIdentifiant persistant pour ce visage physique dans toutes les demandes.
first_seenstringPremière fois que le visage de ce selfie a été vu dans le système.
first_seen_imagebooleanSi c'est la première fois que cette image exacte est vue.
last_seenstringDernière fois que ce visage a été vu dans le réseau.
last_seen_by_your_companystringDernière fois que ce visage a été vu par votre entreprise.
inquiry_datestringHorodatage de la demande de vérification actuelle.
matchbooleanSi le visage du selfie correspond à d'autres visages dans la base de données.
match_fraud_flagbooleanSi le visage du selfie est associé à une activité frauduleuse.
seen_by_your_companybooleanSi ce visage a déjà été vu par votre entreprise.
seen_different_companiesintegerNombre d'autres entreprises dans le réseau ayant vu ce visage.
times_seen_by_your_companyintegerNombre total de fois où ce visage a été vu dans les demandes de votre entreprise.
times_seen_last_monthintegerNombre de fois vu le mois dernier dans le réseau.
warningsobjectAvertissements 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 RequestInput 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 FoundThis magic link have no requests associatedLe 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 Errorinternal 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

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.stepstringNom de l'étape complétée.
data.user_idstring (nullable)Identifiant externe défini dans le magic link.
data.started_ondatetimeHeure de début de l'étape (fuseau UTC).
data.completed_ondatetimeHeure de fin de l'étape (fuseau UTC).
eventstringIdentifiant du type d'événement.
magic_link_tokenuuidToken unique du magic link.
user_idstring (nullable)Identifiant externe.
datedatetimeHorodatage de l'événement.

Étapes supportées :

ÉtapeDescription
form_startL'utilisateur a cliqué sur le bouton initial du magic link.
form_document_frontL'utilisateur a complété la capture du recto de l'INE.
form_document_backL'utilisateur a complété la capture du verso de l'INE.
form_documentL'utilisateur a complété les processus recto et verso.
form_selfieL'utilisateur a complété le processus de liveness.
form_decision_makerL'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_typestringCôté du document : ine_front ou ine_back.
data.invalid_documentbooleantrue si l'image capturée n'est pas un INE valide (recto ou verso).
data.invalid_curpbooleantrue si le CURP n'a pas pu être lu (ine_front uniquement).
data.invalid_back_ocrbooleantrue si le code MRZ n'a pas pu être lu (ine_back uniquement).
eventstringIdentifiant du type d'événement.
magic_link_tokenuuidToken unique du magic link.
user_idstring (nullable)Identifiant externe.
datedatetimeHorodatage 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 / V2

Si 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)