Skip to main content

KYC Magic Link

Separate regional contract

This use case does not use the POST /v1/process Unico endpoint nor the API/TCA contract. The integration is with Trully.ai (host api.trully.ai), with authentication via x-api-key instead of Bearer JWT, and a proprietary response schema. For other countries, use Onboarding (Global).

What this use case solves

KYC Magic Link addresses the challenge of executing the identification process in Mexico, collecting national identity documents (INE) and facial biometrics. With a journey hosted by Unico, you eliminate front-end development friction through a link sent via your own channels (WhatsApp, SMS, email).

Use this use case when:

  • You operate in Mexico and the identity document used is the INE (mandatory).

Do not use this use case when:

  • The user is outside Mexico or uses other documents → look at the other onboarding use cases.

Capabilities involved

Pipeline executed within a single process:

CapabilityRequiredRole in the flow
Document CaptureRequiredCaptures the INE document image. Document reuse is not available in this use case — each session requires a new capture.
LivenessRequiredLiveness check — mandatory selfie that anchors the process.
Risk Fraud ClassificationRequiredCross-references behavioral signals to flag fraud risk associated with the CPF.
Identity VerificationOptional (if contracted)Verifies whether the transaction face belongs to the holder of the provided government identifier, using Unico's identity base and additional signals.

Prerequisites

  • API key — provisioned by your Onboarding Project Manager at Unico. Sent in the x-api-key header.
  • Public HTTPS endpoint to receive webhooks (optional, but recommended).
  • CORS configuration — allow origins https://verification.unico.app (production) and https://verification.uat.unico.app (sandbox) on the server that receives the webhook.

Step-by-step implementation

Unlike other use cases, Magic Link does not have a flow field — the integration is direct with the Trully API. The endpoint creates a unique verification link that you distribute to the user through your own channel.

1. Create the Magic Link

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

Headers:

HeaderRequiredDescription
x-api-keyYesAPI key provisioned by your Onboarding Project Manager at Unico.
Content-TypeYesapplication/json

Body (application/json):

FieldTypeRequiredDescription
external_idstringNoAn external identifier for the request, used for tracking and reference purposes.
metadataobjectNoContainer for configuration parameters.
metadata.phonestringNoUser's phone number in international format (e.g., 521234567890).
metadata.redirect_urlstringNoURL to redirect the user after the KYC process is completed.
metadata.webhook_urlstringNoURL to send the KYC process data after the KYC process is completed. This webhook will be called in the client side. For security reasons the endpoint should use HTTPS. The component will wait one minute for your webhook server to respond — after that, it will drop the communication. The process won't be affected in any way by webhook communication. Make sure to allow https://verification.unico.app and https://verification.uat.unico.app in your CORS configuration for production and sandbox respectively.
metadata.track_webhook_urlstringNoURL to send each KYC step processed by the user (see webhook events below). This webhook will be called in the client side. For security reasons the endpoint should use HTTPS. The component will wait one minute for your webhook server to respond — after that, it will drop the communication. The process won't be affected in any way by webhook communication. Make sure to allow https://verification.unico.app and https://verification.uat.unico.app in your CORS configuration for production and sandbox respectively.

Possible values for data.step (sent to track_webhook_url):

StepDescription
form_startUser is currently scanning the document.
form_document_frontThe user has already captured the INE Front.
form_document_backThe user has already captured the INE Back.
form_documentProcess is currently in the selfie step.
form_selfieUser reached the final step of the operation.
form_decision_makerThe operation returns the system response.

Example request:

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. Receive the token and link URL

Response fields:

FieldTypeDescription
data.external_idstring (nullable)An external identifier for the request, used for tracking and reference purposes.
data.created_onstring (date-time)The date when the magic link was created.
data.is_activebooleanIf true, the magic link is active.
data.tokenstringThe token of the magic link which will be used to link the KYC processes to the magic link.
data.magic_link_urlstring (URI)The magic URL link to start the KYC process.
data.metadata.redirect_urlstring (nullable)URL to redirect the user after the KYC process is completed.
data.metadata.webhook_urlstring (nullable)URL to send the KYC process data after the KYC process is completed. This webhook will be called in the client side.
data.metadata.track_webhook_urlstring (nullable)URL to send each KYC step processed by the user. This webhook will be called in the client side.
data.versionstringThe version of the magic link.
versionstringThe version of the API that processed the request, useful for tracking changes and compatibility.
statusstringA textual representation of the response status, indicating success or failure of the operation.
status_codeintegerThe HTTP status code of the response, providing a standardized indicator of the request's outcome.
request_datestring (date-time)The date and time when the request was made, in ISO 8601 format.
request.metadata.redirect_urlstring (nullable)URL to redirect the user after the KYC process is completed (echo of the request).
request.metadata.webhook_urlstring (nullable)URL to send the KYC process data after completion (echo of the request).
request.metadata.track_webhook_urlstring (nullable)URL to send each KYC step processed by the user (echo of the request).

Example response:

{
"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
}
}
}
Error responses — POST /v2/magic-link
CodeMessageDescription
400 Bad Requestdata provided in the field is invalidInvalid data structure or field values in the request payload. Check required fields and formats.
403 ForbiddenForbiddenAPI key missing, expired or without permission. Verify the x-api-key header.
500 Internal Server Errorinternal server errorServer-side processing failure. Retry with exponential backoff. If persistent, report to support.

Example 400 response:

{
"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. Distribute magic_link_url to the user

Send via WhatsApp, SMS, email or embed. The user accesses the link on their own device and completes the hosted journey.

4. Receive the result
  • Polling via GET (required) — call GET /v2/history/request?magic_link_token={token} periodically until unico.result is populated. See Polling via GET below.
  • Webhook (optional) — configure with your Onboarding PM to receive events automatically. See Webhook below.

Polling via GET

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

Query parameters:

ParameterTypeRequiredDescription
magic_link_tokenstringYesToken returned when the Magic Link was created.

Headers:

HeaderRequiredDescription
x-api-keyYesAPI key provisioned by your Onboarding Project Manager at Unico.

Example request:

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

Example response:

{
"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"
}

Response fields:

Root level:

FieldTypeDescription
statusstringTextual representation of the response status.
status_codeintegerHTTP status code.
request_datestring (date-time)The date and time when the request was made.
versionstringAPI version that processed the request.
data.user_idstringThe user ID set in the original request.

data.images — Base64-encoded captured images:

FieldTypeDescription
data.images.document_imagestringBase64-encoded image of the front of the document.
data.images.document_image_backstringBase64-encoded image of the back of the document.
data.images.selfiestringBase64-encoded selfie image captured during verification.

data.response.unico — Consolidated verdict:

FieldTypeDescription
data.response.unico.process_idstring (UUID)Internal identifier related to the verification process.
data.response.unico.resultstringProcess result. Possible values described below.

Possible values for data.response.unico.result:

The result value encodes one of three evaluation dimensions:

  • Identity assessment — whether the captured face belongs to the document holder (PROCESS_RESULT_VERIFIED, PROCESS_RESULT_NOT_APPROVED).
  • Fraud behavior — whether behavioral or network signals indicate fraud risk (PROCESS_RESULT_LIVE, PROCESS_RESULT_HIGH_RISK, PROCESS_RESULT_CRITICAL_RISK, PROCESS_RESULT_NOT_APPROVED).
  • Liveness — whether a live face was detected at capture time (PROCESS_RESULT_NOT_LIVE).
ResultRecommendationMeaningSignal
PROCESS_RESULT_ERRORRejectProcess finished with error.System
PROCESS_RESULT_VERIFIEDAcceptThe user was active at the time of capture; it is the face of the ID holder and no evidence related to fraud was found.Identity: confirmed
PROCESS_RESULT_LIVEReview / AcceptThe user was active at the time of the capture; we did not find sufficient evidence to guarantee that they are the ID holder and no evidence of fraud.Identity: inconclusive · Fraud: none
PROCESS_RESULT_HIGH_RISKRecommend rejectionWe found at least one strong evidence of fraud. Final decision is yours.Fraud behavior: 1 strong signal
PROCESS_RESULT_CRITICAL_RISKRecommend rejectionWe found at least 2 strong evidences of fraud. Final decision is yours.Fraud behavior: 2+ strong signals
PROCESS_RESULT_NOT_APPROVEDRejectRejection recommended as multiple indications of fraud were detected.Identity: rejected · Fraud behavior: multiple signals
PROCESS_RESULT_NOT_LIVEAllow up to 2 retriesThe user was not live at the time of capture, although we found no other indications of fraud.Liveness: face not live
note

PROCESS_RESULT_VERIFIED requires activation. By default, this result is not active — align with your Unico Project Manager if you want to enable it.

Auxiliary signals for your decision:

For LIVE, HIGH_RISK or CRITICAL_RISK cases, complement your decision with these fields:

FieldTypeMeaning
face_matchbooleanFace matching status between document and selfie.
document.front.face_analysis.match_fraud_flagbooleanWhether the document face has been associated with fraudulent activity.
selfie.match_fraud_flagbooleanWhether the selfie face has been associated with fraudulent activity.
warnings.external_idstringWarning indicating the user's face is associated with multiple external IDs.

data.response — Top-level result signals:

FieldTypeDescription
data.response.face_matchbooleanWhether the selfie face matches the document face.
data.response.labelstring (nullable)Reserved for results from specific sub-processes; null if not applicable.
data.response.reasonstring (nullable)Reasons for the assigned label.
data.response.request_idstringUnique identifier for the API request.

data.response.curp — CURP validation against RENAPO:

FieldTypeDescription
curpstringThe CURP string being analyzed.
government_validbooleanWhether the CURP is valid according to RENAPO.
government_namestringFull name associated with the CURP in the official database.
name_to_CURP_validbooleanWhether the provided name is consistent with the CURP.
is_mexicanbooleanWhether the CURP corresponds to a Mexican citizen.
deceasedbooleanWhether the CURP is marked as deceased in the official database.
date_of_birthstringDate of birth as decoded from the CURP (DD/MM/YYYY).
ageintegerCalculated age of the user.
genderstringGender as decoded from the CURP (M or F).
state_of_birthstringState of birth as decoded from the CURP.
state_isostringISO 3166-2 code for the state of birth.

data.response.document.details — Document detection and forensics:

FieldTypeDescription
detectedbooleanWhether a document was successfully detected in the image.
document_idintegerUnique identifier for the processed document.
forensics.is_validstringForensic analysis result: yes, no or inconclusive.

data.response.document.front.information — OCR-extracted fields from the INE front. Each field contains text (extracted value) and valid (whether it could be structurally validated):

FieldDescription
nameFirst name(s).
last_namePaternal last name.
mother_last_nameMaternal last name.
complete_nameFull name.
birthdateDate of birth (DD/MM/YYYY).
sexSex/gender (H or M).
curpCURP extracted from the document.
electoral_keyElectoral key.
addressAddress.
registration_yearYear the document was registered.
valid_thruDocument expiration year.

data.response.document.front.face_analysis — Analysis of the face found on the INE:

FieldTypeDescription
face_idintegerUnique identifier for this face instance.
face_id_v2integerUnique identifier (version 2).
unique_face_id_v2integerPersistent identifier for this physical face across all inquiries.
first_seenstringTimestamp of the first time this face was ever seen in the system.
last_seenstringTimestamp of the most recent time this face was seen in the network.
last_seen_by_your_companystringMost recent time this face was seen in an inquiry by your company.
inquiry_datestringTimestamp of the current verification inquiry.
matchbooleanWhether this face is a potential match with other faces in the database.
match_fraud_flagbooleanWhether this face has been associated with fraudulent activity.
seen_by_your_companybooleanWhether this face was previously seen by your company.
seen_different_companiesintegerNumber of other companies in the network that have seen this face.
times_seen_by_your_companyintegerTotal times this face was seen in inquiries by your company.
times_seen_last_monthintegerNumber of times seen in the last month across the network.
warnings.external_idstringWarning if the user's face is associated with multiple external IDs.

data.response.document.back — MRZ data from the INE back:

FieldTypeDescription
mrzstringFull Machine-Readable Zone string.
cicstringCIC number extracted from the MRZ.
citizen_idstringCitizen identification number from the MRZ.

data.response.selfie — Analysis of the captured selfie:

FieldTypeDescription
face_idintegerUnique identifier for the selfie face instance.
face_id_v2integerUnique identifier (version 2).
unique_face_id_v2integerPersistent identifier for this physical face across all inquiries.
first_seenstringFirst time this selfie's face was ever seen in the system.
first_seen_imagebooleanWhether this is the first time this exact image was seen.
last_seenstringMost recent time this face was seen in the network.
last_seen_by_your_companystringMost recent time this face was seen by your company.
inquiry_datestringTimestamp of the current verification inquiry.
matchbooleanWhether the selfie face matches other faces in the database.
match_fraud_flagbooleanWhether the selfie face is associated with fraudulent activity.
seen_by_your_companybooleanWhether this face was previously seen by your company.
seen_different_companiesintegerNumber of other companies in the network that have seen this face.
times_seen_by_your_companyintegerTotal times this face was seen in inquiries by your company.
times_seen_last_monthintegerNumber of times seen in the last month across the network.
warningsobjectSpecific warnings related to selfie analysis (same structure as document face_analysis).

Use polling with exponential backoff — do not call in a tight loop.

Error responses — GET /v2/history/request
CodeMessageDescription
400 Bad RequestInput should be a valid UUID, invalid group length...The magic_link_token parameter is malformed or not a valid UUID format.
404 Not FoundThis magic link have no requests associatedThe provided token exists but has no completed KYC processes linked to it. The user may not have finished the journey yet.
500 Internal Server Errorinternal server errorServer-side processing failure. Retry with exponential backoff. If persistent, report to support.

Example 400 response:

{
"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"
}

Example 404 response:

{
"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"
}

Example 500 response:

{
"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

Three webhook events are available. To activate, request setup from your Onboarding Project Manager providing: endpoint URL (HTTPS required), auth type (basic_auth, api_key, oauth2 or NoAuth), auth configuration, max retry attempts, retry interval (s) and timeout (s).

MAGIC_LINK_RESULTS

This event is sent at the end of the flow, when the Decision Maker has finished processing the information sent.

{
"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

These events are received when the user completed an action. For example, form_start will be received when the user is taking the front document, which means that the user clicked and completed the first screen.

{
"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"
}
FieldTypeDescription
data.stepstringName of the completed step.
data.user_idstring (nullable)External ID set in the magic link.
data.started_ondatetimeUTC timezone step start time.
data.completed_ondatetimeUTC timezone step completion time.
eventstringEvent type identifier.
magic_link_tokenuuidUnique magic link token.
user_idstring (nullable)External identifier.
datedatetimeEvent timestamp.

Supported steps:

StepDescription
form_startUser clicked the initial magic link button.
form_document_frontUser completed INE front capture.
form_document_backUser completed INE back capture.
form_documentUser completed both front and back processes.
form_selfieUser completed the liveness process.
form_decision_makerUser completed the entire flow.
MAGIC_LINK_DOCUMENT_RETAKE_REASONS

This event is sent when a document re-capture is required, either during the front or back process. It indicates that critical data from the INE could not be read.

{
"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"
}
FieldTypeDescription
data.document_typestringDocument side: ine_front or ine_back.
data.invalid_documentbooleantrue if the captured image is not a valid INE (either side).
data.invalid_curpbooleantrue if the CURP could not be read (ine_front only).
data.invalid_back_ocrbooleantrue if the MRZ code could not be read (ine_back only).
eventstringEvent type identifier.
magic_link_tokenuuidUnique magic link token.
user_idstring (nullable)External identifier.
datedatetimeEvent timestamp.

The payload is designed so that only one error (true) is received for each document side.

Failure scenarios — INE front:

  • Invalid document → only invalid_document: true
  • CURP reading failure → only invalid_curp: true

Failure scenarios — INE back:

  • Invalid document → only invalid_document: true
  • MRZ reading failure → only invalid_back_ocr: true
V1 / V2 compatibility

If you still send webhook_url in the metadata of the request (Webhook V1), that configuration takes precedence over the global V2. To migrate, remove webhook_url from metadata and configure V2 with your Onboarding PM.


Customizations

The hosted Magic Link page does not support visual customization by the client — it follows the default Unico/Trully visual identity. To customize the journey (logo, colors, texts), use Onboarding (Global) with SDK or Web.

Availability: Mexico · Endpoint: POST https://api.trully.ai/v2/magic-link · Document: INE · Auth: x-api-key (Trully)