---
title: KYC Magic Link
description: Executa o processo de identificação no México, coletando documentos de identidade nacional (INE) e biometria facial por meio de uma jornada hospedada distribuída via link único.
canonical: https://developer.unico.io/pt-BR/dual-api/products/sign-up/kyc-magic-link/index
locale: pt-BR
generated_by: markdown-export
---

- [/pt-BR/](/pt-BR/)
- [Construir](/pt-BR/dual-api/products/)
- Guia Regional Mexicano
- KYC Magic Link

**Nesta página# KYC Magic Link

Contrato regional separadoEste caso de uso **não utiliza** o endpoint `POST /v1/process` da Unico nem o contrato API. A integração é com a **Trully.ai** (host `api.trully.ai`), com **autenticação via `x-api-key`** em vez de Bearer JWT, e um **schema de resposta proprietário**. Para outros países, use Onboarding (Global).
### O que este caso de uso resolve​

O KYC Magic Link endereça o desafio de executar o processo de identificação no México, coletando documentos de identidade nacional (INE) e biometria facial. Com uma jornada hospedada pela Unico, você elimina a fricção de desenvolvimento front-end por meio de um link enviado pelos seus próprios canais (WhatsApp, SMS, e-mail).
**Use este caso de uso quando:**

Você opera no **México** e o documento de identidade utilizado é o **INE (obrigatório)**.

**Não use este caso de uso quando:**

O usuário está fora do México ou utiliza outros documentos → consulte os outros casos de uso de onboarding.

### Capacidades envolvidas​

Pipeline executado dentro de um único processo:
[Captura de Documento (INE)](/pt-BR/capabilities/document-reuse-and-capture)[Liveness](/pt-BR/capabilities/liveness)[Risk Classification](/pt-BR/capabilities/fraud-risk-classification)[Verificação de Identidade](/pt-BR/capabilities/identity-verification)
CapacidadeObrigatóriaPapel no fluxo**Captura de Documento**ObrigatóriaCaptura a imagem do documento INE. O reuso de documento **não está disponível** neste caso de uso — cada sessão requer uma nova captura.**Liveness**ObrigatóriaVerificação de vivacidade — selfie obrigatória que ancora o processo.**Classificação de Risco**ObrigatóriaCruza sinais comportamentais para sinalizar risco de fraude associado ao CPF.**Verificação de Identidade**Opcional (se contratada)Verifica se o rosto da transação pertence ao titular do identificador governamental fornecido, usando a base de identidade da Unico e sinais adicionais.**[Verificação RENAPO](/pt-BR/capabilities/renapo-verification)**Opcional (se contratada)Consulta o RENAPO, o registro nacional de população do México, com a CURP do usuário e retorna o registro junto com o resultado da Verificação de Identidade.
### Pré-requisitos​

**Chave de API** — provisionada pelo seu Gerente de Projeto de Onboarding na Unico. Enviada no header `x-api-key`.
**Endpoint HTTPS público** para receber webhooks (opcional, mas recomendado).
**Configuração de CORS** — permita as origens `https://verification.unico.app` (produção) e `https://verification.uat.unico.app` (sandbox) no servidor que recebe o webhook.

### Implementação passo a passo​

Diferentemente de outros casos de uso, o Magic Link **não possui campo `flow`** — a integração é direta com a API Trully. O endpoint cria um link de verificação único que você distribui ao usuário pelo seu próprio canal.
### 1. Criar o Magic Link​

**Endpoint:** `POST https://sandbox.trully.ai/v2/magic-link`
**Headers:**
HeaderObrigatórioDescrição`x-api-key`SimChave de API provisionada pelo seu Gerente de Projeto de Onboarding na Unico.`Content-Type`Sim`application/json`
**Body (application/json):**
CampoTipoObrigatórioDescrição`external_id`stringNãoUm identificador externo para a requisição, utilizado para fins de rastreamento e referência.`metadata`objectNãoContainer para parâmetros de configuração.`metadata.phone`stringNãoNúmero de telefone do usuário no formato internacional (ex.: `521234567890`).`metadata.redirect_url`stringNãoURL para redirecionar o usuário após a conclusão do processo de KYC.`metadata.webhook_url`stringNãoURL para enviar os dados do processo de KYC após sua conclusão. Este webhook será chamado no lado do cliente. Por razões de segurança, o endpoint deve usar HTTPS. O componente aguardará um minuto pela resposta do seu servidor de webhook — após isso, encerrará a comunicação. O processo não será afetado de forma alguma pela comunicação via webhook. Certifique-se de permitir `https://verification.unico.app` e `https://verification.uat.unico.app` na sua configuração de CORS para produção e sandbox, respectivamente.`metadata.track_webhook_url`stringNãoURL para enviar cada etapa do KYC processada pelo usuário (veja os eventos de webhook abaixo). Este webhook será chamado no lado do cliente. Por razões de segurança, o endpoint deve usar HTTPS. O componente aguardará um minuto pela resposta do seu servidor de webhook — após isso, encerrará a comunicação. O processo não será afetado de forma alguma pela comunicação via webhook. Certifique-se de permitir `https://verification.unico.app` e `https://verification.uat.unico.app` na sua configuração de CORS para produção e sandbox, respectivamente.
`data.step` (enviado para `track_webhook_url`) reporta as mesmas etapas rastreadas pelo Webhook V2 — veja a [tabela de etapas suportadas](#webhook-v2) abaixo.
**Exemplo de requisição:**
```
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. Receber o token e a URL do link​

**Campos da resposta:**
CampoTipoDescrição`data.external_id`string (nullable)Um identificador externo para a requisição, utilizado para fins de rastreamento e referência.`data.created_on`string (date-time)A data em que o magic link foi criado.`data.is_active`booleanSe `true`, o magic link está ativo.`data.token`stringO token do magic link que será usado para vincular os processos de KYC ao magic link.`data.magic_link_url`string (URI)A URL do magic link para iniciar o processo de KYC.`data.metadata.redirect_url`string (nullable)URL para redirecionar o usuário após a conclusão do processo de KYC.`data.metadata.webhook_url`string (nullable)URL para enviar os dados do processo de KYC após sua conclusão. Este webhook será chamado no lado do cliente.`data.metadata.track_webhook_url`string (nullable)URL para enviar cada etapa do KYC processada pelo usuário. Este webhook será chamado no lado do cliente.`data.version`stringA versão do magic link.`version`stringA versão da API que processou a requisição, útil para rastrear mudanças e compatibilidade.`status`stringRepresentação textual do status da resposta, indicando sucesso ou falha da operação.`status_code`integerO código de status HTTP da resposta, fornecendo um indicador padronizado do resultado da requisição.`request_date`string (date-time)A data e hora em que a requisição foi feita, no formato ISO 8601.`request.metadata.redirect_url`string (nullable)URL para redirecionar o usuário após a conclusão do processo de KYC (eco da requisição).`request.metadata.webhook_url`string (nullable)URL para enviar os dados do processo de KYC após a conclusão (eco da requisição).`request.metadata.track_webhook_url`string (nullable)URL para enviar cada etapa do KYC processada pelo usuário (eco da requisição).
**Exemplo de resposta:**
```
{  "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    }  }}
```

**Respostas de erro — POST /v2/magic-link**CódigoMensagemDescrição`400 Bad Request``data provided in the field is invalid`Estrutura de dados inválida ou valores de campo inválidos no payload da requisição. Verifique os campos obrigatórios e os formatos.`403 Forbidden``Forbidden`Chave de API ausente, expirada ou sem permissão. Verifique o header `x-api-key`.`500 Internal Server Error``internal server error`Falha de processamento no servidor. Tente novamente com backoff exponencial. Se persistir, reporte ao suporte.**Exemplo de resposta 400:**```
{  "data": {    "error": "data provided in the field is invalid"  },  "version": "v1.4.2",  "status": "bad request",  "status_code": 400,  "request_date": "2025-07-28T20:22:29+0000",  "request": {    "metadata": null  }}
```

### 3. Distribuir magic_link_url ao usuário​

Envie via WhatsApp, SMS, e-mail ou incorpore. O usuário acessa o link em seu próprio dispositivo e conclui a jornada hospedada.
Se preferir incorporar a jornada dentro do seu próprio aplicativo em vez de abrir o link no navegador, você pode fazer isso via WebView ou CustomTab. PoCs de referência:

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

### 4. Receber o resultado​

Você tem total flexibilidade para decidir como receber o resultado final do processo de KYC — escolha a estratégia que melhor se adapta à arquitetura do seu sistema. Você pode consultar ativamente o resultado (GET) ou recebê-lo passivamente por meio de notificações (Webhook).
**Opção A — Polling ativo via GET**
Recupere o resultado chamando `GET /v2/history/request?magic_link_token={token}` (veja [Polling via GET](#polling-via-get) abaixo). A decisão final é preenchida em `data.response.unico.result`.
Boa prática para o GETEm vez de fazer polling periodicamente a partir do momento em que o link é criado, use os webhooks de rastreamento (veja [Webhook V2](#webhook-v2) abaixo) para saber exatamente quando consultar. Ao receber a etapa `form_decision_maker`, esse é o momento exato e seguro para disparar essa chamada GET.
**Opção B — Recebimento automático via Webhook**
Faça seu sistema ser notificado automaticamente assim que o resultado final estiver pronto (veja [Webhook V2](#webhook-v2) abaixo). Duas versões estão disponíveis:

**Webhook V1** — você recebe o resultado na URL enviada em `metadata.webhook_url` ao criar o token.
**Webhook V2** — configurado previamente com seu PM de Onboarding. Você recebe o veredito final ao escutar o evento `MAGIC_LINK_RESULTS`.

Resiliência — fallbackSe o Webhook (Opção B) for seu método principal, implemente também a consulta GET (Opção A) como fallback. Isso permite recuperar o resultado por meio de rotinas de reconciliação em caso de falhas de rede, indisponibilidades temporárias do servidor, ou um webhook que falhe ao processar corretamente.

### Polling via GET​

**Endpoint:** `GET https://sandbox.trully.ai/v2/history/request`
**Parâmetros de query:**
ParâmetroTipoObrigatórioDescrição`magic_link_token`stringSimToken retornado quando o Magic Link foi criado.
**Headers:**
HeaderObrigatórioDescrição`x-api-key`SimChave de API provisionada pelo seu Gerente de Projeto de Onboarding na Unico.
**Exemplo de requisição:**
```
curl "https://sandbox.trully.ai/v2/history/request?magic_link_token=$TOKEN" \  -H "x-api-key: $TRULLY_API_KEY"
```

**Exemplo de resposta:**
```
{  "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,            "warnings": {              "external_id": "User found in the company with other external_ids: ['abc-123']"            }          },          "information": {            "address": { "text": "DOMICILIO/ADDRESS, HARLINGEN, TX 78552", "valid": false },            "birthdate": { "text": "14/11/1956", "valid": true },            "complete_name": { "text": "LUKE SKYWALKER", "valid": true },            "curp": { "text": "GOCJ850627HDFRRL09", "valid": true },            "electoral_key": { "text": "GRCRSN82031007M500", "valid": true },            "last_name": { "text": "SKYWALKER", "valid": true },            "mother_last_name": { "text": "ORGANA", "valid": true },            "name": { "text": "LUKE", "valid": true },            "registration_year": { "text": "1998", "valid": true },            "sex": { "text": "H", "valid": true },            "valid_thru": { "text": "2027", "valid": true }          }        }      },      "face_match": false,      "label": null,      "reason": null,      "request_id": "d1kxp9ah8f0s71uv9zx0",      "selfie": {        "face_id": 237436,        "face_id_v2": 4378,        "first_seen": "02/05/2025, 02:36:19",        "first_seen_image": true,        "inquiry_date": "07/28/2025, 20:52:49",        "last_seen": "07/28/2025, 20:52:51",        "last_seen_by_your_company": "07/23/2025, 18:14:27",        "match": true,        "match_fraud_flag": true,        "seen_by_your_company": true,        "seen_different_companies": 2,        "times_seen_by_your_company": 2,        "times_seen_last_month": 7,        "unique_face_id_v2": 494,        "warnings": {}      },      "unico": {        "process_id": "d333dfac-9ddb-4066-8e2c-44eaf4c86b4a",        "result": "PROCESS_RESULT_LIVE"      }    },    "user_id": ""  },  "request_date": "2025-07-28T20:53:38",  "status": "Request fulfilled, document follows",  "status_code": 200,  "version": "v3.6.0"}
```

**Campos da resposta:**
**Nível raiz:**
CampoTipoDescrição`status`stringRepresentação textual do status da resposta.`status_code`integerCódigo de status HTTP.`request_date`string (date-time)A data e hora em que a requisição foi feita.`version`stringVersão da API que processou a requisição.`data.user_id`stringO ID do usuário definido na requisição original.
**`data.images`** — Imagens capturadas em Base64:
CampoTipoDescrição`data.images.document_image`stringImagem codificada em Base64 da frente do documento.`data.images.document_image_back`stringImagem codificada em Base64 do verso do documento.`data.images.selfie`stringImagem de selfie codificada em Base64 capturada durante a verificação.
**`data.response.unico`** — Veredicto consolidado:
CampoTipoDescrição`data.response.unico.process_id`string (UUID)Identificador interno relacionado ao processo de verificação.`data.response.unico.result`stringResultado do processo. Valores possíveis descritos abaixo.
**Valores possíveis para `data.response.unico.result`:**
O valor do resultado codifica uma das três dimensões de avaliação:

**Avaliação de identidade** — se o rosto capturado pertence ao titular do documento (`PROCESS_RESULT_VERIFIED`, `PROCESS_RESULT_NOT_APPROVED`).
**Comportamento de fraude** — se sinais comportamentais ou de rede indicam risco de fraude (`PROCESS_RESULT_LIVE`, `PROCESS_RESULT_HIGH_RISK`, `PROCESS_RESULT_CRITICAL_RISK`, `PROCESS_RESULT_NOT_APPROVED`).
**Liveness** — se um rosto ao vivo foi detectado no momento da captura (`PROCESS_RESULT_NOT_LIVE`).

ResultadoRecomendaçãoSignificadoSinal`PROCESS_RESULT_ERROR`**Rejeitar**O processo terminou com erro.Sistema`PROCESS_RESULT_VERIFIED`**Aceitar**O usuário estava ativo no momento da captura; é o rosto do titular do documento e não foram encontradas evidências de fraude.Identidade: confirmada`PROCESS_RESULT_LIVE`**Revisar / Aceitar**O usuário estava ativo no momento da captura; não encontramos evidências suficientes para garantir que é o titular do documento e não há evidências de fraude.Identidade: inconclusiva · Fraude: nenhuma`PROCESS_RESULT_HIGH_RISK`**Recomenda rejeição**Encontramos pelo menos uma evidência forte de fraude. A decisão final é sua.Comportamento de fraude: 1 sinal forte`PROCESS_RESULT_CRITICAL_RISK`**Recomenda rejeição**Encontramos pelo menos 2 evidências fortes de fraude. A decisão final é sua.Comportamento de fraude: 2+ sinais fortes`PROCESS_RESULT_NOT_APPROVED`**Rejeitar**Rejeição recomendada pois múltiplas indicações de fraude foram detectadas.Identidade: rejeitada · Comportamento de fraude: múltiplos sinais`PROCESS_RESULT_NOT_LIVE`**Permitir até 2 tentativas**O usuário não estava ao vivo no momento da captura, embora não tenham sido encontradas outras indicações de fraude.Liveness: face não está ao vivo
observação`PROCESS_RESULT_VERIFIED` **requer ativação**. Por padrão, este resultado **não está ativo** — alinhe com seu Gerente de Projeto da Unico se desejar habilitá-lo.
**Sinais auxiliares para sua decisão:**
Para casos `LIVE`, `HIGH_RISK` ou `CRITICAL_RISK`, complemente sua decisão com estes campos:
CampoTipoSignificado`face_match`booleanStatus de correspondência facial entre o documento e a selfie.`document.front.face_analysis.match_fraud_flag`booleanSe o rosto do documento foi associado a atividade fraudulenta.`selfie.match_fraud_flag`booleanSe o rosto da selfie foi associado a atividade fraudulenta.`warnings.external_id`stringAviso indicando que o rosto do usuário está associado a múltiplos IDs externos.
**`data.response`** — Sinais de resultado de alto nível:
CampoTipoDescrição`data.response.face_match`booleanSe o rosto da selfie corresponde ao rosto do documento.`data.response.label`string (nullable)Reservado para resultados de sub-processos específicos; `null` se não aplicável.`data.response.reason`string (nullable)Razões para o rótulo atribuído.`data.response.request_id`stringIdentificador único para a requisição da API.
**`data.response.curp`** — Validação do CURP contra o RENAPO:
CampoTipoDescrição`curp`stringA string do CURP sendo analisada.`government_valid`booleanSe o CURP é válido de acordo com o RENAPO.`government_name`stringNome completo associado ao CURP no banco de dados oficial.`name_to_CURP_valid`booleanSe o nome fornecido é consistente com o CURP.`is_mexican`booleanSe o CURP corresponde a um cidadão mexicano.`deceased`booleanSe o CURP está marcado como falecido no banco de dados oficial.`date_of_birth`stringData de nascimento decodificada do CURP (DD/MM/YYYY).`age`integerIdade calculada do usuário.`gender`stringGênero decodificado do CURP (`M` ou `F`).`state_of_birth`stringEstado de nascimento decodificado do CURP.`state_iso`stringCódigo ISO 3166-2 para o estado de nascimento.
**`data.response.document.details`** — Detecção e análise forense do documento:
CampoTipoDescrição`detected`booleanSe um documento foi detectado com sucesso na imagem.`document_id`integerIdentificador único para o documento processado.`forensics.is_valid`stringResultado da análise forense: `yes`, `no` ou `inconclusive`.
**`data.response.document.front.information`** — Campos extraídos por OCR da frente do INE. Cada campo contém `text` (valor extraído) e `valid` (se pôde ser estruturalmente validado):
CampoDescrição`name`Primeiro(s) nome(s).`last_name`Sobrenome paterno.`mother_last_name`Sobrenome materno.`complete_name`Nome completo.`birthdate`Data de nascimento (DD/MM/YYYY).`sex`Sexo/gênero (`H` ou `M`).`curp`CURP extraído do documento.`electoral_key`Chave eleitoral.`address`Endereço.`registration_year`Ano em que o documento foi registrado.`valid_thru`Ano de vencimento do documento.
**`data.response.document.front.face_analysis`** — Análise do rosto encontrado no INE:
CampoTipoDescrição`face_id`integerIdentificador único para esta instância de rosto.`face_id_v2`integerIdentificador único (versão 2).`unique_face_id_v2`integerIdentificador persistente para este rosto físico em todas as consultas.`first_seen`stringTimestamp da primeira vez que este rosto foi visto no sistema.`last_seen`stringTimestamp da vez mais recente em que este rosto foi visto na rede.`last_seen_by_your_company`stringÚltima vez em que este rosto foi visto em uma consulta pela sua empresa.`inquiry_date`stringTimestamp da consulta de verificação atual.`match`booleanSe este rosto é uma correspondência potencial com outros rostos no banco de dados.`match_fraud_flag`booleanSe este rosto foi associado a atividade fraudulenta.`seen_by_your_company`booleanSe este rosto foi visto anteriormente pela sua empresa.`seen_different_companies`integerNúmero de outras empresas na rede que viram este rosto.`times_seen_by_your_company`integerTotal de vezes que este rosto foi visto em consultas pela sua empresa.`times_seen_last_month`integerNúmero de vezes visto no último mês em toda a rede.`warnings.external_id`stringAviso se o rosto do usuário está associado a múltiplos IDs externos.
**`data.response.document.back`** — Dados MRZ do verso do INE:
CampoTipoDescrição`mrz`stringString completa da Zona de Leitura por Máquina (MRZ).`cic`stringNúmero CIC extraído do MRZ.`citizen_id`stringNúmero de identificação do cidadão do MRZ.
**`data.response.selfie`** — Análise da selfie capturada:
CampoTipoDescrição`face_id`integerIdentificador único para a instância de rosto da selfie.`face_id_v2`integerIdentificador único (versão 2).`unique_face_id_v2`integerIdentificador persistente para este rosto físico em todas as consultas.`first_seen`stringPrimeira vez que o rosto desta selfie foi visto no sistema.`first_seen_image`booleanSe esta é a primeira vez que esta imagem exata foi vista.`last_seen`stringVez mais recente em que este rosto foi visto na rede.`last_seen_by_your_company`stringVez mais recente em que este rosto foi visto pela sua empresa.`inquiry_date`stringTimestamp da consulta de verificação atual.`match`booleanSe o rosto da selfie corresponde a outros rostos no banco de dados.`match_fraud_flag`booleanSe o rosto da selfie está associado a atividade fraudulenta.`seen_by_your_company`booleanSe este rosto foi visto anteriormente pela sua empresa.`seen_different_companies`integerNúmero de outras empresas na rede que viram este rosto.`times_seen_by_your_company`integerTotal de vezes que este rosto foi visto em consultas pela sua empresa.`times_seen_last_month`integerNúmero de vezes visto no último mês em toda a rede.`warnings`objectAvisos específicos relacionados à análise da selfie (mesma estrutura do face_analysis do documento).
Use polling com **backoff exponencial** — não chame em loop contínuo.
**Respostas de erro — GET /v2/history/request**CódigoMensagemDescrição`400 Bad Request``Input should be a valid UUID, invalid group length...`O parâmetro `magic_link_token` está malformado ou não é um formato UUID válido.`404 Not Found``This magic link have no requests associated`O token fornecido existe, mas não há processos de KYC concluídos vinculados a ele. O usuário pode não ter finalizado a jornada ainda.`500 Internal Server Error``internal server error`Falha de processamento no servidor. Tente novamente com backoff exponencial. Se persistir, reporte ao suporte.**Exemplo de resposta 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"}
```

**Exemplo de resposta 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"}
```

**Exemplo de resposta 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​

Três eventos de webhook estão disponíveis. Para ativá-los, solicite a configuração ao seu Gerente de Projeto de Onboarding, fornecendo: **URL** do endpoint (HTTPS obrigatório), **tipo de autenticação** (`basic_auth`, `api_key`, `oauth2` ou `NoAuth`), **configuração de autenticação**, **número máximo de tentativas**, **intervalo de reenvio (s)** e **timeout (s)**.
MAGIC_LINK_RESULTS
Este evento é enviado ao final do fluxo, quando o Decision Maker terminou de processar as informações enviadas.
```
{  "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
Esses eventos são recebidos quando o usuário concluiu uma ação. Por exemplo, `form_start` será recebido quando o usuário estiver fotografando o documento, o que significa que o usuário clicou e completou a primeira tela.
```
{  "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"}
```

CampoTipoDescrição`data.step`stringNome da etapa concluída.`data.user_id`string (nullable)ID externo definido no magic link.`data.started_on`datetimeHorário de início da etapa no fuso horário UTC.`data.completed_on`datetimeHorário de conclusão da etapa no fuso horário UTC.`event`stringIdentificador do tipo de evento.`magic_link_token`uuidToken único do magic link.`user_id`string (nullable)Identificador externo.`date`datetimeTimestamp do evento.
**Etapas suportadas:**
EtapaDescrição`form_start`Usuário clicou no botão inicial do magic link.`form_document_front`Usuário completou a captura da frente do INE.`form_document_back`Usuário completou a captura do verso do INE.`form_document`Usuário completou os processos da frente e do verso.`form_selfie`Usuário completou o processo de liveness.`form_decision_maker`Usuário completou todo o fluxo.
MAGIC_LINK_DOCUMENT_RETAKE_REASONS
Este evento é enviado quando uma recaptura de documento é necessária, seja durante o processo da frente ou do verso. Indica que dados críticos do INE não puderam ser lidos.
```
{  "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"}
```

CampoTipoDescrição`data.document_type`stringLado do documento: `ine_front` ou `ine_back`.`data.invalid_document`boolean`true` se a imagem capturada não é um INE válido (qualquer lado).`data.invalid_curp`boolean`true` se o CURP não pôde ser lido (apenas `ine_front`).`data.invalid_back_ocr`boolean`true` se o código MRZ não pôde ser lido (apenas `ine_back`).`event`stringIdentificador do tipo de evento.`magic_link_token`uuidToken único do magic link.`user_id`string (nullable)Identificador externo.`date`datetimeTimestamp do evento.
O payload é projetado para que apenas **um** erro (`true`) seja recebido para cada lado do documento.
**Cenários de falha — frente do INE:**

Documento inválido → apenas `invalid_document: true`
Falha na leitura do CURP → apenas `invalid_curp: true`

**Cenários de falha — verso do INE:**

Documento inválido → apenas `invalid_document: true`
Falha na leitura do MRZ → apenas `invalid_back_ocr: true`

Compatibilidade V1 / V2Se você ainda envia `webhook_url` no `metadata` da requisição (Webhook V1), essa configuração **tem precedência** sobre o V2 global. Para migrar, remova `webhook_url` do `metadata` e configure o V2 com seu PM de Onboarding.

### Personalizações​

A página hospedada do Magic Link **não suporta personalização visual** pelo cliente — segue a identidade visual padrão da Unico/Trully. Para personalizar a jornada (logotipo, cores, textos), utilize Onboarding (Global) com SDK ou Web.
**Disponibilidade:** México · **Endpoint:** `POST https://api.trully.ai/v2/magic-link` · **Documento:** INE · **Autenticação:** `x-api-key` (Trully)Última atualização em 8 de out. de 2026**