KYC Magic Link
此用例不使用 Unico 的 POST /v1/process 端点,也不使用 API 合同。集成对象为 Trully.ai(主机 api.trully.ai),通过 x-api-key 进行身份验证(而非 Bearer JWT),并使用专有响应模式。对于其他国家,请使用 Onboarding(全球)。
此用例解决的问题
KYC Magic Link 解决了在墨西哥执行身份识别流程的挑战,负责收集国家身份证件(INE)和面部生物特征。通过 Unico 托管的旅程,您可以借助自己的渠道(WhatsApp、短信、电子邮件)发送的链接,消除前端开发摩擦。
在以下情况下使用此用例:
- 您在墨西哥运营,且使用的身份证件为 INE(必须)。
在以下情况下 请勿使用此用例:
- 用户不在墨西哥或使用其他证件 → 请查看其他入驻用例。
涉及的能力
在单个流程中执行的管道:
| 能力 | 是否必需 | 在流程中的作用 |
|---|---|---|
| Document Capture | 必需 | 采集 INE 证件图像。此用例中不支持文件复用——每个会话都需要重新采集。 |
| Liveness | 必需 | 活体检测——锚定流程的必要自拍。 |
| Risk Fraud Classification | 必需 | 交叉参考行为信号,标记与 CPF 相关的欺诈风险。 |
| Identity Verification | 可选(如已签约) | 使用 Unico 的身份库和附加信号,验证交易人脸是否属于所提供政府标识符的持有人。 |
| RENAPO Verification | 可选(如已签约) | 使用用户的 CURP 查询墨西哥国家人口登记处 RENAPO,并将登记记录与身份验证结果一同返回。 |
前提条件
- API 密钥 — 由 Unico 的 Onboarding 项目经理提供。在
x-api-key请求头中发送。 - 公开 HTTPS 端点,用于接收 webhook(可选,但建议配置)。
- CORS 配置 — 在接收 webhook 的服务器上允许来源
https://verification.unico.app(生产环境)和https://verification.uat.unico.app(沙盒环境)。
分步实现
与其他用例不同,Magic Link 没有 flow 字段——集成直接与 Trully API 对接。该端点创建一个唯一的验证链接,您通过自有渠道分发给用户。
1. 创建 Magic Link
端点: POST https://sandbox.trully.ai/v2/magic-link
请求头:
| 请求头 | 必需 | 描述 |
|---|---|---|
x-api-key | 是 | 由 Unico Onboarding 项目经理提供的 API 密钥。 |
Content-Type | 是 | application/json |
请求体(application/json):
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
external_id | string | 否 | 请求的外部标识符,用于追踪和参考。 |
metadata | object | 否 | 配置参数容器。 |
metadata.phone | string | 否 | 用户的国际格式电话号码(例如 521234567890)。 |
metadata.redirect_url | string | 否 | KYC 流程完成后重定向用户的 URL。 |
metadata.webhook_url | string | 否 | KYC 流程完成后发送数据的 URL。此 webhook 将在客户端调用。出于安全原因,端点应使用 HTTPS。组件将等待一分钟等待您的 webhook 服务器响应——之后将中断通信。流程不会受到 webhook 通信的任何影响。请确保在生产和沙盒环境中分别在 CORS 配置中允许 https://verification.unico.app 和 https://verification.uat.unico.app。 |
metadata.track_webhook_url | string | 否 | 发送用户处理的每个 KYC 步骤的 URL(参见下方 webhook 事件)。此 webhook 将在客户端调用。出于安全原因,端点应使用 HTTPS。组件将等待一分钟等待您的 webhook 服务器响应——之后将中断通信。流程不会受到 webhook 通信的任何影响。请确保在生产和沙盒环境中分别在 CORS 配置中允许 https://verification.unico.app 和 https://verification.uat.unico.app。 |
data.step(发送至 track_webhook_url)报告的步骤与 Webhook V2 追踪的步骤相同——参见下方的支持的步骤表。
示例请求:
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. 接收令牌和链接 URL
响应字段:
| 字段 | 类型 | 描述 |
|---|---|---|
data.external_id | string(可为空) | 请求的外部标识符,用于追踪和参考。 |
data.created_on | string(日期时间) | Magic Link 的创建日期。 |
data.is_active | boolean | 若为 true,则 Magic Link 处于激活状态。 |
data.token | string | Magic Link 的令牌,用于将 KYC 流程与 Magic Link 关联。 |
data.magic_link_url | string(URI) | 用于启动 KYC 流程的 Magic URL 链接。 |
data.metadata.redirect_url | string(可为空) | KYC 流程完成后重定向用户的 URL。 |
data.metadata.webhook_url | string(可为空) | KYC 流程完成后发送数据的 URL。此 webhook 将在客户端调用。 |
data.metadata.track_webhook_url | string(可为空) | 发送用户处理的每个 KYC 步骤的 URL。此 webhook 将在客户端调用。 |
data.version | string | Magic Link 的版本。 |
version | string | 处理请求的 API 版本,用于追踪变更和兼容性。 |
status | string | 响应状态的文本表示,指示操作成功或失败。 |
status_code | integer | 响应的 HTTP 状态码,提供请求结果的标准化指示。 |
request_date | string(日期时间) | 请求的日期和时间,ISO 8601 格式。 |
request.metadata.redirect_url | string(可为空) | KYC 流程完成后重定向用户的 URL(请求回显)。 |
request.metadata.webhook_url | string(可为空) | 完成后发送 KYC 流程数据的 URL(请求回显)。 |
request.metadata.track_webhook_url | string(可为空) | 发送用户处理的每个 KYC 步骤的 URL(请求回显)。 |
示例响应:
{
"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
}
}
}
错误响应 — POST /v2/magic-link
| 代码 | 消息 | 描述 |
|---|---|---|
400 Bad Request | data provided in the field is invalid | 请求 payload 中的数据结构或字段值无效。检查必需字段和格式。 |
403 Forbidden | Forbidden | API 密钥缺失、已过期或无权限。请验证 x-api-key 请求头。 |
500 Internal Server Error | internal server error | 服务器端处理失败。使用指数退避进行重试。如果持续出现,请联系支持团队。 |
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. 将 magic_link_url 分发给用户
通过 WhatsApp、短信、电子邮件发送或嵌入页面。用户在自己的设备上访问链接并完成托管旅程。
如果您希望将旅程嵌入自己的应用中,而不是在浏览器中打开链接,可以通过 WebView 或 CustomTab 实现。参考 PoC:
- Android/Kotlin:TrullyAi-AndroidMagicLink
- React Native:TrullyAI-ReactNativeMagicLink
4. 接收结果
您可以完全灵活地决定如何接收 KYC 流程的最终结果——请选择最适合您系统架构的策略。您可以主动轮询结果(GET),也可以通过通知被动接收(Webhook)。
选项 A — 通过 GET 主动轮询
通过调用 GET /v2/history/request?magic_link_token={token} 获取结果(参见下方的通过 GET 轮询)。最终判定会填充在 data.response.unico.result 中。
不要从链接创建之时起就定期轮询,而应使用追踪 webhook(参见下方的 Webhook V2)来准确了解何时查询。一旦收到 form_decision_maker 步骤,就是触发此 GET 调用的准确、安全时机。
选项 B — 通过 Webhook 自动接收
让您的系统在最终结果准备就绪后立即自动收到通知(参见下方的 Webhook V2)。提供两个版本:
- Webhook V1 — 创建令牌时,您会在
metadata.webhook_url发送的 URL 处收到结果。 - Webhook V2 — 事先与您的 Onboarding PM 配置。您通过监听
MAGIC_LINK_RESULTS事件来接收最终判定。
如果 Webhook(选项 B)是您的主要方式,也请实现 GET 查询(选项 A)作为回退机制。这样,在出现网络故障、服务器临时中断或 webhook 处理失败的情况下,您可以通过对账流程恢复结果。
通过 GET 轮询
端点: GET https://sandbox.trully.ai/v2/history/request
查询参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
magic_link_token | string | 是 | 创建 Magic Link 时返回的令牌。 |
请求头:
| 请求头 | 必需 | 描述 |
|---|---|---|
x-api-key | 是 | 由 Unico Onboarding 项目经理提供的 API 密钥。 |
示例请求:
curl "https://sandbox.trully.ai/v2/history/request?magic_link_token=$TOKEN" \
-H "x-api-key: $TRULLY_API_KEY"
示例响应:
{
"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"
}
响应字段:
根级别:
| 字段 | 类型 | 描述 |
|---|---|---|
status | string | 响应状态的文本表示。 |
status_code | integer | HTTP 状态码 。 |
request_date | string(日期时间) | 请求的日期和时间。 |
version | string | 处理请求的 API 版本。 |
data.user_id | string | 原始请求中设置的用户 ID。 |
data.images — Base64 编码的采集图像:
| 字段 | 类型 | 描述 |
|---|---|---|
data.images.document_image | string | 证件正面的 Base64 编码图像。 |
data.images.document_image_back | string | 证件背面的 Base64 编码图像。 |
data.images.selfie | string | 验证过程中采集的 Base64 编码自拍图像。 |
data.response.unico — 综合判定:
| 字段 | 类型 | 描述 |
|---|---|---|
data.response.unico.process_id | string(UUID) | 与验证流程相关的内部标识符。 |
data.response.unico.result | string | 流程结果。可能的值如下所述。 |
data.response.unico.result 的可能值:
结果值包含三个评估维度之一:
- 身份评估 — 采集的人脸是否属于证件持有人(
PROCESS_RESULT_VERIFIED、PROCESS_RESULT_NOT_APPROVED)。 - 欺诈行为 — 行为或网络信号是否显示欺诈风险(
PROCESS_RESULT_LIVE、PROCESS_RESULT_HIGH_RISK、PROCESS_RESULT_CRITICAL_RISK、PROCESS_RESULT_NOT_APPROVED)。 - 活体检测 — 采集时是否检测到真实人脸(
PROCESS_RESULT_NOT_LIVE)。
| 结果 | 建议 | 含义 | 信号 |
|---|---|---|---|
PROCESS_RESULT_ERROR | 拒绝 | 流程以错误结束。 | 系统 |
PROCESS_RESULT_VERIFIED | 接受 | 用户在采集时是活跃的;是证件持有人的人脸,未发现与欺诈相关的证据。 | 身份:已确认 |
PROCESS_RESULT_LIVE | 审核 / 接受 | 用户在采集时是活跃的;我们没有找到足够证据证明其为证件持有人,也没有欺诈证据。 | 身份:不确定 · 欺诈:无 |
PROCESS_RESULT_HIGH_RISK | 建议拒绝 | 我们发现至少一条强欺诈证据。最终决定由您做出。 | 欺诈行为:1 个强信号 |
PROCESS_RESULT_CRITICAL_RISK | 建议拒绝 | 我们发现至少 2 条强欺诈证据。最终决定由您做出。 | 欺诈行为:2 个以上强信号 |
PROCESS_RESULT_NOT_APPROVED | 拒绝 | 检测到多项欺诈迹象,建议拒绝。 | 身份:已拒绝 · 欺诈行为:多个信号 |
PROCESS_RESULT_NOT_LIVE | 最多允许 2 次重试 | 用户在采集时不是活体,但未发现其他欺诈迹象。 | 活体检测:人脸非活体 |
PROCESS_RESULT_VERIFIED 需要激活。默认情况下,此结果未激活——如需启用,请与您的 Unico 项目经理对齐。
辅助决策信号:
对于 LIVE、HIGH_RISK 或 CRITICAL_RISK 情况,请结合以下字段做出决策:
| 字段 | 类型 | 含义 |
|---|---|---|
face_match | boolean | 证件与自拍照之间的人脸匹配状态。 |
document.front.face_analysis.match_fraud_flag | boolean | 证件人脸是否与欺诈活动相关联。 |
selfie.match_fraud_flag | boolean | 自拍照人脸是否与欺诈活动相关联。 |
warnings.external_id | string | 警告,表示用户人脸与多个外部 ID 关联。 |
data.response — 顶级结果信号:
| 字段 | 类型 | 描述 |
|---|---|---|
data.response.face_match | boolean | 自拍照人脸是否与证件人脸匹配。 |
data.response.label | string(可为空) | 保留用于特定子流程的结果;不适用时为 null。 |
data.response.reason | string(可为空) | 分配标签的原因。 |
data.response.request_id | string | API 请求的唯一标识符。 |
data.response.curp — 针对 RENAPO 的 CURP 验证:
| 字段 | 类型 | 描述 |
|---|---|---|
curp | string | 正在分析的 CURP 字符串。 |
government_valid | boolean | 根据 RENAPO,CURP 是否有效。 |
government_name | string | 官方数据库中与 CURP 关联的全名。 |
name_to_CURP_valid | boolean | 提供的姓名是否与 CURP 一致。 |
is_mexican | boolean | CURP 是否对应墨西哥公民。 |
deceased | boolean | CURP 在官方数据库中是否被标记为已故。 |
date_of_birth | string | 从 CURP 解码的出生日期(DD/MM/YYYY)。 |
age | integer | 用户的计算年龄。 |
gender | string | 从 CURP 解码的性别(M 或 F)。 |
state_of_birth | string | 从 CURP 解码的出生州。 |
state_iso | string | 出生州的 ISO 3166-2 代码。 |
data.response.document.details — 证件检测和取证:
| 字段 | 类型 | 描述 |
|---|---|---|
detected | boolean | 是否在图像中成功检测到证件。 |
document_id | integer | 处理的证件的唯一标识符。 |
forensics.is_valid | string | 取证分析结果:yes、no 或 inconclusive。 |
data.response.document.front.information — 从 INE 正面 OCR 提取的字段。每个字段包含 text(提取值)和 valid(是否可进行结构验证):
| 字段 | 描述 |
|---|---|
name | 名字。 |
last_name | 父系姓氏。 |
mother_last_name | 母系姓氏。 |
complete_name | 全名。 |
birthdate | 出生日期(DD/MM/YYYY)。 |
sex | 性别(H 或 M)。 |
curp | 从证件中提取的 CURP。 |
electoral_key | 选举密钥。 |
address | 地址。 |
registration_year | 证件注册年份。 |
valid_thru | 证件有效期年份。 |
data.response.document.front.face_analysis — 对 INE 上人脸的分析:
| 字段 | 类型 | 描述 |
|---|---|---|
face_id | integer | 此人脸实例的唯一标识符。 |
face_id_v2 | integer | 唯一标识符(版本 2)。 |
unique_face_id_v2 | integer | 跨所有查询的此物理人脸持久标识符。 |
first_seen | string | 此人脸首次在系统中被看到的时间戳。 |
last_seen | string | 此人脸最近一次在网络中被看到的时间戳。 |
last_seen_by_your_company | string | 您的公司最近一次在查询中看到此人脸的时间。 |
inquiry_date | string | 当前验证查询的时间戳。 |
match | boolean | 此人脸是否与数据库中的其他人脸潜在匹配。 |
match_fraud_flag | boolean | 此人脸是否与欺诈活动相关联。 |
seen_by_your_company | boolean | 此人脸是 否曾被您的公司看到。 |
seen_different_companies | integer | 网络中看到此人脸的其他公司数量。 |
times_seen_by_your_company | integer | 此人脸在您公司查询中被看到的总次数。 |
times_seen_last_month | integer | 上个月在整个网络中被看到的次数。 |
warnings.external_id | string | 如果用户人脸与多个外部 ID 关联,则发出警告。 |
data.response.document.back — INE 背面的 MRZ 数据:
| 字段 | 类型 | 描述 |
|---|---|---|
mrz | string | 完整的机器可读区域字符串。 |
cic | string | 从 MRZ 提取的 CIC 号码。 |
citizen_id | string | 从 MRZ 提取的公民身份号码。 |
data.response.selfie — 对采集的自拍照的分析:
| 字段 | 类型 | 描述 |
|---|---|---|
face_id | integer | 自拍人脸实例的唯一标识符。 |
face_id_v2 | integer | 唯一标识符(版本 2)。 |
unique_face_id_v2 | integer | 跨所有查询的此物理人脸持久标识符。 |
first_seen | string | 此自拍人脸首次在系统中被看到的时间。 |
first_seen_image | boolean | 此精确图像是否为首次被看到。 |
last_seen | string | 此人脸最近一次在网络中被看到的时间。 |
last_seen_by_your_company | string | 您的公司最近一次看到此人脸的时间。 |
inquiry_date | string | 当前验证查询的时间戳。 |
match | boolean | 自拍人脸是否与数据库中的其他人脸匹配。 |
match_fraud_flag | boolean | 自拍人脸是否与欺诈活动相关联。 |
seen_by_your_company | boolean | 此人脸是否曾被您的公司看到。 |
seen_different_companies | integer | 网络中看到此人脸的其他公司数量。 |
times_seen_by_your_company | integer | 此人脸在您公司查询中被看到的总次数。 |
times_seen_last_month | integer | 上个月在整个网络中被看到的次数。 |
warnings | object | 与自拍分析相关的特定警告(与 document face_analysis 的结构相同)。 |
使用指数退避进行轮询——请勿在紧循环中调用。
错误响应 — GET /v2/history/request
| 代码 | 消息 | 描述 |
|---|---|---|
400 Bad Request | Input should be a valid UUID, invalid group length... | magic_link_token 参数格式错误或不是有效的 UUID 格式。 |
404 Not Found | This magic link have no requests associated | 提供的令牌存在,但没有与之关联的已完成 KYC 流程。用户可能尚未完成旅程。 |
500 Internal Server Error | internal server error | 服务器端处理失败 。使用指数退避进行重试。如果持续出现,请联系支持团队。 |
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"
}
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"
}
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
提供三种 webhook 事件。如需激活,请联系您的 Onboarding 项目经理,提供:端点 URL(必须使用 HTTPS)、认证类型(basic_auth、api_key、oauth2 或 NoAuth)、认证配置、最大重试次数、重试间隔(秒) 和 超时时间(秒)。
此事件在流程结束时发送,即 Decision Maker 完成处理所发送信息之后。
{
"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"
}
当用户完成某个操作时接收这些事件。例如,当用户正在拍摄证件正面时将收到 form_start,这意味着用户点击并完成了第一个屏幕。
{
"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"
}
| 字段 | 类型 | 描述 |
|---|---|---|
data.step | string | 已完成步骤的名称。 |
data.user_id | string(可为空) | 在 magic link 中设置的外部 ID。 |
data.started_on | datetime | UTC 时区步骤开始时间。 |
data.completed_on | datetime | UTC 时区步骤完成时间。 |
event | string | 事件类型标识符。 |
magic_link_token | uuid | 唯一 Magic Link 令牌。 |
user_id | string(可为空) | 外部标识符。 |
date | datetime | 事件时间戳。 |
支持的步骤:
| 步骤 | 描述 |
|---|---|
form_start | 用户点击了初始 magic link 按钮。 |
form_document_front | 用户完成了 INE 正面采集。 |
form_document_back | 用户完成了 INE 背面采集。 |
form_document | 用户完成了正面和背面的处理流程。 |
form_selfie | 用户完成了活体检测流程。 |
form_decision_maker | 用户完成了整个流程。 |
当需要重新采集证件时(无论是正面还是背面流程),将发送此事件。它表示无法读取 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"
}
| 字段 | 类型 | 描述 |
|---|---|---|
data.document_type | string | 证件面:ine_front 或 ine_back。 |
data.invalid_document | boolean | 若采集的图像不是有效的 INE(任意一面),则为 true。 |
data.invalid_curp | boolean | 若无法读取 CURP,则为 true(仅限 ine_front)。 |
data.invalid_back_ocr | boolean | 若无法读取 MRZ 码,则为 true(仅限 ine_back)。 |
event | string | 事件类型标识符。 |
magic_link_token | uuid | 唯一 Magic Link 令牌。 |
user_id | string(可为空) | 外部标识符。 |
date | datetime | 事件时间戳。 |
载荷设计为每个证件面只接收一个错误(true)。
INE 正面失败场景:
- 无效证件 → 只有
invalid_document: true - CURP 读取失败 → 只有
invalid_curp: true
INE 背面失败场景:
- 无效证件 → 只有
invalid_document: true - MRZ 读取失败 → 只有
invalid_back_ocr: true
如果您仍在请求的 metadata 中发送 webhook_url(Webhook V1),该配置优先于全局 V2。如需迁移,请从 metadata 中删除 webhook_url,并与您的 Onboarding PM 配置 V2。
自定义
托管的 Magic Link 页面不支持客户端的视觉自定义——它遵循默认 的 Unico/Trully 视觉标识。如需自定义旅程(Logo、颜色、文字),请使用带有 SDK 或 Web 的 Onboarding(全球)。
可用地区: 墨西哥 · 端点: POST https://api.trully.ai/v2/magic-link · 证件: INE · 认证: x-api-key(Trully)