> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# API de Travel Rule do GAFI: conformidade para VASPs

> Didit: API de Travel Rule do GAFI para VASPs e PSPs, com troca de dados de remetente e beneficiário e correção automática. $0.02 por troca.

A Didit executa a troca de dados entre remetente e beneficiário exigida pelo GAFI (FATF) e pelo Regulamento de Transferências de Fundos (TFR) da UE para transferências de ativos virtuais: ela procura um canal que alcance o VASP da contraparte, negocia por ele os dados exigidos, acompanha a troca por um ciclo de vida de 13 estados e avisa você quando a troca for concluída, para que você possa liberar os fundos on-chain.

## Visão geral

A Travel Rule do GAFI (Recomendação 16), implementada na UE como o Regulamento de Transferências de Fundos (TFR), exige que o Provedor de Serviços de Ativos Virtuais remetente (o **VASP remetente**) colete e transmita as informações do remetente e do beneficiário ao VASP destinatário (o **VASP beneficiário**) antes que uma transferência de ativo virtual seja liquidada.

Ao contrário da maioria das jurisdições, o TFR da UE se aplica **sem valor mínimo**: toda transferência de cripto está no escopo, não apenas as transferências acima de um limiar de reporte.

O produto Travel Rule da Didit é uma troca gerenciada, não apenas um campo de dados:

* Você envia uma transferência com `transaction_category: "travelRule"`.
* A Didit tenta os trilhos em ordem de prioridade para alcançar o VASP da contraparte, executa a troca pelo primeiro que o alcança e, quando o outro lado retorna um nome de beneficiário, compara esse nome com o que você enviou.
* Somente depois que a troca chegar a `COMPLETED` você deve transmitir a transferência on-chain.
* Em seguida, você informa à Didit o hash da transação on-chain para encerrar a troca como `FINISHED`.

Sete trilhos estão disponíveis nesta versão, tentados em ordem estrita de prioridade: o primeiro que consegue alcançar a contraparte é o utilizado.

| Prioridade | Trilho | Como funciona |
| - | - | - |
| 1 | `INTERNAL` | Usado quando outro cliente da Didit comprovou o controle da carteira do beneficiário com uma mensagem assinada ou um depósito de teste. A Didit cria uma transferência de entrada correspondente na aplicação desse cliente e negocia a troca inteiramente dentro da plataforma, sem nenhuma chamada de saída para a rede. Instantâneo. |
| 2 | `TRP` | Integração nativa com o Travel Rule Protocol (TRP / OpenVASP), um protocolo aberto. Usado quando a transferência traz um [Travel Address](#endereços-de-viagem), quando a entrada da carteira de destino no catálogo de endereços armazena um, ou quando o VASP da contraparte é encontrado no [diretório](#diretório) com um endpoint TRP. Transporta os ativos listados em [Identificadores de ativos TRP](#identificadores-de-ativos-trp). A Didit troca os dados do remetente e do beneficiário de máquina para máquina, sem idas e vindas por e-mail. |
| 3 | `GTR` | Rede Global Travel Rule (GTR). A contraparte é identificada por um `counterparty_gtr_vasp_code` explícito ou por uma entrada do diretório que contenha um. A Didit lê a resposta da contraparte na resposta da GTR ou consultando o status da requisição a cada 5 minutos enquanto a transferência aguarda. |
| 4 | `TRUST` | Rede TRUST. A contraparte é identificada por `counterparty_trust_membership_id` ou por uma entrada do diretório que contenha um. Somente envio: a TRUST não devolve nada que a Didit consiga ler, então a transferência permanece em `AWAITING_COUNTERPARTY` até expirar. |
| 5 | `VERIFYVASP` | Rede VerifyVASP. A contraparte é identificada por `counterparty_verifyvasp_id` ou por uma entrada do diretório que contenha um. A Didit lê a resposta da contraparte consultando o status da verificação a cada 5 minutos. |
| 6 | `SYGNA` | Rede Sygna Bridge (adquirida pela VerifyVASP em 2026, ainda em operação para os membros existentes). Implementação nativa do protocolo Sygna: IVMS101 criptografado com ECIES e requisições de permissão assinadas. A contraparte é identificada por `counterparty_sygna_vasp_code` ou por uma entrada do diretório que contenha um. A resposta de aceite ou rejeição da contraparte conclui ou recusa a transferência: a Didit consulta o status da transferência a cada 5 minutos e também recebe a resposta pelo seu callback Sygna assim que o host TRP público da Didit estiver no ar. |
| 7 | `EMAIL` | Alternativa usada quando nenhum trilho de protocolo ou de rede alcança a contraparte e você informa o contato de conformidade dela em `counterparty_vasp_email`, ou quando a entrada da contraparte no diretório tem um [contato de conformidade](#contatos). A Didit envia a esse contato, por e-mail, um link de acesso de uso único para que ele possa confirmar ou recusar a troca sem uma conta na Didit. Este é o trilho principal para o problema do sunrise: contrapartes que ainda não podem ser alcançadas por nenhuma rede. |

Os trilhos de rede (`GTR`, `TRUST`, `VERIFYVASP`, `SYGNA`) exigem uma associação à rede do lado remetente e, hoje, essa associação precisa ser **sua**.
Conecte as credenciais da sua associação no **Marketplace** do console (categoria de redes de Travel Rule), e suas transferências trafegam sob a sua própria identidade na rede.

**Hoje a Didit não possui associação de plataforma em nenhuma das quatro redes e está em processo de onboarding como provedor nelas.**
Até que esse onboarding seja concluído, `platform_available` é `false` para as quatro, o modo `didit` das configurações (roteamento pela associação de plataforma da Didit) não está disponível para nenhuma rede, e `disabled_networks` não tem nada para desativar.
Uma associação que você mesmo conecta sempre tem precedência sobre uma associação de plataforma.
Nenhuma associação de rede está incluída por padrão, nem mesmo a GTR.
Ativar a Travel Rule não ativa GTR, TRUST, VerifyVASP nem Sygna.
Consulte [Obter configurações da Travel Rule](https://docs.didit.me/pt-br/management-api/travel-rule/get-settings.md) para ver os modos efetivos de `networks` da sua aplicação, e [Redes de Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md) para saber o que cada rede alcança hoje.
Se as quatro informarem `unavailable`, nenhuma consegue rotear uma troca: conecte sua própria associação no **Marketplace** ou use uma contraparte alcançável por `INTERNAL`, `TRP` ou `EMAIL`.

Ao salvar uma associação, o código de participante precisa ser o seu: a operação retorna `400` quando o código é o próprio código da Didit naquela rede ou um código que a associação de outra aplicação já possui.
Uma associação GTR precisa da sua chave privada ed25519 (base64), aquela cuja chave pública está registrada no portal da GTR: ela criptografa os dados pessoais que você envia e descriptografa os dados que você recebe.
Uma associação VerifyVASP aponta para o seu próprio VerifyVASP Enclave: a URL é a do seu Enclave, e o token é o que o seu Enclave apresenta à Didit.

Mesmo com sua própria associação, um trilho de rede só roteia uma transferência quando o `beneficiary_data` dela traz o id da contraparte naquela rede (`counterparty_gtr_vasp_code`, `counterparty_trust_membership_id`, `counterparty_verifyvasp_id` ou `counterparty_sygna_vasp_code`), ou quando a entrada da contraparte no diretório a lista naquela rede (veja [Rotas](#rotas)).

`platform_available` informa se a associação de plataforma está configurada, e não é uma verificação em tempo real do status da rede. Da mesma forma, `connected` significa que as credenciais da sua associação estão salvas e passaram na validação local; a primeira troca real as verifica junto à rede. Um modo `didit` ou `own` não garante que a contraparte seja alcançável nem que a entrega seja bem-sucedida.

Com sua própria associação, a Didit lê a resposta da contraparte via `GTR`, `VERIFYVASP` e `SYGNA` a partir da resposta da rede ou consultando a rede a cada 5 minutos, o que conclui ou recusa a transferência.
`TRUST` apenas envia: uma transferência enviada por ela permanece em `AWAITING_COUNTERPARTY` até que `confirmation_timeout_hours` se esgote, depois passa para `EXPIRED` e o seu `timeout_outcome` é aplicado.
O recebimento de uma transferência que outro VASP envia a você por uma rede ainda não está ativado, e nenhuma troca por uma rede foi concluída em uma rede de produção até agora: consulte [Redes de Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md).

Outras redes (CODE, a aliança coreana, TRISA, Notabene e Veriscope) aparecem no **Marketplace** do console como blocos para solicitar acesso.
A Didit ainda não tem integração com elas, então nenhuma transferência pode ser roteada por elas hoje.

Quando nenhum dos sete canais consegue identificar uma contraparte, a Didit executa mais uma etapa de identificação antes de desistir: a atribuição por análise de blockchain.
A carteira de destino é consultada nos dados de análise de blockchain; quando a carteira pertence a uma exchange ou custodiante conhecida, a Didit registra o VASP atribuído na transferência, adiciona-o ao [diretório](#diretório) e executa os canais mais uma vez com o novo nome.
Consulte [Atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) para ver o comportamento completo e os preços.

Uma transferência cujo destino foi [declarado como carteira autocustodiada](#carteiras-autocustodiadas-declaradas) ignora os sete canais, já que não há VASP de contraparte com quem trocar dados, e segue diretamente para a comprovação de propriedade da carteira pelo usuário final.

> [!NOTE]
>
> A Didit também opera o lado da troca voltado para a contraparte: os endpoints públicos de identidade e de consulta TRP que outros VASPs chamam para alcançar você, os endpoints de callback e o fluxo de retirada por e-mail.
> Você nunca chama esses endpoints diretamente, pois são infraestrutura gerenciada, mas a página [Interoperabilidade de Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-interoperability.md) documenta cada um deles para que VASPs de contraparte possam se conectar a você.
> Você interage com a Travel Rule apenas pelos endpoints `/v3/` descritos nesta página.

## O que é executado quando você envia uma transferência

As verificações são executadas na única chamada `POST /v3/transactions/`. Quando você recebe a resposta, a triagem já foi executada, a transferência já está armazenada e as regras já foram avaliadas.
A troca em si começa depois da resposta: a Didit escolhe o trilho e contata a contraparte fora da sua requisição, então nenhuma rede ou contraparte pode atrasar ou fazer a criação falhar.
Cada mudança de status a partir daí chega como um webhook [`travel_rule.status.updated`](#webhooks) que informa o trilho. O objeto de transferência retornado pelos endpoints de transferência da Travel Rule traz um campo [`delivery`](#entrega-e-novas-tentativas) que mostra se a mensagem foi entregue.
Não há pipeline para consultar periodicamente: as partes assíncronas são a troca, a resposta da contraparte e qualquer ação do usuário final.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant You as Your platform
    participant Didit as Didit API
    participant CP as Counterparty VASP
    participant User as Your customer

    You->>Didit: POST /v3/transactions/ (travelRule)
    Note over Didit: Validate + bind subject + blocklist check
    Note over Didit: Device & IP enrichment
    Note over Didit: Crypto screening (when crypto + monitoring on)
    Note over Didit: Threshold check -> transfer stored (AWAITING_COUNTERPARTY)
    Note over Didit: Rules engine (EU TFR bundle + your rules)
    Didit--)You: transaction.created webhook
    Didit-->>You: Transaction + travel_rule.status + action_required
    Note over Didit: After the response: rails in priority order -> analytics attribution
    Didit->>CP: Exchange over the first reachable rail
    Didit--)You: travel_rule.status.updated (each status change)
    User->>Didit: Proves wallet control (when action_required)
    CP-->>Didit: Confirms beneficiary data
    Didit--)You: travel_rule.status.updated (COMPLETED)
    You->>You: Broadcast on-chain
    You->>Didit: PATCH .../travel-rule/ { payment_txn_id }
    Didit--)You: travel_rule.status.updated (FINISHED)
```

Etapa por etapa:

1. **Validação e vinculação do titular.** O payload é validado.
   Um `transaction_id` já usado na sua aplicação é rejeitado com `400`. Quando duas requisições com o mesmo id concorrem, uma delas recebe `409`.
   O `subject` é vinculado ao perfil do seu usuário ou da sua empresa por `vendor_data`, para que a transferência apareça nesse perfil para monitoramento.
   Um `vendor_data` de titular ou de contraparte que esteja na lista de bloqueio é rejeitado com `400`, e nenhuma transação é criada.
   Carteiras, contas bancárias, IPs e dispositivos na lista de bloqueio são verificados na etapa 6 e recusam a transação nesse ponto, depois que o roteamento foi executado.
2. **Enriquecimento de dispositivo e rede.** Os IPs das partes são enriquecidos com dados geográficos, e qualquer contexto de dispositivo (automático no [envio pelo SDK](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md)) é normalizado no grafo de dispositivos. É o mesmo grafo alimentado pelas sessões de KYC, então a relação "relacionado por dispositivo" funciona entre onboarding e transações.
3. **Triagem cripto.** Em transferências cripto com monitoramento ativado, a carteira relevante (ou o hash on-chain) passa por triagem com análise de blockchain antes de qualquer troca: exposição a sanções, proximidade com mixers e fundos roubados. Consulte [Triagem cripto e de carteiras](https://docs.didit.me/pt-br/transaction-monitoring/aml-screening.md).
4. **Transferência da Travel Rule.** O mecanismo de troca verifica o limiar e respeita uma [declaração de carteira autocustodiada](#carteiras-autocustodiadas-declaradas). Em seguida, armazena a transferência com o trilho ainda vazio: `NOT_APPLICABLE` abaixo do seu limiar, `UNCONFIRMED_OWNERSHIP` para uma carteira autocustodiada declarada, `COMPLETED` quando a outra carteira é a sua própria carteira verificada e `AWAITING_COUNTERPARTY` nos demais casos.
   Cada mudança de status coloca um evento `travel_rule.status.updated` na fila, e a Didit o envia depois do `transaction.created` da transação (etapa 7).
5. **Criação da sessão de propriedade da carteira.** Se a transferência exige que o usuário final comprove o controle da carteira e `auto_wallet_verification` está ativado, uma sessão do [widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) é criada e retornada em `action_required`.
6. **Avaliação de regras.** Todas as regras ativas são executadas. O [pacote EU TFR](#pacote-de-regras-eu-tfr) reage ao status de transferência definido na etapa 4, e suas regras personalizadas veem o resultado da triagem da etapa 3. Uma regra pode reter a transação (`IN_REVIEW`), recusá-la ou exigir uma [verificação adicional](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md#ações-exigidas-do-usuário) (`AWAITING_USER`).
7. **Faturamento e notificação.** Uma transação de saída é faturada em uma única linha: a [linha da Travel Rule](#preços) quando a transação iniciou uma troca, e Triagem de transações nos demais casos. Uma transferência de entrada não gera nenhuma das duas tarifas, e uma aplicação de sandbox nunca é cobrada.
   A resposta é enviada, e `transaction.created` é disparado para os seus destinos de webhook, seguido dos eventos `travel_rule.status.updated` da etapa 4.
8. **Roteamento, depois da resposta.** A Didit percorre os [sete trilhos](#visão-geral) em ordem de prioridade. Se nenhum deles encontrar a contraparte, a [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) identifica a contraparte e os trilhos são executados novamente uma vez. O primeiro trilho alcançável conduz a troca. Nesse trilho, a transferência permanece em `AWAITING_COUNTERPARTY` enquanto a contraparte responde. Ela é liquidada na hora quando uma contraparte `INTERNAL` é encontrada (`COMPLETED` ou `COUNTERPARTY_MISMATCHED_DATA`), e passa a `COUNTERPARTY_VASP_NOT_FOUND` quando nenhum trilho alcança a contraparte. Cada mudança dispara `travel_rule.status.updated`, e suas regras são executadas novamente sempre que o status ou o trilho mudam. Uma transferência que o roteamento deixa em `COUNTERPARTY_VASP_NOT_FOUND` recebe nesse momento a sua sessão do widget de propriedade da carteira (quando `auto_wallet_verification` está ativado). Leia essa sessão no `action_required` da transação com [Obter transação](https://docs.didit.me/pt-br/management-api/transactions/get.md).

### Como cada etapa corresponde às suas obrigações

| Etapa do pipeline | Obrigação que ela cumpre |
| - | - |
| Dados do remetente que você fornece em `originator_data` | Informações precisas do remetente (FATF R.16; EU TFR Art. 14). Nos trilhos que transportam dados pessoais (`INTERNAL`, `TRP` e os trilhos de rede), a Didit transmite a identidade verificada quando o titular é um usuário com uma verificação de KYC da Didit aprovada (consulte [Dados verificados e procedência](#dados-verificados-e-procedência)). Nos demais casos, transmite exatamente o `originator_data` que você envia. |
| Troca pelos trilhos antes da liquidação | Informações do remetente e do beneficiário transmitidas à VASP da contraparte **antes** da liquidação da transferência (FATF R.16; EU TFR Art. 14-16) |
| Correspondência do nome do beneficiário | Verificação de que os dados do beneficiário correspondem ao destino (obrigações do CASP beneficiário pelo EU TFR Art. 16) |
| Comprovação de propriedade da carteira autocustodiada | A obrigação do EU TFR para carteiras autocustodiadas: verificar a propriedade de um endereço não custodiado em vez de fazer a troca com uma VASP |
| Triagem cripto + pacote de regras EU TFR | Procedimentos baseados em risco para transferências com informações ausentes ou incompletas, e controles de exposição a sanções |
| Bloqueio em `COMPLETED` antes da transmissão | Os fundos não são liberados até que a troca seja concluída, o que é o núcleo da regra |
| Encerramento em `FINISHED` com o hash on-chain + linha do tempo | Manutenção de registros: cada transferência traz a linha do tempo completa da negociação para auditoria |

> [!NOTE]
>
> **Observação sobre testes.** Aplicações de sandbox ignoram a avaliação de regras e o faturamento, e não enviam os webhooks `transaction.created` nem `transaction.status.updated`. As transações de sandbox permanecem `APPROVED`, a menos que uma transferência da Travel Rule que expira aplique o seu `timeout_outcome`, e nada é cobrado.
> O próprio mecanismo de troca da Travel Rule é executado em aplicações de sandbox quando a Travel Rule está ativada, com uma única contraparte: toda troca de **saída** vai para o [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) no trilho `TEST_VASP`. Ele responde dentro da Didit com o cenário que você escolher, então a transferência é concluída, é recusada, apresenta divergência, fica inalcançável, expira ou aguarda a comprovação de propriedade da carteira.
> Nenhuma mensagem de conformidade chega a uma VASP real da contraparte, e os webhooks `travel_rule.status.updated` são entregues com `environment: sandbox`.
> **Entrada**: o test VASP pode enviar uma transferência para você ([Acionar transferência de entrada do Test VASP](https://docs.didit.me/pt-br/management-api/travel-rule/trigger-test-vasp-inbound.md)), e o registro (`POST /v3/travel-rule/inbound/`) é liquidado com base no seu catálogo de endereços de carteira, como em uma aplicação de produção: `ON_HOLD`, `UNCONFIRMED_OWNERSHIP`, `COUNTERPARTY_MISMATCHED_DATA` ou `COMPLETED` e depois `FINISHED`.
> Consulte [Testar a Travel Rule no sandbox](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md).

## Ciclo de vida

Toda transferência tem um `status` que assume um de 13 valores.
A troca começa em `AWAITING_COUNTERPARTY` no caso normal, em `NOT_APPLICABLE` quando o valor está abaixo do seu `threshold_amount` ou quando uma solicitação de pagamento Lightning não indica nenhum beneficiário (consulte [Lightning](#lightning)), ou em `UNCONFIRMED_OWNERSHIP` quando o destino foi [declarado como carteira autocustodiada](#carteiras-autocustodiadas-declaradas). Ela termina em um dos estados finais: `FINISHED`, `CANCELLED` ou `EXPIRED`.

A transferência segue sua própria máquina de estados, **separada do** status de revisão da transação subjacente.
Um status da troca nunca altera sozinho o status da transação, com uma exceção: uma expiração aplica o `timeout_outcome` que você configurou (ou uma [política de sunrise ou de contraparte não responsiva](#políticas-de-sunrise-e-de-não-resposta), quando aplicável).
Em vez disso, suas regras são executadas novamente a cada transição. Assim, as [regras da EU TFR](#pacote-de-regras-eu-tfr) ou qualquer regra baseada em `travel_rule_status` podem mover a transação, por exemplo para `IN_REVIEW`.
Uma transferência que exige que o usuário final comprove o controle da carteira adiciona um bloco `action_required` à transação, mas o `status` da transação permanece como suas regras o deixaram.
Leia o estado da troca em `travel_rule.status` e o veredito de permitir / reter / recusar no próprio `status` da transação.

Cada transição (e cada status informado passivamente) também é replicada nos valores personalizados da transação, para que as [regras](https://docs.didit.me/pt-br/transaction-monitoring/rules.md) possam se basear neles: `custom_values.travel_rule_status` (status canônico), `custom_values.travel_rule_rail` (o canal que transportou a troca, vazio até que um seja selecionado) e `custom_values.travel_rule_regime` (derivado da `jurisdiction` nas suas [configurações](#configuração): `SG` → `singapore`, `GB` → `uk` e qualquer código de país membro da UE ou do EEE, como `DE` ou `FR` → `eu`. Códigos sem mapeamento são gravados em minúsculas, por exemplo `US` → `us`. Um `props.travel_rule_regime` que você mesmo envia sempre prevalece sobre o valor derivado).

| Status | Significado |
| - | - |
| `AWAITING_COUNTERPARTY` | A transferência aguarda a contraparte: primeiro enquanto a Didit escolhe o canal e envia a troca, logo após a criação, e depois enquanto a contraparte responde. O campo [`delivery`](#entrega-e-novas-tentativas) da transferência mostra se a mensagem foi entregue. O `TRUST` apenas envia, então uma transferência por esse canal permanece neste status até expirar. |
| `UNCONFIRMED_OWNERSHIP` | A transferência aguarda a comprovação de controle da carteira. Ocorre quando a carteira da contraparte foi [declarada autocustodiada](#carteiras-autocustodiadas-declaradas) no envio (de saída ou de entrada), ou quando uma transferência de entrada corresponde a uma [entrada do catálogo de endereços](#catálogo-de-endereços-de-carteiras) cuja propriedade ainda não foi verificada. Avança pelo [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) ou por [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira). |
| `ON_HOLD` | A Didit define este status apenas em transferências de entrada: a carteira de destino de um [registro após o depósito](#registro-sunrise-após-o-depósito) ou de uma consulta `TRP` de entrada não está no seu [catálogo de endereços](#catálogo-de-endereços-de-carteiras), ou uma consulta `TRP` de entrada aguarda sua decisão (a aceitação automática está desativada ou a resposta automática não pôde ser entregue). Resolva com [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira). Ele não altera sozinho o status da transação; a [regra da biblioteca](https://docs.didit.me/pt-br/transaction-monitoring/rules-library.md) opcional `travel-rule-pending-action` move essas transações para `AWAITING_USER`. |
| `COMPLETED` | A troca foi concluída com sucesso: a contraparte (ou você, em uma transferência de entrada) a aprovou, ou as verificações que a Didit executa nesse caminho foram aprovadas (correspondência do nome do beneficiário, comprovação de propriedade da carteira). É seguro transmitir a transferência on-chain. |
| `FINISHED` | A troca é encerrada com o hash da transação on-chain. Em uma transferência de saída, você informa o hash via [`PATCH .../travel-rule/`](#envio-de-uma-transferência). Em uma transferência de entrada, a Didit define este status quando o depósito já foi liquidado ([registro após o depósito](#registro-sunrise-após-o-depósito)), quando o remetente confirma uma transferência `TRP` ou quando o lado de saída `INTERNAL` é concluído. |
| `CANCELLED` | Cancelada manualmente com `action: "cancel"` a partir de qualquer estado não final, ou cancelada pelo remetente de uma transferência `TRP` de entrada. |
| `EXPIRED` | O prazo de `confirmation_timeout_hours` se esgotou enquanto o status era `AWAITING_COUNTERPARTY`. Um processo de varredura (a cada 15 minutos) expira a transferência e aplica o `timeout_outcome` configurado à transação subjacente: `REJECT` a recusa, `HOLD` a envia para revisão e `PROCEED` a deixa inalterada. Sua [política de sunrise ou de contraparte não responsiva](#políticas-de-sunrise-e-de-não-resposta) substitui o `timeout_outcome` quando aplicável. |
| `COUNTERPARTY_MISMATCHED_DATA` | O nome do beneficiário não atendeu ao `name_matching_strictness` configurado em relação ao outro lado: o nome retornado pela contraparte ou o `holder_name` da entrada correspondente no catálogo de endereços. |
| `COUNTERPARTY_VASP_NOT_FOUND` | Nenhum dos sete canais, nem o recurso alternativo de [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain), conseguiu identificar um VASP de contraparte alcançável para esta transferência. Qualquer entidade atribuída continua registrada na transferência e no diretório. Em transferências de saída, a Didit gera automaticamente uma sessão do [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) (quando `auto_wallet_verification` está ativado), para que a transferência ainda possa ser concluída como uma transferência para carteira autocustodiada. `reason` e `next_actions` informam o motivo e o que faz a transferência avançar: consulte [Por que uma transferência está parada](#por-que-uma-transferência-fica-travada). |
| `COUNTERPARTY_VASP_NOT_REACHABLE` | Um VASP de contraparte foi identificado, mas o canal selecionado não conseguiu entregar: o endpoint de identidade ou de consulta `TRP` dele não pôde ser alcançado, a identidade informada não correspondeu a `counterparty_vasp_lei` ou `counterparty_vasp_name`, uma rede recusou a mensagem ou não a aceitou após seis tentativas (consulte [Entrega e novas tentativas](#entrega-e-novas-tentativas)), ou o provedor de e-mail recusou o e-mail de conformidade. `reason` distingue esses casos e `next_actions` informa o que faz a transferência avançar: consulte [Por que uma transferência está parada](#por-que-uma-transferência-fica-travada). Tente novamente com `action: "resend"` assim que ele voltar a ficar alcançável. |
| `COUNTERPARTY_VASP_GENERAL_DECLINE` | A contraparte recusou a troca: propriedade negada, recebimento do e-mail recusado ou rejeição via `TRP` ou Sygna. |
| `NOT_ENOUGH_COUNTERPARTY_DATA` | Uma consulta `TRP` de entrada não identificou o beneficiário nem pelo nome nem pelo endereço da carteira, então a Didit não conseguiu associá-la ao seu catálogo de endereços. Nem o endpoint de propriedade nem `resend` aceitam essa transferência de entrada: você só pode cancelá-la, e o cancelamento não responde à consulta da contraparte. A Didit nunca define este status em uma transferência de saída; se você mesmo o registrar em uma, `action: "resend"` executa o roteamento novamente. |
| `NOT_APPLICABLE` | O valor da transferência ficou abaixo do `threshold_amount` configurado, uma solicitação de pagamento [Lightning](#lightning) de saída não indica nenhum beneficiário (`chain_details.not_applicable_reason` informa o motivo) ou você mesmo registrou esse status com a Travel Rule desativada (incluindo os valores legados `UNKNOWN` e `EXEMPT`, veja abaixo). |

> [!WARNING]
>
> **Nunca transmita antes de `COMPLETED`.**
> Liberar fundos on-chain enquanto uma transferência está em `AWAITING_COUNTERPARTY`, `UNCONFIRMED_OWNERSHIP` ou em qualquer estado de divergência ou recusa anula o propósito da troca.
> Condicione sua etapa de transmissão a `status == "COMPLETED"` e, em seguida, chame `PATCH .../travel-rule/` com o `payment_txn_id` resultante para passar a `FINISHED`.

As transições em resumo (`CANCELLED` também pode ser alcançado a partir de qualquer estado não terminal com `action: "cancel"`):

```mermaid theme={null}
stateDiagram-v2
    [*] --> NOT_APPLICABLE: below threshold
    [*] --> UNCONFIRMED_OWNERSHIP: self-hosted wallet declared
    [*] --> AWAITING_COUNTERPARTY: transfer stored, routing queued
    [*] --> COMPLETED: your own verified wallet
    [*] --> ON_HOLD: inbound with no matching wallet entry
    [*] --> NOT_ENOUGH_COUNTERPARTY_DATA: inbound TRP inquiry names no beneficiary
    AWAITING_COUNTERPARTY --> COUNTERPARTY_MISMATCHED_DATA: INTERNAL rail, verified entry, name mismatch
    AWAITING_COUNTERPARTY --> COUNTERPARTY_VASP_NOT_FOUND: no rail resolved
    AWAITING_COUNTERPARTY --> COUNTERPARTY_VASP_NOT_REACHABLE: delivery failed
    AWAITING_COUNTERPARTY --> COMPLETED: counterparty confirmed, names match where checked
    AWAITING_COUNTERPARTY --> COUNTERPARTY_MISMATCHED_DATA: name match failed
    AWAITING_COUNTERPARTY --> COUNTERPARTY_VASP_GENERAL_DECLINE: counterparty declined
    AWAITING_COUNTERPARTY --> EXPIRED: confirmation timeout
    AWAITING_COUNTERPARTY --> COUNTERPARTY_VASP_NOT_REACHABLE: TRP inquiry not delivered
    UNCONFIRMED_OWNERSHIP --> COMPLETED: ownership proven, names match
    UNCONFIRMED_OWNERSHIP --> COUNTERPARTY_MISMATCHED_DATA: name match failed
    UNCONFIRMED_OWNERSHIP --> COUNTERPARTY_VASP_GENERAL_DECLINE: ownership denied
    ON_HOLD --> COMPLETED: you confirm the wallet, names match
    ON_HOLD --> COUNTERPARTY_MISMATCHED_DATA: you confirm the wallet, name mismatch
    ON_HOLD --> COUNTERPARTY_VASP_GENERAL_DECLINE: you deny the wallet
    COUNTERPARTY_MISMATCHED_DATA --> COMPLETED: you approve an inbound TRP inquiry
    COUNTERPARTY_MISMATCHED_DATA --> COUNTERPARTY_VASP_GENERAL_DECLINE: you decline an inbound TRP inquiry
    COUNTERPARTY_VASP_NOT_FOUND --> COMPLETED: wallet ownership proven in the widget
    COUNTERPARTY_VASP_NOT_FOUND --> AWAITING_COUNTERPARTY: action resend
    COUNTERPARTY_VASP_NOT_REACHABLE --> AWAITING_COUNTERPARTY: action resend
    COMPLETED --> FINISHED: payment_txn_id reported or deposit already settled
    FINISHED --> [*]
    EXPIRED --> [*]
```

### Entrega e novas tentativas

A Didit envia cada mensagem que uma transferência deve enviar fora da requisição que a originou e tenta novamente até que o outro lado a receba.
O objeto de transferência retornado por [Finalizar, cancelar ou reenviar](https://docs.didit.me/pt-br/management-api/travel-rule/update-transfer.md), [Confirmar propriedade](https://docs.didit.me/pt-br/management-api/travel-rule/confirm-ownership.md) e [registro sunrise](#registro-sunrise-após-o-depósito) traz a mensagem mais recente em `delivery`, assim como o objeto `travel_rule` incorporado à transação; ele é `null` quando a transferência nunca deveu nenhuma mensagem.

| Campo | Significado |
| - | - |
| `kind` | `SEND` (a primeira mensagem para a contraparte), `ANSWER` (sua aceitação ou recusa, devida à rede que perguntou), `TXID` (o hash on-chain, depois que você finaliza a transferência), `CANCEL` (depois que você a cancela) ou `POLL` (uma consulta de status a uma rede que a oferece, a cada 5 minutos enquanto a transferência aguarda a contraparte). |
| `status` | `QUEUED`, `SENDING`, `RETRYING`, `DELIVERED` ou `FAILED`. |
| `rail` | O canal que transporta a mensagem; vazio até que a Didit tenha escolhido um para a primeira mensagem. |
| `attempts` | Tentativas feitas até o momento. |
| `last_error` | Por que a última tentativa falhou; vazio quando nenhuma falhou. Um motivo curto que indica a etapa e o tipo de falha, por exemplo `sygna permission request failed: HTTP 503` ou `sygna status query failed: no answer in time`; quando a GTR responde com um erro, o código de status e a mensagem dela são incluídos. Os corpos de resposta nunca são incluídos. |
| `next_attempt_at` | Quando a próxima tentativa será executada, enquanto a mensagem estiver em `QUEUED` ou `RETRYING`. |
| `delivered_at` | Quando o outro lado recebeu a mensagem. |

Uma falha da qual a rede ainda pode se recuperar (sem resposta a tempo, falha de conexão, HTTP `408`, `429` ou `5xx`) é tentada novamente após 30 segundos, 2 minutos, 10 minutos, 30 minutos e 1 hora.
Quando uma primeira mensagem falha definitivamente (a rede a recusou ou a sexta tentativa também falhou), a transferência passa para `COUNTERPARTY_VASP_NOT_REACHABLE` com `last_error` em sua `timeline`, e você pode tentar novamente com `action: "resend"`.
Qualquer outra mensagem que falhe definitivamente é registrada na `timeline`.
`delivery` nunca substitui o `status` da transferência: acompanhe a troca pelo `status` e use `delivery` para ver por que uma transferência ainda está aguardando.

### Valores de status legados

Se você já enviava `travel_rule_details.status` antes desta versão, esses valores continuam funcionando e são mapeados automaticamente.
Grafias em camelCase de qualquer status (por exemplo `counterpartyVaspNotFound`) também são aceitas, tanto no envio quanto nos valores de condição de [regras](https://docs.didit.me/pt-br/transaction-monitoring/rules.md), e são normalizadas para a forma canônica:

| Valor legado | Mapeado para |
| - | - |
| `UNKNOWN` | `NOT_APPLICABLE` |
| `COMPLIANT` | `COMPLETED` |
| `PENDING_ACTION` | `ON_HOLD` |
| `PENDING_COUNTERPARTY` | `AWAITING_COUNTERPARTY` |
| `FAILED` | `CANCELLED` |
| `EXEMPT` | `NOT_APPLICABLE` |

## Configuração

Configure o perfil do seu VASP e a política de negociação uma vez por aplicação com `GET`/`PUT /v3/travel-rule/settings/`.

```bash theme={null}
curl -X GET https://verification.didit.me/v3/travel-rule/settings/ \
  -H "x-api-key: YOUR_API_KEY"
```

```json theme={null}
{
  "is_enabled": false,
  "jurisdiction": "EU",
  "name_matching_strictness": "DEFAULT",
  "confirmation_timeout_hours": 48,
  "timeout_outcome": "HOLD",
  "threshold_amount": "0.00",
  "inbound_auto_accept": true,
  "allow_self_declaration": true,
  "allow_screenshot_proof": true,
  "auto_wallet_verification": true,
  "vasp_attribution_enabled": true,
  "counterparty_screening_enabled": false,
  "sunrise_policy": "",
  "sunrise_jurisdictions": ["CO", "KH", "VN"],
  "non_responsive_policy": "",
  "legal_name": "",
  "lei": "",
  "compliance_email": "",
  "is_discoverable": true,
  "travel_address": "",
  "disabled_networks": [],
  "networks": {
    "gtr": { "rail": "GTR", "mode": "unavailable", "platform_available": false, "connected": false },
    "trust": { "rail": "TRUST", "mode": "unavailable", "platform_available": false, "connected": false },
    "verifyvasp": { "rail": "VERIFYVASP", "mode": "unavailable", "platform_available": false, "connected": false },
    "sygna": { "rail": "SYGNA", "mode": "unavailable", "platform_available": false, "connected": false }
  }
}
```

```bash theme={null}
curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "is_enabled": true,
    "legal_name": "Origin CASP SL",
    "jurisdiction": "EU",
    "name_matching_strictness": "DEFAULT",
    "confirmation_timeout_hours": 48,
    "timeout_outcome": "HOLD",
    "is_discoverable": true
  }'
```

`PUT` é uma atualização parcial: envie apenas os campos que você quer alterar.

| Campo | Tipo | Descrição |
| - | - | - |
| `is_enabled` | boolean | Ativa o fluxo de negociação gerenciado para transações `travelRule` de saída desta aplicação. Exige um `legal_name` não vazio (já armazenado ou incluído na mesma requisição); caso contrário, a requisição retorna `400`. |
| `legal_name` | string | A razão social do seu VASP. É exibida à contraparte na página de retirada por e-mail e retornada no [diretório de VASPs](#diretório). |
| `lei` | string | O seu Legal Entity Identifier (LEI), retornado no diretório de VASPs. |
| `jurisdiction` | string | O código da jurisdição de atuação do seu VASP, com até 8 caracteres (padrão `"EU"`). |
| `name_matching_strictness` | string | `NONE`, `STRICT`, `CONTAINS`, `DEFAULT` ou `FUZZY`; veja abaixo. |
| `confirmation_timeout_hours` | integer | Número de horas que uma transferência em `AWAITING_COUNTERPARTY` pode ficar parada antes de expirar automaticamente. Mínimo `1`, padrão `48`. |
| `timeout_outcome` | string | O que acontece com a transação subjacente quando uma transferência expira: `HOLD` a envia para revisão, `REJECT` a recusa e `PROCEED` mantém o status dela inalterado. Padrão `HOLD`. `sunrise_policy` e `non_responsive_policy` têm precedência quando uma delas se aplica. |
| `sunrise_policy` | string | `HOLD`, `REJECT`, `PROCEED` ou `""` (padrão) para seguir `timeout_outcome`: o que acontece com uma transferência expirada quando a contraparte é uma entrada do diretório em uma jurisdição listada em `sunrise_jurisdictions`. Veja [Políticas de sunrise e de não resposta](#políticas-de-sunrise-e-de-não-resposta). |
| `non_responsive_policy` | string | `HOLD`, `REJECT`, `PROCEED` ou `""` (padrão) para seguir `timeout_outcome`: o que acontece com uma transferência expirada quando a contraparte é uma entrada do diretório cuja [capacidade de resposta](#capacidade-de-resposta) é `UNRESPONSIVE`. `sunrise_policy` se aplica primeiro quando ambas se encaixam. |
| `sunrise_jurisdictions` | string\[] | Somente leitura. Os países que a Didit considera em período de sunrise da Travel Rule, atualmente `["CO", "KH", "VN"]`. Qualquer outra jurisdição segue `timeout_outcome`. |
| `compliance_email` | string | E-mail de contato de conformidade do perfil do seu VASP. A [rede Didit](#a-rede-didit) só lista o seu perfil depois que esse endereço é confirmado por um link enviado por e-mail; alterá-lo exige uma nova confirmação. |
| `is_discoverable` | boolean | Define se o perfil do seu VASP pode ser listado na [rede Didit](#a-rede-didit): encontrado em `GET /v3/travel-rule/vasps/` por outros clientes da Didit e alcançado pelo trilho INTERNAL. A listagem tem outras condições; `didit_network` nas configurações indica quais estão faltando. Padrão `true`. |
| `inbound_auto_accept` | boolean | Quando `true`, uma consulta `TRP` de entrada cuja carteira do beneficiário é uma entrada verificada no seu catálogo de endereços e cujo nome corresponde é aprovada automaticamente. Quando `false`, ela aguarda em `ON_HOLD` pela sua decisão. Os outros caminhos de entrada não leem esta configuração. Padrão `true`. |
| `allow_self_declaration` | boolean | Quando `true`, o [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) oferece a autodeclaração como método de comprovação, e você pode criar entradas no [catálogo de endereços de carteiras](#catálogo-de-endereços-de-carteiras) com `self_declared: true`. Padrão `true`. |
| `allow_screenshot_proof` | boolean | Quando `true`, o [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) oferece o envio de captura de tela como método de evidência de propriedade. Uma captura de tela nunca verifica a carteira por si só: a sua equipe de conformidade a revisa e confirma a transferência. É mais fraca que a assinatura criptográfica; desative-a quando a sua política exigir comprovação no nível de assinatura. Padrão `true`. |
| `auto_wallet_verification` | boolean | Quando `true`, uma transferência de saída que precisa de comprovação de controle da carteira pelo usuário final gera automaticamente uma sessão do [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) vinculada à transação e a exibe no bloco `action_required` da transação; os SDKs da Didit a iniciam automaticamente no [envio pelo lado do cliente](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md). Padrão `true`. |
| `counterparty_screening_enabled` | boolean | [Triagem de VASPs contraparte](#triagem-da-contraparte) opcional quanto a sanções e mídia adversa, faturada por triagem ao preço da Análise AML de empresas. Quando `true`, a Didit faz a triagem da contraparte alcançada por uma troca de saída no início da troca, reaproveitando uma triagem com menos de 30 dias. Padrão `false`: nada é triado nem faturado. |
| `vasp_attribution_enabled` | boolean | Quando `true`, uma transferência de saída que nenhum trilho consegue rotear é atribuída por meio de [análise de blockchain](#atribuição-por-análise-de-blockchain): a carteira de destino é associada ao VASP que a detém, a entidade é adicionada ao diretório e os trilhos são executados novamente uma vez com o nome atribuído. Padrão `true`. |
| `threshold_amount` | string (decimal) | Valor mínimo de transferência que aciona uma troca gerenciada, na moeda padrão da sua aplicação: a Didit o compara com o valor da transferência convertido para essa moeda (ou com o `amount_in_default_currency` que você envia), e não com o valor na moeda da própria transferência. Transferências abaixo dele são resolvidas diretamente como `NOT_APPLICABLE` e nunca são negociadas. Se a Didit não conseguir converter o valor, o limiar não é aplicado e a transferência passa pela troca. Aplicações de sandbox não convertem valores, então nelas o limiar só se aplica quando você envia `amount_in_default_currency`. O padrão é `0.00`, alinhado à ausência de valor mínimo no EU TFR, de modo que toda transferência é verificada independentemente do valor. |
| `ownership_validation_mode` | string | `FULL`, `SIMPLIFIED` ou `AUTOMATED`: quanta comprovação a propriedade de uma carteira exige. Veja [Modos de validação de propriedade](#modos-de-validação-de-propriedade). Padrão `AUTOMATED`. |
| `simplified_validation_threshold` | string (decimal) | No modo `SIMPLIFIED`, uma transferência abaixo deste valor aceita uma autodeclaração. Padrão `0.00`. |
| `data_sharing_fields` | object | Os campos que você envia sobre os seus próprios usuários, por tipo de entidade. Veja [Compartilhamento de dados](#compartilhamento-de-dados). |
| `matching_rules` | object | O rigor com que cada campo dos dados da contraparte é comparado, por tipo de entidade. Veja [Correspondência por campo](#correspondência-por-campo). |
| `disabled_networks` | string\[] | Rails de rede (`GTR`, `TRUST`, `VERIFYVASP`, `SYGNA`) pelos quais suas transferências NÃO devem ser roteadas por meio da associação de plataforma da Didit. Uma rede para a qual você conectou sua própria associação (Marketplace do console) nunca é afetada por esta lista. A Didit ainda não tem nenhuma associação de plataforma, então hoje a lista não tem efeito no roteamento (um rail listado informa `mode: off`). Padrão `[]`. |
| `networks` | object | Somente leitura. Status por rede, indexado por `gtr` / `trust` / `verifyvasp` / `sygna`: `{rail, mode, platform_available, connected}`, em que `mode` é `own` (a sua associação conectada), `didit` (a associação de plataforma da Didit, ainda indisponível em todas as redes), `off` (desativada por você) ou `unavailable`. |
| `travel_address` | string | Somente leitura. O travel address do seu próprio VASP: o endpoint `TRP` de consultas de entrada, codificado, que outros VASPs usam para alcançar você. É preenchido assim que o Travel Rule é ativado, por exemplo `ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeS5uNDp3dGW3bweBWLKws442chRsyNxmmJnyWc7frxjjSeABVsYR11UuBePkw6E`. |

### Rigor da correspondência de nomes

| Valor | Comportamento |
| - | - |
| `NONE` | Qualquer nome de beneficiário é aceito e nenhuma comparação é feita. |
| `STRICT` | Os conjuntos de tokens normalizados dos dois nomes devem ser exatamente iguais. |
| `CONTAINS` | Todas as palavras de um nome aparecem no outro, por menos que sejam. |
| `DEFAULT` | Cada token do nome mais curto deve aparecer no nome mais longo (correspondência de subconjunto), e o nome mais curto precisa ter pelo menos dois tokens, a menos que os dois nomes sejam idênticos. |
| `FUZZY` | A razão de similaridade entre as strings normalizadas completas deve ser de pelo menos `0.85`. |

### Modos de validação de propriedade

`ownership_validation_mode` define quanta prova a propriedade de uma carteira exige antes que uma transferência se apoie nela:

| Modo | Comportamento |
| - | - |
| `FULL` | Uma prova é sempre exigida: uma mensagem assinada, um depósito de teste ou uma captura de tela revisada. A palavra do usuário final nunca conta. O widget não oferece `SELF_DECLARATION`, iniciar uma responde `403`, e uma entrada no catálogo de endereços criada com `self_declared: true` responde `400`. |
| `SIMPLIFIED` | Uma autodeclaração é aceita enquanto a transferência estiver abaixo de `simplified_validation_threshold`; acima disso, uma prova é exigida. Uma transferência de entrada (uma consulta TRP, uma mensagem de rede ou um depósito que você informa) é avaliada pelo seu valor convertido para a moeda padrão da sua aplicação, pela cotação atual. Um ativo sem cotação, e toda transferência de uma aplicação de sandbox, conta como acima do limiar. |
| `AUTOMATED` | O catálogo de endereços e as provas anteriores do usuário final respondem por si só, incluindo autodeclarações enquanto `allow_self_declaration` for `true`. Este é o padrão e o que toda aplicação fazia antes de os modos existirem. |

Uma carteira é memorizada por usuário final depois de verificada.
Em `FULL` e `SIMPLIFIED`, uma transferência posterior só a reutiliza quando ela é respaldada por uma prova que o modo aceita para essa transferência.
Quando `inbound_auto_accept` não tem uma carteira do catálogo de endereços para corresponder, uma carteira cripto que você registrou nas transações de exatamente um usuário final identifica o titular.
A Didit adiciona essa carteira ao catálogo de endereços do usuário final como sua autodeclaração, verificada, a menos que o modo seja `FULL`. Ela nunca adiciona uma carteira que o catálogo de endereços já lista sob outro nome da mesma chain (`eth` e `ethereum`), incluindo uma registrada como de outro VASP.
As verificações de endereço que outros VASPs fazem antes de enviar (via `GTR`, `Sygna` e `VerifyVASP`) também seguem o modo: em `FULL`, uma carteira que o usuário final apenas declarou não é informada como sua.

### Compartilhamento de dados

`data_sharing_fields` escolhe quais campos a Didit envia à contraparte sobre os seus próprios usuários, separadamente para pessoas físicas e empresas:

```json theme={null}
{
  "data_sharing_fields": {
    "individual": ["name", "wallet_address", "address", "date_of_birth"],
    "company": ["name", "wallet_address", "address"]
  }
}
```

* Pessoas físicas podem compartilhar `name`, `wallet_address`, `address`, `national_id`, `customer_identification`, `date_of_birth` e `place_of_birth`. Empresas usam os cinco primeiros.
* `name` e `wallet_address` são sempre enviados.
* Um tipo de entidade para o qual você nunca fez uma escolha compartilha todos os campos. Uma lista vazia também é uma escolha: ela compartilha apenas o nome e a carteira.
* Um `PUT` faz a mesclagem por tipo de entidade, então enviar `individual` mantém intacta a escolha de `company` armazenada.
* Uma escolha que não consegue cumprir as obrigações do remetente do regime da sua `jurisdiction` (EU TFR ou Recomendação 16 do FATF), incluindo uma lista vazia, é recusada com `400`. Os erros ficam em `data_sharing_fields`, indexados por tipo de entidade.

### Correspondência por campo

`matching_rules` define o rigor com que cada campo dos dados da contraparte é comparado com o que você tem:

```json theme={null}
{
  "matching_rules": {
    "individual": { "name": "DEFAULT", "date_of_birth": "STRICT", "address": "NONE", "account": "STRICT" },
    "company": { "name": "FUZZY", "address": "NONE", "account": "STRICT" }
  }
}
```

Cada valor é `NONE`, `STRICT`, `CONTAINS`, `DEFAULT` ou `FUZZY`.
Padrões: `name` segue `name_matching_strictness`, `date_of_birth` e `address` são `NONE`, e `account` é `STRICT`.
Um campo omitido mantém o seu padrão, e um campo que o tipo de entidade não compara (uma empresa não tem `date_of_birth`) é recusado com `400`.

### Limiares por jurisdição

`threshold_amount` existe porque o escopo do Travel Rule varia conforme o regulador.
A Didit usa `0.00` como padrão (a posição da UE), então toda transferência é trocada, a menos que você aumente o valor deliberadamente:

| Regime | Limiar | Observações |
| - | - | - |
| **UE** - Regulamento de Transferências de Fundos (UE) 2023/1113 | **Sem mínimo** | Toda transferência cripto de CASP para CASP está no escopo. A propriedade de uma carteira autocustodiada deve ser verificada em transferências acima de EUR 1,000. |
| **Recomendação 16 do FATF** (referência global) | USD/EUR 1,000 | Abaixo dele, o FATF permite um conjunto de dados reduzido (nomes e endereços de carteira, sem verificação). |
| **Estados Unidos** - Travel Rule do BSA | USD 3,000 | O limiar de longa data da FinCEN para transferências de fundos, aplicado a moedas virtuais conversíveis. |
| **Reino Unido** | Equivalente a EUR 1,000 | Informações completas acima; conjunto de dados reduzido abaixo (MLRs, Parte 7A). |
| **Singapura** - MAS PSN02 | SGD 1,500 | Requisitos reduzidos abaixo do limiar. |
| **Suíça** - FINMA | Sem mínimo | Informações exigidas para todas as transferências; espera-se prova de propriedade para carteiras autocustodiadas. |

Defina `threshold_amount` com o valor do seu regulador; transferências abaixo dele resultam em `NOT_APPLICABLE` sem trocar nenhum dado de identidade.
Os limiares mudam com o tempo: confirme o valor atual com a sua assessoria jurídica de conformidade em vez de tratar esta tabela como aconselhamento jurídico.

### Modelo de dados IVMS 101

O padrão do setor para os dados trocados no âmbito da Travel Rule é o **IVMS 101** (interVASP Messaging Standard).
`travel_rule_details.originator_data` e `travel_rule_details.beneficiary_data` são payloads de pessoa no estilo IVMS 101. A Didit os encapsula no envelope nativo de cada trilho: o trilho TRP troca blocos `IVMS101` (`ivms101.2023`, informado no campo `ivms_version` da transferência), o trilho Sygna usa sua variante IVMS criptografada com ECIES, e os trilhos `GTR`, `TRUST` e `VERIFYVASP` usam seus próprios envelopes criptografados. Assim, um único formato de payload chega a cada contraparte no formato que o protocolo dela espera.

Ao montar a mensagem IVMS 101, a Didit lê estas chaves de cada payload de pessoa: `first_name` e `last_name` (ou um único `name` ou `full_name`), `date_of_birth`, `place_of_birth`, `residence_country` (ou `country`), `vendor_data` (ou `customer_identification`) e `wallet_address`.

Duas regras práticas:

* **Alfabeto latino.** O IVMS 101 exige valores em alfabeto latino, então translitere os nomes escritos originalmente em outro alfabeto. A [correspondência de nomes](#rigor-da-correspondência-de-nomes) da Didit compara conjuntos de tokens normalizados, então diferenças de ordem e de maiúsculas e minúsculas não fazem uma troca falhar. Alfabetos diferentes nos dois lados, sim.
* **Envie dados que você verificou.** Quando o titular por trás de `vendor_data` é um usuário com uma verificação KYC da Didit aprovada, a Didit transmite a identidade verificada, não os valores que você digitou: consulte [Dados verificados e procedência](#dados-verificados-e-procedência).
  Para qualquer outro titular, a Didit transmite exatamente os `originator_data` que você envia. Por isso, monte-os a partir da identidade que você verificou no onboarding, e não de um campo de formulário não verificado.
  É isso que exige a redação do FATF: "informações do remetente exigidas e **precisas**".
  No trilho `INTERNAL`, a aplicação do beneficiário também recebe o `subject` que você enviou (nome, `vendor_data`, data de nascimento, país e endereço) como a parte contraparte da transação de entrada dela.

#### Dados verificados e procedência

Quando o titular de uma transferência é um dos seus usuários, uma pessoa física com uma verificação KYC aprovada, a Didit monta esse lado da troca a partir dos dados verificados:

* o remetente de uma transferência de saída que você cria com `POST /v3/transactions/`;
* o beneficiário de uma transferência de entrada que você informa com `POST /v3/transactions/`, ou com `POST /v3/travel-rule/inbound/` quando o `holder_vendor_data` da carteira correspondente indica esse usuário.

Em `POST /v3/transactions/`, os dois casos se aplicam a uma transação cuja `transaction_category` é `travel_rule` enquanto a Travel Rule está ativada.

Os nomes, a data e o local de nascimento, o número e o tipo do documento, o endereço e o país de residência (obtido desse endereço) verificados têm precedência sobre os valores que você enviou. Um campo que a verificação não contém mantém o seu valor. O mesmo vale para um endereço completo que você enviou quando o endereço verificado não está completo o suficiente para ser transmitido.

Os `metadata` da transferência, no objeto `travel_rule` incorporado à transação, registram a origem de cada campo e onde os seus valores eram diferentes:

```json theme={null}
{
  "metadata": {
    "originator_provenance": { "name": "verified", "date_of_birth": "verified", "customer_identification": "caller" },
    "originator_verified_differences": {
      "name": { "caller": "Jane Doe", "verified": "Jane Elizabeth Doe" }
    }
  }
}
```

`*_provenance` associa cada campo a `verified` ou `caller`, e `*_verified_differences` lista todos os campos em que você enviou um valor diferente do verificado, sem considerar maiúsculas e minúsculas, espaços nem códigos de país de duas ou três letras. Enquanto os dados de uma transferência de entrada estão [mascarados](#dados-mascarados-da-contraparte), as diferenças ficam de fora. A Didit calcula os dois, então cópias dessas chaves, ou de `name_match`, que você enviar em `travel_rule_details.metadata` são descartadas.

#### Envio direto de IVMS 101

Além dos objetos planos `originator_data` e `beneficiary_data`, `travel_rule_details` (em `POST /v3/transactions/`) e `POST /v3/travel-rule/inbound/` aceitam IVMS 101 nativo:

* um bloco `originator` e um bloco `beneficiary`, com `originatorPersons` ou `beneficiaryPersons` contendo uma `naturalPerson` ou uma `legalPerson`, e `accountNumber`;
* os mesmos blocos dentro de um objeto `ivms101` (ou `IVMS101`);
* uma pessoa IVMS 101, ou um bloco inteiro, como `originator_data` ou `beneficiary_data`.

Cada lado aceita uma pessoa: uma `naturalPerson` ou uma `legalPerson`, o que torna a parte uma empresa. Um `originator_data` ou `beneficiary_data` plano não vazio prevalece sobre um bloco do mesmo lado.

```json theme={null}
{
  "travel_rule_details": {
    "status": "AWAITING_COUNTERPARTY",
    "beneficiary": {
      "beneficiaryPersons": [
        {
          "naturalPerson": {
            "name": { "nameIdentifier": [{ "primaryIdentifier": "Ruiz", "secondaryIdentifier": "Carlos", "nameIdentifierType": "LEGL" }] }
          }
        }
      ],
      "accountNumber": ["0xBeneficiaryWallet01"]
    }
  }
}
```

Um bloco malformado retorna `400` com a chave do seu caminho, por exemplo `{"travel_rule_details": {"originator.originatorPersons": ["must be a non-empty list of originator persons."]}}`. Em `POST /v3/travel-rule/inbound/`, as mesmas chaves ficam no nível superior, sob `ivms101.` quando você usou o objeto envoltório.

#### Dados obrigatórios por regime

Enquanto a Travel Rule está ativada, uma transferência de saída igual ou acima do seu limiar deve conter o que o seu regime exige, ou retorna `400`. Apenas os lados que você enviou são verificados, os dados verificados contam para o remetente, e os erros ficam sob `travel_rule_details.originator_data` ou `travel_rule_details.beneficiary_data`, por exemplo `"EU TFR requires the originator name."` ou `"FATF Recommendation 16 requires the beneficiary wallet address."`:

| Regime | Remetente | Beneficiário |
| - | - | - |
| EU TFR (sua `jurisdiction` é um estado-membro da UE, Islândia, Liechtenstein, Noruega, `EU` ou `EEA`; `EU` é o padrão) | O nome, mais o endereço, o número do documento oficial e o número de identificação do cliente juntos, ou a data e o local de nascimento. Uma empresa não tem a alternativa do nascimento. | Nome e endereço da carteira |
| FATF Recommendation 16 (todas as outras jurisdições, inclusive uma em branco) | O nome, mais um entre o endereço, o número do documento oficial ou o número de identificação do cliente, ou a data e o local de nascimento juntos. Uma empresa não tem a alternativa do nascimento. | Nome e endereço da carteira |

Para o remetente, a verificação lê os campos que a sua aplicação compartilha em [`data_sharing_fields`](#compartilhamento-de-dados), porque são apenas esses que um trilho envia. O beneficiário é verificado tal como você o enviou. Quando a transferência só atende ao regime com um campo que você não compartilha, o `400` indica o requisito do regime e, em seguida, os campos que as suas configurações compartilham.

O número do documento oficial é `national_id` (ou `document_number`), o número de identificação do cliente é `customer_identification` (ou `vendor_data`) e a data de nascimento é `date_of_birth`. Um `beneficiary_data.wallet_address` vazio é preenchido com `counterparty.payment_method.account_id` antes da verificação. Um saque UTXO cuja saída do beneficiário a Didit inferiu a partir de `travel_rule_details.utxo` conta como se contivesse esse dado. Uma transferência Lightning à qual a Travel Rule não se aplica não é verificada.

### Endereços de viagem

Um **endereço de viagem** (travel address) é uma string compacta e codificada que aponta para o endpoint de consulta `TRP` de entrada de um VASP. Ele nunca expõe uma URL bruta nem qualquer endereço de carteira.
Depois que a Travel Rule é ativada, a Didit gera o seu próprio `travel_address` (retornado como somente leitura nas configurações) para que você possa compartilhá-lo com outros VASPs que chegam até você pelo canal `TRP`.
Cada carteira da sua própria agenda de endereços também recebe um `receiving_travel_address` próprio: uma consulta enviada a ele identifica essa carteira, então a Didit não precisa encontrá-la pelo número da conta ou pelo nome do titular.
O host TRP público da Didit ainda não responde a outros VASPs, portanto o recebimento por `TRP` só estará disponível quando isso acontecer: consulte [Redes da Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md).
Quando você souber o endereço de viagem de uma contraparte, armazene-o no [registro da agenda de endereços de carteiras](#catálogo-de-endereços-de-carteiras) de destino para que a Didit encaminhe as transferências desse beneficiário diretamente por `TRP`, em vez de recorrer ao e-mail.
A Didit valida os endereços de viagem que você armazena em um registro da agenda de endereços de carteiras ou envia em `originating_vasp`: cada um deve começar com `ta` e ser decodificado em uma URL de consulta que contenha `t=i`. Por isso, um valor provisório como `ta...` retorna `400`.
Um `beneficiary_data.travel_address` em uma transação não é validado: se ele não puder ser decodificado, o canal `TRP` é ignorado.

A codificação é Base58Check com o prefixo `ta`: o host e o caminho do endpoint (que sempre contém o par de consulta `t=i`), mais um checksum double-SHA-256 de quatro bytes, codificados em base58.
Um endereço real, portanto, tem esta aparência e chega a cerca de 100 caracteres:

```text theme={null}
ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx
```

Quando a Didit valida um endereço de viagem, um valor que não seja um endereço bem formado e com checksum válido retorna `400` com `"Invalid travel address."`.
Use um endereço real obtido na resposta das suas próprias configurações ou fornecido pela própria contraparte.

## Testes sem credenciais de rede

Você não precisa ser membro da GTR, TRUST, VerifyVASP ou Sygna para testar os caminhos que dispensam associação. Você ainda precisa de uma chave de API da Didit para a aplicação em teste.

* **Envio em sandbox:** envie uma transação `travelRule` a partir de uma aplicação de sandbox. Após as verificações de limiar e de carteira autocustodiada, o [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) responde a ela dentro da Didit com o cenário que você escolher pela carteira ou pelo nome do beneficiário: aceitar, recusar, divergência de nome, inacessível, tempo esgotado ou autocustodiada. Nenhuma rede, e-mail ou outro cliente da Didit recebe nada.
* **Recebimento em sandbox:** faça o VASP de teste enviar uma transferência para você com [Trigger Test VASP Inbound Transfer](https://docs.didit.me/pt-br/management-api/travel-rule/trigger-test-vasp-inbound.md) ou registre uma você mesmo com [Register Inbound Travel Rule Transfer](https://docs.didit.me/pt-br/management-api/travel-rule/register-inbound.md). Teste uma carteira desconhecida, uma carteira não verificada, uma divergência no nome do beneficiário e uma carteira verificada e correspondente. Esses testes acionam decisões reais de recebimento sem contatar nenhuma rede.
* **Duas aplicações de produção controladas:** use o canal `INTERNAL` entre duas das suas próprias aplicações de produção (a que recebe pode ser descoberta e comprova o controle da carteira de destino com uma mensagem assinada ou um depósito de teste), ou uma contraparte TRP controlada, para testar uma troca entre duas partes sem credenciais comerciais de rede. Aplicações de produção podem gerar cobranças e notificações normais; use identidades de teste e contrapartes que você controla.

Consulte [Testar a Travel Rule em sandbox](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) para ver todos os cenários e o resultado exato de cada um. Testes bem-sucedidos em sandbox ou de protocolo local não validam as credenciais, a associação nem a interoperabilidade em produção de uma rede comercial. Isso exige um sandbox autorizado da rede ou uma troca controlada em produção com credenciais de associação válidas.

## Envio de uma transferência

Inclua a transferência em [`POST /v3/transactions/`](https://docs.didit.me/pt-br/transaction-monitoring/transactions) definindo `transaction_category` como `travelRule` (ou `travel_rule`) e anexando um objeto `travel_rule_details` (alias: `travelRule`).

O bloco `travel_rule_details` em si é opcional, mas, depois que você o anexa, `travel_rule_details.status` passa a ser obrigatório: um bloco sem ele retorna `400`.
Quando o Travel Rule está **ativado** para a sua aplicação, a Didit ignora o valor de `status` que você envia e conduz a troca por conta própria:

1. Se o valor estiver abaixo do `threshold_amount` configurado, a transferência é resolvida imediatamente como `NOT_APPLICABLE` e nada é negociado.
2. Se o método de pagamento da contraparte declarar o destino como uma carteira autocustodiada (`payment_method.method_type: "unhosted_wallet"`), nenhum trilho é tentado: a transferência vai direto para `UNCONFIRMED_OWNERSHIP` e o widget de propriedade da carteira é gerado automaticamente (veja [Carteiras autocustodiadas declaradas](#carteiras-autocustodiadas-declaradas)).
3. Caso contrário, os trilhos são executados em ordem de prioridade, e o primeiro que conseguir alcançar a contraparte conduz a troca:
   * `INTERNAL` - exatamente um outro cliente da Didit tem uma prova por mensagem assinada ou por depósito de teste para `beneficiary_data.wallet_address`, feita depois da última troca de titular da carteira. A sua própria aplicação nunca conta e, quando o seu usuário final escolheu um membro da rede Didit no [widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md), só a prova desse membro conta. A aplicação desse cliente está em produção (não em sandbox), tem o Travel Rule ativado e `is_discoverable` definido, e é o VASP que você indicou quando envia `counterparty_vasp_lei` ou `counterparty_vasp_name`. Uma carteira apenas autodeclarada, comprovada por captura de tela, não verificada ou apenas listada em um catálogo de endereços nunca recebe nada pelo `INTERNAL`.
   * `TRP` - o ativo da transferência tem um mapeamento de Digital Token Identifier para a rede da transferência (veja [Identificadores de ativos TRP](#identificadores-de-ativos-trp)), e o payload traz `beneficiary_data.travel_address`, a entrada do catálogo de endereços do próprio destino armazena um, ou a contraparte é resolvida no [diretório](#diretório) (por `counterparty_vasp_lei` ou `counterparty_vasp_name`) com um endpoint TRP.
   * `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` - você conectou a sua própria associação a essa rede em **Marketplace**, e a contraparte é resolvida para um ID de rede (campo explícito ou entrada do diretório; veja [Campos de resolução da contraparte](#campos-de-resolução-da-contraparte)).
     A Didit ainda não tem associação de plataforma nessas redes (está em processo de onboarding como provedor), então `disabled_networks` não altera esta etapa hoje.
   * `EMAIL` - `beneficiary_data.counterparty_vasp_email` foi informado, ou `counterparty_vasp_name` é resolvido para uma entrada do diretório com um e-mail de conformidade.
4. Se nenhum trilho conseguir resolver uma contraparte, a Didit executa a cadeia de [descoberta de contraparte](#descoberta-de-contraparte). Com `vasp_attribution_enabled` ativado, isso inclui a [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain): a carteira de destino é associada ao VASP que a detém, o nome atribuído é gravado em `beneficiary_data.counterparty_vasp_name` (quando vazio) e no [diretório](#diretório), e os trilhos são executados novamente uma vez. Assim, uma carteira atribuída a um VASP cuja entrada no diretório traz um endpoint TRP, um ID de rede ou um e-mail de conformidade é roteada nesta segunda passagem.
5. Se a contraparte continuar sem resolução, a transferência passa para `COUNTERPARTY_VASP_NOT_FOUND`. Em transferências de saída, a Didit gera automaticamente o [widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) (quando `auto_wallet_verification` está ativado) para que a transferência ainda possa ser concluída como transferência para carteira autocustodiada, e você pode executar o roteamento novamente mais tarde com `action: "resend"` quando tiver dados melhores da contraparte.

As etapas 1 e 2 acontecem dentro da requisição. As etapas 3 a 5 são executadas logo após a resposta: a transferência retorna `AWAITING_COUNTERPARTY` com `protocol: null`, e cada resultado chega como um webhook [`travel_rule.status.updated`](#webhooks).

### Identificadores de ativos TRP

O `TRP` identifica o ativo transferido pelo seu Digital Token Identifier (DTI) da ISO 24165.
Um DTI identifica um token em uma blockchain, portanto um token multichain tem um DTI por rede.

A Didit envia transferências pelo `TRP` para estes ativos:

| Ativo | Rede | DTI |
| - | - | - |
| `BTC` | Bitcoin | `4H95J0R2X` |
| `ETH` | Ethereum | `X9J9K872S` |
| `USDC` | Ethereum | `CK9PW1MFH` |
| `USDC` | Celo | `2ZTG3NNVB` |
| `USDC` | Base | `CP6817N4B` |
| `USDC` | Optimism | `898NNTPZJ` |
| `USDC` | Arbitrum One | `4ZSZS1F4F` |
| `USDC` | Polygon PoS | `LS71LQK3L` |
| `USDC` | Avalanche C-Chain | `45J6XJX7H` |
| `USDC` | Solana | `5R3XFPZSM` |
| `USDC` | Plume | `N064ZKXDM` |

Os identificadores de `USDC` são os que o emissor do token publica no seu white paper MiCA.

Para um token multichain, a transferência deve indicar a sua rede em `transaction_details.crypto_params.crypto_chain` (por exemplo, `CELO`, `BASE`, `OP`, `ARB` ou `POL`).
Sem uma rede, ou em uma rede sem mapeamento, a transferência não é enviada pelo `TRP` e a Didit tenta os trilhos restantes: primeiro as redes de interoperabilidade, depois o e-mail.

O `USDT` ainda não está mapeado.
Um token sem mapeamento de DTI, como a stablecoin própria de uma empresa, exige que o seu emissor registre um DTI junto à autoridade de registro da ISO 24165, um por token por blockchain.
Depois que os DTIs existirem, entre em contato com o suporte da Didit informando cada DTI, a sua blockchain e as casas decimais do token, e a Didit adiciona o mapeamento.

Consultas `TRP` de entrada que trazem um DTI por cadeia mapeado são registradas com a moeda do token, o valor nas casas decimais do token e a rede.

### Descoberta de contraparte

Uma transferência que traz apenas um endereço de carteira ainda chega à sua contraparte sempre que alguém consegue identificá-la.
Antes de uma transferência de saída ser declarada impossível de rotear, a Didit consulta, nesta ordem, e para na primeira etapa que indicar um VASP com uma rota:

| Etapa | O que faz |
| - | - |
| `internal_address_book` | Outro cliente da Didit comprovou o controle da carteira (uma assinatura ou um depósito de teste), então o trilho `INTERNAL` faz a entrega para ele. Uma entrada não comprovada no catálogo de endereços nunca conta. |
| `wallet_attribution` | A atribuição da carteira por análise de blockchain, associada a um VASP do diretório com uma rota. Um resultado armazenado é reutilizado e cobrado uma única vez. Requer `vasp_attribution_enabled`. |
| `network_lookup` | Uma rede de Travel Rule que responde "quem detém este endereço", quando sua aplicação tem acesso a ela. Hoje, apenas a GTR oferece isso, e a consulta é executada quando o rail GTR envia. Caso contrário, a etapa é registrada como `skipped` com o motivo. |
| `customer_hint` | O nome do VASP, o LEI ou a jurisdição que você enviou em `beneficiary_data`, correspondido a um VASP do diretório com uma rota. Um `travel_address` ou um e-mail de conformidade é alcançado pelo seu próprio rail. |
| `end_user` | Ninguém identificou a contraparte, então o usuário final é consultado. Veja abaixo. |

O campo `discovery` da transferência lista cada etapa executada com seu `outcome` (`match`, `miss` ou `skipped`), um `reason` legível por máquina, o `vasp` e o `rail` encontrados e um registro de data e hora.
Um VASP escolhido por você ou pelo usuário final tem prioridade sobre todas as etapas automáticas: a descoberta nunca o substitui por um palpite próprio.

Quando nenhuma etapa identifica uma contraparte, a transferência passa para `COUNTERPARTY_VASP_NOT_FOUND`, ou para `COUNTERPARTY_VASP_NOT_REACHABLE` quando um VASP foi identificado, mas nenhuma de suas rotas está disponível para sua aplicação.
A transferência passa então a ter um `reason` (`awaiting_end_user`, `no_directory_match`, `directory_match_no_route` ou `picked_member_without_proven_wallet` quando o membro escolhido pelo usuário final não comprovou a carteira) e uma lista de `next_actions`:

| `action` | Significado |
| - | - |
| `select_counterparty_vasp` | O usuário final escolhe o VASP de destino no [widget de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md), ou você mesmo o indica com `{"action": "beneficiary_vasp", "beneficiary_vasp": "<directory VASP id>"}` no [endpoint de transferência](#envio-de-uma-transferência). A transferência é roteada para esse VASP e enviada novamente. |
| `declare_self_hosted` | O usuário final declara a carteira como autocustodiada no mesmo widget. |
| `add_vasp_hint` | Envie um nome de VASP, um LEI ou um `travel_address` em `beneficiary_data` e reenvie. |
| `update_compliance_email` | Informe novamente o e-mail de conformidade da contraparte quando o primeiro tiver sido recusado; veja [Por que uma transferência está travada](#por-que-uma-transferência-fica-travada). |
| `resend` | Executa a descoberta novamente com o que tiver mudado. |

O link do widget é o `url` nas ações que o usuário final executa.
Quando uma ação de propriedade de carteira está pendente, o bloco `action_required` da transação (tipo `wallet_ownership`) traz o mesmo `reason` e as mesmas `next_actions`, de modo que um cliente que já acompanha `action_required` exibe o seletor sem trabalho adicional.

### Campos de resolução da contraparte

Tudo o que a Didit sabe sobre a contraparte vem de `travel_rule_details.beneficiary_data`.
Estes campos orientam a resolução do rail; todos são opcionais:

| Campo | Orienta |
| - | - |
| `wallet_address` | A correspondência no catálogo de endereços `INTERNAL`, a consulta ao catálogo de endereços `TRP` e os fluxos de propriedade de carteira. Quando você o omite, a Didit usa `counterparty.payment_method.account_id`. |
| `chain` | Delimita as duas consultas a catálogos de endereços: uma entrada só corresponde quando seu `chain` é igual a este valor (sem diferenciar maiúsculas de minúsculas) ou quando a entrada não tem `chain`. Quando você o omite, a Didit o preenche a partir de `transaction_details.crypto_params.crypto_chain`, `custom_properties.crypto_chain` ou da moeda da transferência, em maiúsculas, mas apenas quando esse valor é uma blockchain que a Didit reconhece (por exemplo, `ETH`, `BTC`, `SOL`, `TRX`); caso contrário, a transferência fica sem blockchain e corresponde a entradas de qualquer blockchain. Para uma transferência em `USDT` ou `USDC` sem blockchain explícita, a Didit a infere a partir de um hash de transação em `transaction_details.payment_reference_id` (um hash `0x` resulta em `ETH`). |
| `memo` | A tag de destino ou o memo de `wallet_address` em uma rede com memo. Faz parte da carteira sempre que `wallet_address` é correspondido (veja [Redes com memo e tag](#redes-com-memo-e-tag)). Alias: `destinationTag`. |
| `travel_address` | Roteia diretamente pelo `TRP`, o sinal mais forte que você pode enviar. |
| `counterparty_vasp_lei` | Consulta ao diretório por LEI para `TRP`, `GTR`, `TRUST`, `VERIFYVASP` e `SYGNA`. Também é conferido com a identidade informada pelo endpoint TRP: uma divergência, ou uma identidade sem LEI, interrompe a troca como `COUNTERPARTY_VASP_NOT_REACHABLE`. |
| `counterparty_vasp_name` | Consulta ao diretório para `TRP`, `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` e `EMAIL`: o nome exato, o mesmo nome escrito de outra forma (`B.V.` por `BV`, um acento) e, por fim, um alias de uma entrada. É conferido de forma aproximada com a identidade TRP quando ambos estão presentes. |
| `counterparty_vasp_jurisdiction` | Código de país ISO 3166 da entidade receptora quando o VASP indicado é uma marca com várias entidades regulamentadas, ou quando várias entradas do diretório têm o mesmo nome; veja [Marcas e suas entidades](#marcas-e-suas-entidades). |
| `counterparty_gtr_vasp_code` | ID explícito da rede `GTR`, que dispensa o diretório. |
| `counterparty_trust_membership_id` | ID explícito da rede `TRUST`, que dispensa o diretório. |
| `counterparty_verifyvasp_id` | ID explícito da rede `VerifyVASP`, que dispensa o diretório. |
| `counterparty_sygna_vasp_code` | Código de VASP explícito da `Sygna Bridge`, que dispensa o diretório. |
| `counterparty_vasp_email` | Contato de conformidade explícito para o rail `EMAIL`, que dispensa o diretório. |

### Formatos de blockchain

Em uma blockchain baseada em contas (blockchains EVM, Solana, Tron), uma transferência move fundos de um endereço para outro, e a Didit lê as duas carteiras diretamente da transação.
Três outros formatos exigem mais, e o que a Didit resolveu para eles fica na transferência como `chain_details` (vazio, `{}`, em uma blockchain baseada em contas).
`chain_details.originator` e `chain_details.beneficiary` trazem, cada um, o `address`, seu `memo` e a `source` de onde veio, e a correspondência e o roteamento leem as carteiras primeiro a partir daí.

#### Transferências UTXO

Uma transação de Bitcoin, Litecoin, Bitcoin Cash ou Dogecoin gasta entradas de qualquer número de endereços e paga qualquer número de saídas, algumas delas como troco de volta ao remetente.
Envie as entradas e saídas como `travel_rule_details.utxo` (valores na unidade da própria moeda, como strings decimais), e a Didit infere o que você não declarar:

* **Remetente**: `originator_data.wallet_address` quando você o envia; caso contrário, o endereço de entrada que mais contribuiu (`source: largest_input`).
* **Beneficiário**: a carteira declarada; caso contrário, a única saída que não devolve troco a um endereço de entrada (`only_non_change_output`); caso contrário, a única saída que paga o valor da transferência (`amount_match`).

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "btc-withdrawal-0042",
    "transaction_category": "travelRule",
    "transaction_details": {
      "direction": "outbound",
      "amount": "0.25",
      "currency": "BTC",
      "currency_kind": "crypto"
    },
    "subject": { "vendor_data": "user-042", "full_name": "Ana Diaz" },
    "counterparty": { "full_name": "Luis Perez" },
    "travel_rule_details": {
      "status": "AWAITING_COUNTERPARTY",
      "beneficiary_data": { "name": "Luis Perez", "counterparty_vasp_name": "Destination Exchange" },
      "utxo": {
        "inputs": [
          { "address": "bc1qsenderhotwallet01", "amount": "0.30" },
          { "address": "bc1qsendercoldwallet02", "amount": "0.05" }
        ],
        "outputs": [
          { "address": "bc1qbeneficiarydeposit01", "amount": "0.25" },
          { "address": "bc1qsenderhotwallet01", "amount": "0.0999" }
        ]
      }
    }
  }'
```

A transferência passa a conter:

```json theme={null}
{
  "chain_details": {
    "chain": "BTC",
    "shape": "utxo",
    "originator": { "address": "bc1qsenderhotwallet01", "memo": "", "source": "largest_input" },
    "beneficiary": { "address": "bc1qbeneficiarydeposit01", "memo": "", "source": "only_non_change_output" },
    "utxo": {
      "inputs": [
        { "address": "bc1qsenderhotwallet01", "amount": "0.300000000000000000" },
        { "address": "bc1qsendercoldwallet02", "amount": "0.050000000000000000" }
      ],
      "outputs": [
        { "address": "bc1qbeneficiarydeposit01", "amount": "0.250000000000000000" },
        { "address": "bc1qsenderhotwallet01", "amount": "0.099900000000000000" }
      ],
      "change_output_indexes": [1],
      "beneficiary_output_index": 0
    }
  }
}
```

`chain_details.warnings` sinaliza o que não confere: `declared_originator_not_an_input`, `declared_beneficiary_not_an_output`, `beneficiary_output_ambiguous` (nenhuma saída pôde ser distinguida das demais) e `beneficiary_output_amount_differs`.
`utxo` em qualquer outra chain resulta em `400`, e cada lista contém no máximo 1.000 entradas.
Um depósito informado recebe o mesmo objeto `utxo` (consulte [Registro sunrise após o depósito](#registro-sunrise-após-o-depósito)).

#### Redes com memo e tag

Em XRP, Stellar (XLM), EOS, Cosmos (ATOM) e Hedera (HBAR), uma exchange recebe todos os clientes em um único endereço compartilhado e os distingue pela destination tag ou pelo memo.
Por isso, o memo faz parte da carteira: envie-o como `payment_method.memo` no participante, ou como `memo` em `originator_data` / `beneficiary_data` (alias `destinationTag`), e a Didit compara o endereço e o memo em conjunto.

* Uma entrada do catálogo de endereços com memo corresponde apenas às transferências que indicam esse memo. Uma entrada sem memo corresponde ao endereço inteiro. Uma transferência que não indica memo nunca chega a uma entrada que tem memo: em um endereço compartilhado, um depósito sem a sua tag não pertence a ninguém.
* Um X-address de XRP traz a tag embutida: a Didit o divide no endereço clássico e na tag (`source: x_address`), de modo que uma carteira registrada em qualquer um dos formatos corresponde a uma transferência no outro.
* Cada memo em um endereço compartilhado é um método de pagamento próprio na transação.
* O que cada rede aceita: uma destination tag de XRP é um número inteiro de 0 a 4294967295 (um número JSON é aceito); um memo da Stellar tem até 28 bytes de texto, um id de 64 bits ou um hash de 32 bytes em hexadecimal; EOS aceita até 256 bytes, Cosmos até 256 caracteres e Hedera até 100 bytes. Um memo em uma chain que não tem memo (Bitcoin, chains EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, Lightning) resulta em `400`.

#### Lightning

Um pagamento Lightning não tem endereço on-chain do beneficiário: o pagador tem uma solicitação de pagamento.
Em uma transferência de cripto em bitcoin ou Lightning, `payment_method.account_id` pode ser essa solicitação, e a Didit identifica o beneficiário a partir dela sem contatar nenhuma rede:

| O que você envia | Beneficiário |
| - | - |
| Fatura BOLT11 (`lnbc...`) | O nó recebedor, indicado na fatura ou recuperado a partir da sua assinatura. |
| Oferta ou fatura BOLT12 (`lno1...`, `lni1...`) | O nó emissor, a menos que ele se oculte por trás de blinded paths. |
| Lightning Address (`name@domain`) | O próprio endereço. |
| Id do nó | O próprio nó. |
| LNURL (`lnurl1...`, `lnurlp://`) | Nenhum: ele indica um serviço, não um recebedor. |

O recebedor é armazenado como a conta e como `chain_details.beneficiary` (`source: invoice_payee`), na chain `LIGHTNING`, e o conteúdo da solicitação fica em `chain_details.lightning`.
Quando a solicitação não indica nenhum recebedor, uma transferência de saída fica `NOT_APPLICABLE`, com o motivo em `chain_details.not_applicable_reason` e na sua `timeline`: `LIGHTNING_NO_PAYEE_IDENTIFIER`, `LIGHTNING_BOLT12_BLINDED_PAYEE` ou `LIGHTNING_LNURL_NAMES_NO_PAYEE`.
Um valor é interpretado como Lightning apenas em bitcoin, em `LIGHTNING` ou quando nenhuma chain é indicada (uma Lightning Address apenas em bitcoin ou `LIGHTNING`): em qualquer outra chain, ele é um endereço da própria chain.

> [!NOTE]
>
> O rail `INTERNAL` chega a outro cliente da Didit somente por meio de uma carteira que esse cliente comprovou controlar com uma mensagem assinada ou um depósito de teste, e essas comprovações existem hoje para Bitcoin, chains EVM, Solana e Tron.
> Portanto, em redes com memo, Lightning, Litecoin, Bitcoin Cash e Dogecoin, uma transferência nunca chega a outro cliente da Didit pelo `INTERNAL`.
> A correspondência por memo, tag e Lightning continua valendo para o seu próprio catálogo de endereços: transferências de entrada, depósitos informados e consultas `TRP` às suas carteiras.

### Atualização da carteira do remetente

Um saque costuma ser declarado a partir da carteira principal do seu cliente e transmitido a partir de quaisquer endereços que detinham as moedas.
Registre a carteira da qual os fundos realmente saíram com `PATCH /v3/transactions/{transaction_id}/travel-rule/`:

```bash theme={null}
curl -X PATCH "https://verification.didit.me/v3/transactions/$TRANSACTION_ID/travel-rule/" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "action": "update_originator_wallet", "wallet_address": "bc1qsendercoldwallet02" }'
```

* Somente transferências de saída, e nunca uma `CANCELLED` ou `EXPIRED` (`409`).
* Quando as entradas UTXO da transferência são conhecidas, a carteira deve ser uma delas (caso contrário, `400`). Em uma rede com memo, envie também `memo`.
* Isso altera apenas o registro: nada é reenviado à contraparte e o status se mantém. `chain_details.originator` passa a ser a nova carteira com `source: updated`, a `timeline` registra a carteira anterior e a nova, e a contraparte `INTERNAL` da transferência é atualizada da mesma forma.

### Atribuição por análise de blockchain

Quando você informa apenas um endereço de carteira, a Didit ainda consegue descobrir quem está do outro lado.
Se nenhum rail consegue rotear a transferência, a Didit resolve a carteira de destino com base em dados de atribuição de análise de blockchain - a mesma análise que alimenta a [triagem de transações cripto](https://docs.didit.me/pt-br/transaction-monitoring/aml-screening.md) sabe quais carteiras pertencem a quais exchanges e custodiantes.
A atribuição é executada apenas em transferências de saída que contêm tanto uma carteira de destino quanto uma `chain` (consulte [Campos de resolução da contraparte](#campos-de-resolução-da-contraparte)); sem uma chain, ela é ignorada.

Quando a carteira é atribuída a uma entidade conhecida, a Didit:

1. Registra a atribuição na transferência: `beneficiary_data.counterparty_vasp_name` é preenchido (quando você não informou um), e os metadados da transferência contêm um bloco `vasp_attribution` com o nome da entidade, o tipo da entidade, o país e `source: "blockchain_analytics"`.
2. Adiciona a entidade ao [diretório de VASPs](#diretório) (ou a associa à entrada existente), para que a atribuição se mantenha estável entre transferências.
3. Executa os rails novamente uma vez com o nome atribuído - uma entrada do diretório que já tem um endpoint TRP faz a transferência ser roteada imediatamente, em vez de cair em `COUNTERPARTY_VASP_NOT_FOUND`.

A chamada de atribuição também funciona como uma triagem cripto completa: a transação recebe o resultado completo da triagem - pontuação de risco, categoria de risco da carteira, snapshot da rede - exatamente como se o monitoramento cripto tivesse sido executado, e o `custom_values.aml_screening_trigger` da transação é definido como `travel_rule_attribution`, para que você veja que a triagem foi executada porque o roteamento da Travel Rule a exigiu.
Quando o monitoramento cripto já fez a triagem da mesma carteira nesta transação, o resultado armazenado é reutilizado - sem uma segunda chamada de análise e sem uma segunda cobrança.
A atribuição nunca bloqueia a criação da transação: se a consulta de análise falhar ou o seu saldo não for suficiente para cobri-la, a transferência simplesmente segue para `COUNTERPARTY_VASP_NOT_FOUND` e nada é cobrado pela tentativa.
Em `action: "resend"`, uma atribuição registrada anteriormente é reutilizada em vez de ser consultada novamente.

Desative a etapa inteira com `vasp_attribution_enabled: false` nas [configurações](#configuração).
Consulte [Preços](#preços) para saber como a chamada de atribuição é cobrada.

Quando a Travel Rule está **desativada**, `travel_rule_details` (incluindo um `status` informado por quem faz a chamada, legado ou atual) continua sendo registrado na transação, mas de forma passiva: nenhum rail é acionado.
Use isso para preencher retroativamente dados de conformidade que você já acompanhava com o seu próprio processo.
Uma transferência de saída passiva não inicia nenhuma troca, por isso é cobrada como Transaction Screening, e não na [linha da Travel Rule](#preços).

Com a Travel Rule ativada, esta requisição é roteada pelo rail `EMAIL`, porque informa o e-mail de conformidade da contraparte e nenhum rail anterior consegue alcançar o beneficiário:

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "trv-2026-07-05-001",
    "transaction_category": "travelRule",
    "transaction_details": {
      "direction": "outbound",
      "action_type": "transfer",
      "amount": "0.25",
      "currency": "ETH",
      "currency_kind": "crypto"
    },
    "subject": {
      "entity_type": "individual",
      "vendor_data": "user-042",
      "full_name": "Jane Doe"
    },
    "travel_rule_details": {
      "status": "AWAITING_COUNTERPARTY",
      "originator_data": {
        "first_name": "Jane",
        "last_name": "Doe",
        "date_of_birth": "1990-04-12",
        "residence_country": "ES",
        "customer_identification": "user-042",
        "wallet_address": "0x135908330861442a814796ae99feac507925782a"
      },
      "beneficiary_data": {
        "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
        "name": "Ana Diaz",
        "counterparty_vasp_email": "compliance@bene-casp.example"
      }
    }
  }'
```

A resposta, reduzida aos campos que importam aqui:

```json theme={null}
{
  "uuid": "22222222-3333-4444-5555-666666666666",
  "txn_id": "trv-2026-07-05-001",
  "transaction_type": "travelRule",
  "direction": "OUTBOUND",
  "status": "APPROVED",
  "amount": "0.25",
  "currency": "ETH",
  "currency_type": "crypto",
  "travel_rule": {
    "uuid": "33333333-4444-5555-6666-777777777777",
    "status": "AWAITING_COUNTERPARTY",
    "protocol": null,
    "required": true,
    "obligations_count": 0,
    "originator_data": {
      "first_name": "Jane",
      "last_name": "Doe",
      "date_of_birth": "1990-04-12",
      "residence_country": "ES",
      "customer_identification": "user-042",
      "wallet_address": "0x135908330861442a814796ae99feac507925782a"
    },
    "beneficiary_data": {
      "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
      "name": "Ana Diaz",
      "counterparty_vasp_email": "compliance@bene-casp.example",
      "chain": "ETH"
    },
    "metadata": {
      "compliance_email_source": "caller_supplied"
    }
  },
  "action_required": null
}
```

* `originator_data` é o que você enviou, porque o titular do exemplo não tem uma verificação KYC aprovada. Para um usuário verificado, a Didit o monta a partir dos dados verificados (consulte [Dados verificados e procedência](#dados-verificados-e-procedência)).
  O rail `EMAIL` mostra ao destinatário apenas os campos do remetente que você compartilha em [`data_sharing_fields`](#compartilhamento-de-dados).
* `beneficiary_data.chain` é `ETH` porque a requisição não informou nenhuma chain, então a Didit a obteve a partir da moeda.
* `status` é `APPROVED` porque nenhuma regra atuou sobre a transação. Suas próprias regras podem definir outro status.
* O contato de conformidade recebe o link de retirada. A transferência é concluída, falha na correspondência de nome ou é recusada quando ele responde, ou expira se ele não responder (consulte [Retirada por e-mail](#coleta-por-e-mail-para-contrapartes-inacessíveis)).

`protocol` ainda é `null` porque o rail é escolhido depois da resposta (por exemplo, `EMAIL` quando você informou `counterparty_vasp_email`). [Obter transação](https://docs.didit.me/pt-br/management-api/transactions/get.md) o mostra depois de escolhido, e todo webhook `travel_rule.status.updated` posterior o traz em `rail`.
Se a carteira do beneficiário pertencer a outro cliente da Didit que comprovou ter controle sobre ela, o rail `INTERNAL` conclui toda a troca logo após a resposta, e esse webhook já informa `COMPLETED` (ou `COUNTERPARTY_MISMATCHED_DATA`). Quando o nome não corresponde, sua transferência fica em `COUNTERPARTY_MISMATCHED_DATA` e o outro cliente não recebe nada.
Sem `counterparty_vasp_email`, e quando nem os rails nem a [atribuição](#atribuição-por-análise-de-blockchain) conseguem alcançar o beneficiário, a transferência termina depois em `COUNTERPARTY_VASP_NOT_FOUND`, com uma ação `wallet_ownership` na transação.

> [!NOTE]
>
> O objeto `travel_rule` incorporado à transação traz os campos próprios da transferência (`uuid`, `status`, `protocol`, `required`, `obligations_count`, `originator_data`, `beneficiary_data`, `metadata`), o que a Didit resolveu e comparou (`chain_details`, `name_match`, `data_match`, `mismatched_fields` e os campos de [mascaramento](#dados-mascarados-da-contraparte) `data_masked` e `data_unmasked`) e os campos que indicam em que ponto ela está: `direction`, `rail`, `counterparty_vasp`, `delivery`, `discovery`, `reason` e `next_actions` (consulte [Por que uma transferência fica travada](#por-que-uma-transferência-fica-travada)).
> Cada linha de [`GET /v3/transactions/`](https://docs.didit.me/pt-br/management-api/transactions/list) traz o mesmo bloco, ou `null` para uma transação sem transferência.
> Os endpoints dedicados a transferências descritos abaixo também retornam esses campos, além de `ivms_version`, `ownership_confirmed`, `deadline_at`, `timeline` e `created_at`, mas não `obligations_count` nem `metadata`.

Para encerrar uma transferência de saída `COMPLETED` depois de transmiti-la on-chain:

```bash theme={null}
curl -X PATCH https://verification.didit.me/v3/transactions/22222222-3333-4444-5555-666666666666/travel-rule/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"payment_txn_id": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"}'
```

Isso exige que a transferência seja uma transferência de **saída** no status `COMPLETED`; caso contrário, a API retorna `409`.
Em caso de sucesso, tanto a transferência de saída quanto a sua contraparte no rail `INTERNAL` passam para `FINISHED`, e o `payment_txn_id` da transação recebe o hash que você informou.
No rail `TRP`, a Didit também envia o hash para o callback de confirmação da contraparte.

Para cancelar uma transferência que ainda não chegou a um estado final, envie `{"action": "cancel"}` para o mesmo endpoint.
A contraparte no rail `INTERNAL` também é cancelada e, no rail `TRP`, depois que a contraparte aprova a consulta, a Didit envia o cancelamento para o callback de confirmação dela.
Uma transferência que já está em `FINISHED`, `CANCELLED` ou `EXPIRED` retorna `409`.
Uma requisição sem `payment_txn_id` e sem uma `action` compatível retorna `400`.

Em uma transferência que passou por `GTR`, `VERIFYVASP` ou `SYGNA`, a Didit informa o hash on-chain (ou o cancelamento) à rede depois da resposta, com as [mesmas novas tentativas](#entrega-e-novas-tentativas). O `delivery` da resposta mostra essa mensagem.

Para tentar novamente uma transferência de saída que não conseguiu alcançar a contraparte, ou seja, uma que esteja atualmente em `COUNTERPARTY_VASP_NOT_FOUND`, `COUNTERPARTY_VASP_NOT_REACHABLE` ou `NOT_ENOUGH_COUNTERPARTY_DATA`, primeiro melhore os dados da contraparte. Por exemplo, adicione um `travel_address` à entrada da carteira de destino, adicione um [contato](#contatos) à entrada da contraparte no diretório ou catalogue o VASP no [diretório](#diretório).
Em seguida, envie `{"action": "resend"}` para o mesmo endpoint.
A Didit reinicia o prazo de confirmação e coloca a sequência de roteamento novamente na fila desde o início, usando os dados armazenados na transferência: a resposta mostra a transferência de volta em `AWAITING_COUNTERPARTY` (com `resend queued` no seu `timeline`), e o resultado chega como um webhook `travel_rule.status.updated`.
Um reenvio feito enquanto uma tentativa anterior ainda está em andamento é enviado assim que essa tentativa termina.
Qualquer outro status, ou uma transferência de entrada, retorna `409`.

```bash theme={null}
curl -X PATCH https://verification.didit.me/v3/transactions/22222222-3333-4444-5555-666666666666/travel-rule/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "resend"}'
```

Para indicar você mesmo a contraparte quando a [descoberta](#descoberta-de-contraparte) não conseguiu, envie `{"action": "beneficiary_vasp", "beneficiary_vasp": "<directory VASP id>"}` (o `id` de `GET /v3/travel-rule/vasps/`).
A transferência é roteada para esse VASP e enviada novamente.
Somente uma transferência de saída em `COUNTERPARTY_VASP_NOT_FOUND`, `COUNTERPARTY_VASP_NOT_REACHABLE` ou `NOT_ENOUGH_COUNTERPARTY_DATA` aceita essa ação. Qualquer outro status retorna `409`, e um id desconhecido retorna `404`.

### Por que uma transferência fica travada

Uma transferência em `COUNTERPARTY_VASP_NOT_FOUND` ou `COUNTERPARTY_VASP_NOT_REACHABLE` informa por que está travada e o que a faz avançar, em toda leitura da sua transação.
O bloco `travel_rule` de [`GET /v3/transactions/{transaction_id}/`](https://docs.didit.me/pt-br/management-api/transactions/get), do `201` de [`POST /v3/transactions/`](https://docs.didit.me/pt-br/management-api/transactions/create) e de cada linha de [`GET /v3/transactions/`](https://docs.didit.me/pt-br/management-api/transactions/list) traz essa informação, assim como o objeto de transferência com que o [endpoint de transferência](https://docs.didit.me/pt-br/management-api/travel-rule/update-transfer.md) responde:

* `reason` é a causa legível por máquina, `""` em qualquer outro status.
* `next_actions` lista o que faz a transferência avançar, `[]` em qualquer outro status.
* `delivery` é a mensagem mais recente que a transferência deve entregar à outra parte: `kind`, `status` (`QUEUED`, `SENDING`, `RETRYING`, `DELIVERED` ou `FAILED`), `rail`, `attempts`, `last_error`, `next_attempt_at` e `delivered_at`, ou `null` quando não houve nenhuma a entregar.
* `discovery` mostra onde a Didit procurou a contraparte, com uma entrada por etapa executada: `step`, `outcome` (`match`, `miss` ou `skipped`), `reason`, `vasp`, `rail` e `at`.

`email_undeliverable` e `delivery_failed` resultam de uma entrega com falha e aparecem apenas em `COUNTERPARTY_VASP_NOT_REACHABLE`.
Uma entrega com falha define o `reason` primeiro, de modo que uma contraparte que a Didit encontrou nunca é informada como uma que ela não conseguiu encontrar.
Os outros quatro vêm do rastro de descoberta, em qualquer um dos dois status.

| `reason` | O que aconteceu | `next_actions` |
| - | - | - |
| `email_undeliverable` | O provedor de e-mail recusou o e-mail de conformidade e não resta nenhum endereço para tentar: no envio, em um lembrete ou como um bounce permanente informado depois. | `update_compliance_email`, depois `resend` |
| `delivery_failed` | O rail que fazia a entrega falhou de forma definitiva: um rail de rede recusou a mensagem ou esgotou as novas tentativas, um host de identidade `TRP` não respondeu ou o host `TRP` da contraparte não aceitou a consulta. | `resend` |
| `awaiting_end_user` | Nenhuma etapa de descoberta identificou uma contraparte que a Didit consiga alcançar, então o usuário final é solicitado a indicá-la. | `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint`, `resend` |
| `directory_match_no_route` | Uma etapa identificou uma entrada do [diretório](#diretório), mas essa entrada não tem nenhuma rota que a Didit possa usar para você. | Igual a `awaiting_end_user` |
| `picked_member_without_proven_wallet` | O usuário final escolheu outro cliente da Didit como contraparte, mas esse cliente não comprovou o controle da carteira. | Igual a `awaiting_end_user` |
| `no_directory_match` | O rastro de descoberta não indica nenhum outro motivo. | Igual a `awaiting_end_user` |

| Próxima ação | O que fazer |
| - | - |
| `update_compliance_email` | Informe novamente o e-mail de conformidade da contraparte, com `{"action": "update_compliance_email", "compliance_email": "..."}` no endpoint da transferência. |
| `resend` | Execute o roteamento novamente com `{"action": "resend"}` depois que algo mudar. |
| `select_counterparty_vasp` | O usuário final escolhe o VASP de destino no [widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md). `url` é o link do widget enquanto a transferência tiver uma sessão de widget aberta. |
| `declare_self_hosted` | O usuário final declara a carteira como autocustodiada no widget, na mesma `url`. |
| `add_vasp_hint` | Informe à Didit quem é a contraparte, com um nome de VASP, LEI ou travel address (por exemplo, um `travel_address` na [entrada do catálogo de endereços](#catálogo-de-endereços-de-carteiras) da carteira de destino), depois reenvie. |

Um reenvio faz a transferência avançar, então o `reason` dela é limpo.
A entrada da linha do tempo de uma transição causada por uma entrega com falha traz o mesmo valor em `reason`.

Se o provedor de e-mail recusar o e-mail de conformidade da [transferência de exemplo acima](#envio-de-uma-transferência), o bloco `travel_rule` da transação fica assim, de forma resumida:

```json theme={null}
{
  "uuid": "33333333-4444-5555-6666-777777777777",
  "status": "COUNTERPARTY_VASP_NOT_REACHABLE",
  "protocol": "EMAIL",
  "direction": "OUTBOUND",
  "rail": "EMAIL",
  "counterparty_vasp": null,
  "delivery": {
    "kind": "SEND",
    "status": "FAILED",
    "rail": "EMAIL",
    "attempts": 1,
    "last_error": "email undeliverable",
    "next_attempt_at": null,
    "delivered_at": null
  },
  "reason": "email_undeliverable",
  "next_actions": [
    { "action": "update_compliance_email" },
    { "action": "resend" }
  ]
}
```

Aqui `delivery` coincide com `reason`, porque o próprio envio foi recusado.
Uma recusa em um lembrete, ou um bounce informado depois, mantém `delivery.status` em `DELIVERED`: o primeiro e-mail de fato foi enviado.
Leia `reason`, não `delivery`, para saber por que uma transferência está travada.

Para corrigir, informe novamente o e-mail de conformidade da contraparte e depois reenvie:

```bash theme={null}
curl -X PATCH https://verification.didit.me/v3/transactions/22222222-3333-4444-5555-666666666666/travel-rule/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "update_compliance_email", "compliance_email": "desk@bene-casp.example"}'

curl -X PATCH https://verification.didit.me/v3/transactions/22222222-3333-4444-5555-666666666666/travel-rule/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "resend"}'
```

`update_compliance_email` mantém o endereço como `beneficiary_data.counterparty_vasp_email` desta transferência: ele pertence somente a esta transferência e não entra em nenhuma entrada do diretório nem em nenhuma lista de contatos.
O status não muda, a linha do tempo ganha `compliance email updated` e a transferência mantém `reason: email_undeliverable` até que o reenvio envie a requisição para o novo endereço.
Somente uma transferência de saída em `COUNTERPARTY_VASP_NOT_FOUND`, `COUNTERPARTY_VASP_NOT_REACHABLE` ou `NOT_ENOUGH_COUNTERPARTY_DATA` aceita essa ação; qualquer outra transferência responde `409`, e um `compliance_email` ausente ou malformado responde `400`.

### Carteiras autocustodiadas declaradas

Quando seu cliente informar que o destino é a própria carteira autocustodiada (não hospedada), declare isso na transação em vez de deixar o roteamento descobrir que não há nenhum VASP por trás dela: defina o tipo de método de pagamento da contraparte como `unhosted_wallet`.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "trv-2026-07-07-002",
    "transaction_category": "travelRule",
    "transaction_details": {
      "direction": "outbound",
      "action_type": "transfer",
      "amount": "0.25",
      "currency": "ETH",
      "currency_kind": "crypto"
    },
    "subject": {
      "entity_type": "individual",
      "vendor_data": "user-042",
      "full_name": "Jane Doe"
    },
    "counterparty": {
      "entity_type": "external",
      "full_name": "Jane Doe",
      "payment_method": {
        "method_type": "unhosted_wallet",
        "account_id": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9"
      }
    },
    "travel_rule_details": {
      "status": "AWAITING_COUNTERPARTY",
      "beneficiary_data": {
        "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
        "name": "Jane Doe"
      }
    }
  }'
```

A declaração ignora o roteamento por completo:

* Nenhum rail é tentado (não há VASP de contraparte com quem trocar dados) e a transferência é criada diretamente em `UNCONFIRMED_OWNERSHIP`.
* Quando `auto_wallet_verification` está ativado (o padrão), a Didit gera automaticamente uma sessão do [widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) vinculada à transação e a retorna no bloco `action_required` da transação; os SDKs a abrem automaticamente no [envio pelo lado do cliente](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md).
* Assim que o cliente comprova o controle da carteira, a transferência executa a correspondência do nome do beneficiário e avança para `COMPLETED` (ou `COUNTERPARTY_MISMATCHED_DATA` se a correspondência falhar).

Esta é a obrigação do EU TFR para carteiras autocustodiadas em forma de API: verificar a propriedade da carteira não hospedada em vez de trocar dados com um VASP de contraparte.
A declaração é lida do método de pagamento no lado de **destino** de uma transferência de saída e no lado de **origem** de uma transferência de entrada; em ambos os casos, o participante contraparte.
Uma transferência declarada como não hospedada já está em seu caminho final sem rail, então `UNCONFIRMED_OWNERSHIP` não é um estado que permite reenvio: conclua a comprovação de propriedade (ou cancele) em vez de chamar `action: "resend"`.

## Recebimento

### Confirmação de propriedade da carteira

Uma transferência fica em `UNCONFIRMED_OWNERSHIP` em dois casos:

* Uma transferência de entrada corresponde a uma entrada do [catálogo de endereços](#catálogo-de-endereços-de-carteiras) cuja propriedade ainda não foi verificada.
* A carteira da contraparte foi declarada autocustodiada (`counterparty.payment_method.method_type: "unhosted_wallet"`), em um saque de saída ou em um depósito de entrada. Consulte [Carteiras autocustodiadas declaradas](#carteiras-autocustodiadas-declaradas).

Sua aplicação confirma ou recusa a transferência:

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/{transaction_uuid}/travel-rule/ownership/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirmed": true}'
```

O corpo aceita `confirmed` (obrigatório, booleano) e um `wallet_address` opcional.

O endpoint aceita uma transferência em qualquer um destes estados e retorna `409` com `{"detail": "Transfer is not awaiting ownership confirmation."}` para qualquer outro:

* `UNCONFIRMED_OWNERSHIP`, em qualquer direção.
* `ON_HOLD` em uma transferência de entrada.
* `UNCONFIRMED_OWNERSHIP`, `ON_HOLD` ou `COUNTERPARTY_MISMATCHED_DATA` em uma transferência `TRP` de entrada, para que um responsável por conformidade possa resolver manualmente uma consulta da contraparte.

Em uma transferência que a própria Didit criou (trilho `INTERNAL`, registro sunrise ou carteira autocustodiada declarada):

* `confirmed: true` marca a entrada correspondente do catálogo de endereços de carteiras como verificada quanto à propriedade e, em seguida, executa a correspondência de nome com o `holder_name` dessa entrada: `COMPLETED` se ela for aprovada, `COUNTERPARTY_MISMATCHED_DATA` se não for.
  A contraparte no trilho `INTERNAL`, quando existe, recebe o mesmo resultado.
  Para uma carteira autocustodiada declarada, `confirmed: true` registra que seu cliente verificou quem controla a carteira da contraparte e conclui a transferência (`COMPLETED`), seja de saída ou de entrada.
  Uma transferência de entrada cujo depósito já foi liquidado passa então diretamente para `FINISHED`.
* `confirmed: false` move os dois lados da transferência para `COUNTERPARTY_VASP_GENERAL_DECLINE`.
* A entrada correspondente é buscada no seu próprio catálogo de endereços apenas pelo endereço da carteira, sem considerar a blockchain.
  Resolver uma transferência de entrada em `ON_HOLD` sem entrada correspondente cria a entrada a partir do `beneficiary_data.wallet_address` da transferência e a marca como verificada.
  Uma carteira autocustodiada declarada é a exceção: a carteira é registrada no seu catálogo de endereços como verificada quanto à propriedade, conforme descrito abaixo.
  Em todos os outros casos, uma entrada inexistente retorna `409` com `{"detail": "wallet address entry no longer available"}`, que também é o que uma entrada excluída retorna.

Em uma transferência `TRP` de entrada, a mesma chamada responde à consulta da contraparte:

* `confirmed: true` exige um endereço de pagamento a ser retornado, obtido do `wallet_address` da requisição, depois da entrada correspondente e depois de `beneficiary_data.wallet_address`.
  Sem nenhum dos três, a requisição retorna `400` com `{"wallet_address": ["wallet_address is required to approve."]}`.
  A Didit cria ou verifica a entrada, envia o callback de resolução da consulta à contraparte, define `ownership_confirmed` e move a transferência para `COMPLETED`.
* `confirmed: false` envia uma resolução de recusa e move a transferência para `COUNTERPARTY_VASP_GENERAL_DECLINE`.
* Se o endpoint de callback da contraparte não puder ser alcançado, a requisição retorna `502` e a transferência mantém seu status atual.
  Em uma aprovação, a entrada do catálogo de endereços de carteiras ainda é criada ou marcada como verificada.

Para uma carteira autocustodiada declarada, a carteira que você verifica é a da contraparte: o destino de um saque de saída ou a origem (a carteira do remetente) de um depósito de entrada.
A Didit a adiciona ao catálogo de endereços de carteiras como verificada quanto à propriedade, sob o nome da contraparte, de modo que a carteira é comparada com o nome da contraparte (o remetente, no caso de um depósito).
Se o catálogo de endereços já contiver essa carteira sob um nome de titular diferente, a transferência passa para `COUNTERPARTY_MISMATCHED_DATA`.

Se a transferência não indicar nenhuma carteira da contraparte, informe `wallet_address` no corpo da requisição.
Quando nem a transferência nem a requisição fornecem um endereço de carteira, a requisição é rejeitada com `400`.

```json theme={null}
{"confirmed": true, "wallet_address": "0xCounterpartyWallet01"}
```

* Uma transferência de rede já respondida pela própria rede (uma transferência VerifyVASP, ou uma transferência GTR ou Sygna Bridge já decidida) retorna `409` (consulte [Transferências de uma rede](#transferências-de-uma-rede)).

A resposta é o objeto de transferência mais completo descrito acima.
Uma nova transferência `INTERNAL` nunca fica aguardando aqui: ela só chega a um cliente que já comprovou a carteira. Uma transferência `INTERNAL` mais antiga, ainda aguardando desde antes dessa regra, mantém os dados do remetente ocultos até que você comprove o controle da carteira (uma mensagem assinada ou um depósito de teste), e confirmá-la retorna `409` até que você o faça. Recusá-la continua funcionando.
Quando a contraparte responde que a carteira é autocustodiada (hoje, o [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) dá essa resposta no sandbox), confirmar adiciona a carteira ao seu catálogo de endereços sob o nome do beneficiário e executa a correspondência de nome: uma correspondência conclui a transferência e marca a carteira como verificada.

### Transferências de uma rede

A Didit também pode receber transferências Travel Rule que uma contraparte envia por `GTR`, `VERIFYVASP` ou `SYGNA`.
O recebimento é ativado pela Didit para cada rede separadamente, e **nenhuma está ativada hoje**: ele também exige que cada rede registre os endpoints da Didit, e a Didit ainda não é membro dessas redes.
Transferências `TRUST` não podem ser recebidas.

Depois que uma rede é ativada, uma mensagem entregue por ela é tratada assim:

* **Roteamento.** A mensagem chega à sua aplicação quando indica o código de participante da sua própria associação conectada a essa rede. Uma mensagem endereçada à associação da própria Didit só chega até você quando você é o único cliente da Didit em produção que comprovou o controle da carteira do beneficiário. Qualquer outra é recusada, para que nenhum cliente jamais receba a transferência de outro cliente.
* **Decisão.** A Didit cria a transferência de entrada na sua aplicação e a decide como uma [consulta TRP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-interoperability.md#endpoints-trp): correspondência de carteira, propriedade, correspondência de nome e `inbound_auto_accept`.
* **Uma única vez.** As redes reenviam uma mensagem até que ela seja respondida. Uma repetição recebe a mesma resposta que a primeira cópia recebeu, e nada é criado ou decidido duas vezes.
* **Sua revisão, por `GTR` e `SYGNA`.** Uma transferência que aguarda por você (`UNCONFIRMED_OWNERSHIP`, `ON_HOLD` ou `COUNTERPARTY_MISMATCHED_DATA`) é decidida com [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira): `confirmed: true` a aprova (informe `wallet_address` quando a transferência não indicar nenhum) e `confirmed: false` a recusa. A Didit responde à rede depois da resposta, com as [mesmas novas tentativas](#entrega-e-novas-tentativas). Uma transferência que já foi respondida retorna `409`.
* **Sem resposta posterior por `VERIFYVASP`.** A VerifyVASP recebe a resposta no momento em que pergunta, então uma transferência que precisaria da sua revisão é recusada imediatamente e não pode ser decidida depois (`409`).

### Dados mascarados da contraparte

Até que a propriedade da carteira seja confirmada, os dados pessoais da contraparte em uma transferência recebida vêm mascarados, em vez de omitidos.
A primeira letra de cada palavra é mantida, e a carteira, a chain e o roteamento do VASP continuam legíveis.
`data_masked` é `true`, e a parte contraparte no detalhe da transação, na lista e na exportação CSV é mascarada da mesma forma.

Assim que a propriedade é confirmada, os valores reais aparecem e `data_unmasked` registra a entrada de auditoria:

```json theme={null}
{
  "data_masked": false,
  "data_unmasked": { "at": "2026-10-17T10:00:00Z", "reason": "wallet_proof", "actor": "" }
}
```

`reason` é `ownership_confirmed`, `wallet_proof`, `address_book_match`, `own_verified_wallet`, `inquiry_approved` (você aprovou uma consulta `TRP` ou uma mensagem `GTR` ou `Sygna`), `known_payment_method` (a carteira do usuário final nos seus próprios registros respondeu) ou `travel_address` (o travel address por carteira identificou a carteira).
Uma transferência recebida `INTERNAL` traz `data_unmasked` com `reason: wallet_proof` desde o momento em que é criada, porque só um destinatário que comprovou a carteira recebe uma.
`actor` é o e-mail do usuário do console ou o rótulo da chave de API, e fica em branco para uma decisão automática.
O relatório **Registro de transferências da Travel Rule** (CSV e PDF) mascara os nomes de uma transferência recebida da mesma forma até que a propriedade seja confirmada. Os relatórios que você envia a um regulador, como o XML do goAML e o PDF do relatório regulatório, trazem os dados reais da contraparte.

### Retorno sobre divergências

Uma transferência `COUNTERPARTY_MISMATCHED_DATA` agora indica os campos que divergem.
`data_match` contém a comparação e `mismatched_fields` lista os campos.
Ambos trazem apenas nomes de campos e resultados, nunca valores, por isso continuam legíveis enquanto os dados estão mascarados:

```json theme={null}
{
  "status": "COUNTERPARTY_MISMATCHED_DATA",
  "mismatched_fields": ["date_of_birth"],
  "data_match": {
    "matched": false,
    "mismatched_fields": ["date_of_birth"],
    "fields": {
      "name": { "result": "matched", "strictness": "DEFAULT" },
      "date_of_birth": { "result": "mismatched", "strictness": "STRICT" },
      "address": { "result": "not_compared", "strictness": "NONE" },
      "account": { "result": "matched", "strictness": "STRICT" }
    }
  }
}
```

A entrada da linha do tempo indica os campos, por exemplo "beneficiary date of birth does not match wallet holder".
Uma rejeição `TRP` após uma divergência informa ao VASP remetente quais campos divergem, por exemplo "Beneficiary data does not match the wallet holder: name".
O que o outro VASP fica sabendo é limitado de propósito: enquanto o nome estiver errado, o nome é o único campo informado (`mismatched_fields: ["name"]`, todos os outros campos `not_compared`), e, assim que o nome corresponde, todo campo que diverge é indicado. Isso se aplica ao lado do remetente de uma troca `INTERNAL` e a uma rejeição `TRP`.
Um nome ausente nos dois lados aparece como `not_compared` e não é uma divergência, e um país corresponde pelo que ele designa, então `ES` e `ESP` coincidem.

#### Pontuação de correspondência de nomes

Toda transferência cujo nome foi comparado traz `name_match`, e a entrada da linha do tempo que decidiu isso traz o mesmo objeto ao lado do seu `detail`:

```json theme={null}
{
  "name_match": {
    "score": 90,
    "matched": false,
    "method": "sequence_ratio",
    "strictness": "FUZZY",
    "compared_with": "wallet_holder",
    "transfer_name": "Ana Diaz",
    "compared_name": "Ana Diaz Garcia",
    "matched_names": ["Ana", "Diaz"],
    "mismatched_names": ["Garcia"]
  }
}
```

* `score` é a similaridade entre os dois nomes completos, de 0 a 100, e `0` quando algum deles está em branco. `matched` é o resultado no nível de `strictness`, então os dois podem discordar: `FUZZY` decide pela própria razão de similaridade de `0.85`.
* `matched_names` são as palavras do nome da transferência encontradas no outro nome; `mismatched_names` são as palavras que um dos lados tem e o outro não.
* `method` é `none`, `exact_token`, `token_subset`, `token_containment` ou `sequence_ratio`, para `NONE`, `STRICT`, `DEFAULT`, `CONTAINS` e `FUZZY`.
* `compared_with` é `wallet_holder` (o titular registrado para a carteira) ou `counterparty_vasp` (o nome que a contraparte respondeu na página de resposta por e-mail, ou a resposta do Didit Test VASP).
* O resultado da transferência segue `data_match`, que compara todos os campos, então uma transferência pode ser `COUNTERPARTY_MISMATCHED_DATA` enquanto `name_match.matched` é `true`.
* `name_match` está no objeto de transferência que os endpoints da Travel Rule retornam e no `travel_rule` incorporado da transação, e é `null` até que um nome seja comparado. A lista de transferências e os webhooks não o incluem.
* Os nomes ficam ocultos enquanto as partes estão [mascaradas](#dados-mascarados-da-contraparte) e na cópia do outro cliente de uma troca `INTERNAL`.

### Mensagens e solicitações de documentos

Dois VASPs podem resolver uma transferência contestada dentro da Didit, em vez de por e-mail.
`GET` e `POST /v3/transactions/{transaction_id}/travel-rule/messages/` listam e enviam mensagens em uma transferência:

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/{transaction_uuid}/travel-rule/messages/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind": "DOCUMENT_REQUEST", "body": "Please confirm the beneficiary date of birth.", "requested_documents": ["Proof of address"]}'
```

* `kind` é `MESSAGE` (padrão) ou `DOCUMENT_REQUEST`. Uma solicitação de documento precisa de pelo menos uma entrada em `requested_documents` (até 10); uma mensagem precisa de um `body` (até 5000 caracteres) ou de um arquivo.
* `reply_to` indica uma mensagem anterior da mesma transferência. Uma resposta do outro lado que traz um documento atende à solicitação de documento que ela responde, e `fulfilled_at` é preenchido nela. Sua própria resposta nunca atende à sua própria solicitação.
* Envie multipart com `files` para anexar até 5 arquivos de 10 MB cada, em PDF, PNG, JPEG ou WebP. A Didit verifica o conteúdo de cada arquivo, não apenas o tipo declarado, e qualquer outro arquivo retorna `400` em `files` ("Attach PDF, PNG, JPEG or WebP files only.").
* Uma transferência comporta até 100 mensagens, das quais até 20 podem ter anexos (cada uma com até 5 arquivos), contando os dois lados; além de qualquer um desses limites, a requisição retorna `400`. Os anexos de mensagens não contam para os documentos da própria transação.
* As mensagens funcionam nos rails `INTERNAL` e `EMAIL`. No `INTERNAL`, o outro cliente da Didit vê a mensagem no seu lado do par. No `EMAIL`, a contraparte recebe um e-mail e responde no portal de retirada. Se esse e-mail de notificação não puder ser enviado, a mensagem é salva mesmo assim e a requisição retorna `201`.
* A requisição retorna `409` com um motivo em `detail` para uma transferência por `TRP`, `GTR`, `TRUST`, `VerifyVASP` ou `Sygna` (esses protocolos não transportam mensagens), uma transferência ainda sem contraparte, uma transferência `INTERNAL` cujos dados não corresponderam ao titular da carteira (nada chegou ao destinatário), uma transferência `INTERNAL` cujo destinatário ainda não comprovou o controle da carteira (nos dois lados, até que comprove), uma transferência `EMAIL` cuja contraparte não tem mais um endereço de e-mail de conformidade e uma transferência `EMAIL` cujo link de retirada expirou ou cuja transferência está encerrada.
* Nenhum webhook é disparado quando a contraparte responde. Consulte o endpoint de mensagens.
* O e-mail que avisa a contraparte sobre uma nova mensagem é enviado em inglês.

### Catálogo de endereços de carteiras

Registre as carteiras que você controla para que as transferências recebidas (rail `INTERNAL`, consultas `TRP` recebidas e [registros após o depósito](#registro-sunrise-após-o-depósito)) possam ser resolvidas com base nelas, usando `POST`/`GET /v3/travel-rule/wallet-addresses/` e `PATCH`/`DELETE /v3/travel-rule/wallet-addresses/{entry_uuid}/`.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
    "chain": "ETH",
    "holder_name": "Ana Diaz",
    "holder_vendor_data": "user-042",
    "self_declared": true
  }'
```

| Campo | Tipo | Descrição |
| - | - | - |
| `address` | string | O endereço da carteira. Único por aplicação, `chain` e `memo` (o endereço é comparado sem diferenciar maiúsculas de minúsculas); uma duplicata retorna `400`. Um X-address da XRP é armazenado como seu endereço clássico e sua tag. Vazio em uma entrada [importada pelo hash](#importação-de-carteiras-em-massa). |
| `address_hash` | string | Somente leitura. SHA-256 do endereço em minúsculas, em hexadecimal minúsculo. |
| `memo` | string | Opcional. A destination tag ou o memo que faz parte da carteira em uma [rede com memo](#redes-com-memo-e-tag); vazio para o endereço inteiro. Alias: `destinationTag`. |
| `chain` | string | Identificador de blockchain opcional, com até 32 caracteres. Use o mesmo token que suas transferências levam (por exemplo, `ETH` ou `BTC`) ou deixe vazio para corresponder a transferências em qualquer blockchain; veja a nota abaixo. Um recebedor Lightning (node id ou Lightning Address) registrado em bitcoin é armazenado em minúsculas em `LIGHTNING`, onde as transferências [Lightning](#lightning) são correspondidas. |
| `holder_name` | string | Nome do titular da carteira, usado na correspondência do nome do beneficiário. |
| `holder_vendor_data` | string | Seu identificador interno do titular. |
| `entity_type` | string | Texto livre com até 16 caracteres; o padrão é `"individual"`. |
| `travel_address` | string | Opcional. O travel address do VASP contraparte para esta carteira, se você o conhecer. Permite que a Didit encaminhe transferências para este beneficiário pelo trilho `TRP` em vez de e-mail. |
| `receiving_travel_address` | string | Somente leitura. Seu próprio travel address por carteira para esta carteira. Informe-o a um VASP que envia para esta carteira: a consulta TRP dele passa então a nomear a carteira diretamente. Vazio para uma carteira registrada como de outro VASP, enquanto a Travel Rule estiver desativada e antes de o seu perfil de VASP ser salvo. Ele deixa de responder assim que a carteira é excluída. |
| `is_ownership_verified` | boolean | Somente leitura. Indica se a propriedade deste endereço foi comprovada (pelo [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) ou por autodeclaração). |
| `self_declared` | boolean | Somente escrita, apenas em `POST`. Quando `true`, a entrada é criada já verificada por meio de uma prova `SELF_DECLARATION`: transferências recebidas neste endereço pulam totalmente `UNCONFIRMED_OWNERSHIP` e vão direto para a correspondência de nome. Retorna `400` quando `allow_self_declaration` está desativado nas suas configurações. |

`PATCH` aceita `holder_name`, `holder_vendor_data`, `entity_type` e `travel_address`, e retorna apenas esses quatro campos.
`DELETE` exclui a entrada (`204`): o endereço fica liberado para novo registro e ela deixa imediatamente de corresponder a novas transferências.

> [!NOTE]
>
> A correspondência não diferencia maiúsculas de minúsculas no endereço, inclui o `memo` em uma rede com memo e é delimitada por `chain`.
> Quando uma transferência informa uma blockchain, uma entrada só corresponde se o `chain` dela tiver o mesmo valor (sem diferenciar maiúsculas de minúsculas) ou estiver vazio.
> Os nomes de blockchain são comparados como texto, sem conversão, portanto uma entrada armazenada como `ethereum` não corresponde a uma transferência cuja blockchain é `ETH`.
> As transferências enviadas obtêm a blockchain de `beneficiary_data.chain`, depois de `transaction_details.crypto_params.crypto_chain`, depois de `custom_properties.crypto_chain` e depois da moeda (por exemplo, `ETH`, ou, para `USDT` e `USDC`, a blockchain inferida a partir de `payment_reference_id`), definida apenas quando é uma blockchain que a Didit reconhece; os registros após depósito a obtêm do campo `chain`, em minúsculas.
> As consultas `TRP` recebidas ignoram a blockchain: elas correspondem pelo endereço ou, quando a consulta não nomeia nenhuma carteira, pelo nome do beneficiário em relação às suas entradas verificadas.
> [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira) também corresponde apenas pelo endereço.
> Quando várias entradas correspondem, o trilho `INTERNAL` e os registros após depósito preferem uma entrada com propriedade verificada e, em seguida, a mais antiga; a busca `TRP` de saída usa a entrada mais antiga que armazena um travel address.
> As consultas `TRP` recebidas e o endpoint de propriedade usam qualquer uma das entradas correspondentes, portanto mantenha uma entrada por endereço sempre que possível.
> O trilho `INTERNAL` não corresponde a nenhuma entrada quando existem entradas verificadas para o endereço em mais de uma outra aplicação.

#### Importação de carteiras em massa

Importe até 10.000 carteiras em uma única chamada com [`POST /v3/travel-rule/wallet-addresses/import/`](https://docs.didit.me/pt-br/management-api/travel-rule/import-wallet-addresses), em JSON (`{"entries": [...]}` ou um array simples) ou como um arquivo CSV UTF-8 de no máximo 5 MB com uma linha de cabeçalho.
Uma linha identifica uma carteira pelo `address`, pelo `address_hash` (o SHA-256 do endereço em minúsculas, com 64 caracteres hexadecimais ou 44 em base64) ou por ambos, além de qualquer um dos campos de entrada acima.
Envie apenas o hash para registrar uma carteira sem revelar o endereço: ela corresponde a transferências para esse endereço como qualquer outra entrada e pode ser comprovada com o [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md).

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \
  -H "x-api-key: YOUR_API_KEY" \
  -F "file=@wallets.csv;type=text/csv"
```

```text theme={null}
address,address_hash,chain,memo,holder_name,holder_vendor_data
0xBeneficiaryWallet01,,ethereum,,Ana Diaz,user-042
,4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e,bitcoin,,,user-043
rExchangeSharedAddress01,,XRP,104729,Ana Diaz,user-042
```

A importação é idempotente e informa cada linha na ordem de envio: `created`, `existing` (a mesma carteira, blockchain e memo já está no cadastro e não foi alterada), `duplicate` (repete uma linha anterior, indicada em `duplicate_of_row`) ou `failed` com seus `errors`.
Uma linha com erro nunca faz as outras falharem: a resposta é `200` quando nenhuma linha falhou e `207` quando alguma falhou, com as contagens em `total`, `created`, `existing`, `duplicate` e `failed`.
Uma célula vazia no CSV conta como não enviada, e as colunas que a importação não lê são ignoradas, então uma exportação de outra ferramenta é importada como está.

Em `GET /v3/travel-rule/transfers/`, cada linha traz `originator_memo` e `beneficiary_memo` ao lado das duas carteiras.

### Coleta por e-mail para contrapartes inacessíveis

Quando nenhum trilho de protocolo consegue alcançar a contraparte, a Didit recorre ao `EMAIL`: ela envia um link de coleta de uso único para `beneficiary_data.counterparty_vasp_email` (ou para um e-mail obtido a partir de `beneficiary_data.counterparty_vasp_name` no registro do diretório de VASPs).
O destinatário não precisa de uma conta Didit nem de uma chave de API: o token do link é a autenticação.
Como a requisição é enviada:

* **Para os endereços certos.** Um `counterparty_vasp_email` que você informa é o único destinatário. Caso contrário, a Didit escreve para até três endereços: os [contatos](#contatos) da contraparte que não tiveram devolução (os seus primeiro, depois os contatos da plataforma, com os que já responderam antes em primeiro lugar) e, em seguida, o e-mail de conformidade da entrada do diretório, quando sobra uma vaga. Cada endereço recebe o próprio e-mail.
* **Em seu nome.** O e-mail sai do endereço da Didit como "*sua razão social* via Didit", no idioma da jurisdição da contraparte (inglês quando nenhuma é conhecida), e o link abre a página de resposta nesse idioma. Você não recebe cópia: acompanhe a linha do tempo da transferência.
* **Com lembretes.** Até a contraparte responder, a Didit envia lembretes 72, 24 e 6 horas antes do prazo, com no mínimo 12 horas após a requisição ou o último lembrete, e nunca depois do prazo.
* **Com tratamento de devoluções.** Uma devolução ou uma denúncia de spam marca o contato atingido como inválido, com o motivo, e a linha do tempo da transferência registra isso. Um contato da plataforma passa então a ser inválido para todos os clientes da Didit; o contato próprio da sua aplicação, apenas para a sua aplicação. Quando a entrega de e-mails da Didit para totalmente de enviar para um endereço (após uma devolução permanente, uma denúncia de spam ou um cancelamento de inscrição), todos os contatos nesse endereço são marcados como inválidos (`suppressed`) e voltam a ser válidos assim que o envio para o endereço é retomado. Quando não resta nenhum endereço para escrever, a transferência passa a `COUNTERPARTY_VASP_NOT_REACHABLE`, com o motivo do servidor de e-mail de destino na linha do tempo. Uma devolução permanente ou uma denúncia de spam no `counterparty_vasp_email` que você informou faz isso imediatamente, porque ele é o único destinatário; uma devolução temporária (`soft_bounce`) nele, ou no próprio e-mail de conformidade da entrada do diretório, mantém a requisição aberta para os lembretes.

O link abre uma página hospedada que mostra a troca pendente e chama estes dois endpoints públicos para o destinatário.
Para a [transferência de exemplo acima](#envio-de-uma-transferência), os dados de coleta são:

```bash theme={null}
curl https://verification.didit.me/v3/travel-rule/pickup/{token}/
```

```json theme={null}
{
  "reference": "33333333-4444-5555-6666-777777777777",
  "requested_at": "2026-07-05T10:00:00Z",
  "originator_vasp_name": "Origin CASP SL",
  "originator_vasp_lei": "529900EXAMPLEORIG001",
  "recipient_vasp_name": "Example Counterparty VASP",
  "language": "es",
  "amount": "0.250000000000000000",
  "currency": "ETH",
  "fiat_amount": "",
  "fiat_currency": "",
  "chain": "ETH",
  "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
  "status": "AWAITING_COUNTERPARTY",
  "ivms_version": "ivms101.2023",
  "deadline_at": "2026-07-07T10:00:00Z",
  "reminders_sent": 0,
  "contact": "",
  "decline_reasons": ["data_mismatch", "not_our_customer", "wallet_not_hosted", "sanctions", "risk_appetite", "jurisdiction", "insufficient_data", "other"],
  "join_invitation": { "eligible": false, "url": "" },
  "originator_data": { "name": "Jane Doe", "wallet_address": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7" },
  "beneficiary_data": { "name": "Ana Diaz", "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb" },
  "ivms_request": {
    "originator": {
      "originatorPersons": [{ "naturalPerson": { "name": { "nameIdentifier": [{ "primaryIdentifier": "Doe", "secondaryIdentifier": "Jane", "nameIdentifierType": "LEGL" }] } } }],
      "accountNumber": ["0x77ccff0cc624a53cd8b8d8703ced826710211ec7"]
    },
    "beneficiary": {
      "beneficiaryPersons": [{ "naturalPerson": { "name": { "nameIdentifier": [{ "primaryIdentifier": "Diaz", "secondaryIdentifier": "Ana", "nameIdentifierType": "LEGL" }] } } }],
      "accountNumber": ["0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb"]
    }
  },
  "data_masked": false
}
```

`reference` é o `uuid` da transferência. `originator_data` e o `ivms_request` IVMS 101 gerado a partir dele contêm apenas os campos do remetente que você compartilha em [`data_sharing_fields`](#compartilhamento-de-dados); o nome e a carteira são sempre incluídos. `fiat_amount` e `fiat_currency` ficam vazios quando você não enviou nenhum valor convertido, `contact` repete o valor `?contact=` do link e `decline_reasons` lista os valores aceitos por `decline_reason`. `join_invitation.eligible` é `true` enquanto a contraparte tiver um convite ativo para entrar na Didit; o link do convite em si só é enviado no e-mail.

Este endpoint retorna o valor armazenado sem alterações, por isso traz as 18 casas decimais completas, e não a forma reduzida usada pelo objeto de detalhes da transação.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/pickup/{token}/respond/ \
  -H "Content-Type: application/json" \
  -d '{"decision": "accept", "beneficiary_name": "Ana Diaz"}'
```

`decision` é `accept` ou `decline`.
Em `accept`, o `beneficiary_name` informado é comparado com o `beneficiary_data.name` da transferência segundo a sua regra de nomes: `COMPLETED` quando há correspondência, `COUNTERPARTY_MISMATCHED_DATA` caso contrário. Em vez disso, a contraparte pode enviar uma resposta IVMS 101 completa como `ivms_response`; nesse caso, o nome do beneficiário dessa resposta prevalece sobre `beneficiary_name`.
Em `decline`, a transferência passa para `COUNTERPARTY_VASP_GENERAL_DECLINE`. A contraparte pode informar um `decline_reason` de `decline_reasons`, com um `decline_detail` (até 512 caracteres, obrigatório para `other`), e a linha do tempo da sua transferência registra isso, por exemplo `counterparty declined: The beneficiary is not our customer`.
A resposta é o `{"status": "..."}` resultante, mais `decline_reason` após uma recusa. Depois que a contraparte responde, os dois endpoints retornam `410`.
Os dois endpoints retornam `404` para um token desconhecido e `410` quando a janela se encerra: ou a transferência saiu de `AWAITING_COUNTERPARTY`, ou o prazo de confirmação dela (`confirmation_timeout_hours` após a criação ou o último reenvio) já passou.

A contraparte lê e responde pelo link de coleta com `GET` e `POST /v3/travel-rule/pickup/{token}/messages/`.
Ela não precisa de chave de API, aceita apenas anexos em PDF, PNG, JPEG ou WebP e responde `410` quando o link expira ou a transferência é encerrada.
Uma mensagem que você enviou mostra o nome do seu VASP como `author` e como `uploaded_by` do anexo, nunca a pessoa ou a chave de API por trás dela.

### Depósitos sem correspondência

Um depósito de entrada pode chegar antes dos dados de Travel Rule do VASP de origem.
Esse depósito permanece em `AWAITING_COUNTERPARTY` ou `NOT_ENOUGH_COUNTERPARTY_DATA` até os dados chegarem.
Liste os depósitos que ainda estão aguardando com uma chave de API que tenha o privilégio de transações:

```bash theme={null}
curl "https://verification.didit.me/v3/travel-rule/unmatched/" \
  -H "x-api-key: YOUR_API_KEY"
```

A resposta usa as mesmas linhas de `GET /v3/travel-rule/transfers/`, limitadas aos depósitos de entrada que aguardam os dados do VASP de origem.

Quando os dados tiverem chegado como uma mensagem recebida separada, faça você mesmo o pareamento entre os dois:

```bash theme={null}
curl -X POST "https://verification.didit.me/v3/travel-rule/unmatched/{transaction_uuid}/match/" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"transaction_id": "<uuid of the received message transaction>"}'
```

`{transaction_uuid}` é o depósito.
`transaction_id` é a transação da mensagem de Travel Rule recebida.
A chamada retorna `{ "deposit": ..., "message": ... }`.
Ela responde `404` quando alguma das transações não existe mais e `409` com `travel_rule_match_conflict` ("This deposit can no longer be matched.") quando algum dos lados já avançou.

### Registro sunrise após o depósito

Quando um depósito de cripto é liquidado on-chain **antes** de qualquer troca de Travel Rule ter ocorrido (o VASP remetente estava inacessível, ou você está preenchendo retroativamente depósitos históricos), registre-o posteriormente com `POST /v3/travel-rule/inbound/`.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/inbound/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chain": "eth",
    "txid": "0xf103cfc37f6d390b61827987b9dc631b5e1d2bfeb008a780c1e38047ae5d557b",
    "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
    "amount": "500.00",
    "currency": "USDC",
    "originator_data": { "name": "Carlos Ruiz", "wallet_address": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7" },
    "beneficiary_data": { "name": "Ana Diaz" },
    "originating_vasp": {
      "name": "Northwind Digital Assets Ltd",
      "lei": "5493001KJTIIGC8Y1R12",
      "travel_address": "tareGfwAzkySLkFzcqr7AKno3K4VsT3jayMwPvj3ovbFZHzpayHLmgCrAMoLqjfCYRPpvLqr9dSr2VVTFAncwChcMjL4AheNuHCJM8NRcUg"
    }
  }'
```

`originating_vasp.travel_address` deve ser um [travel address](#endereços-de-viagem) real e com checksum válido: um valor fictício retorna `400` com `"Invalid travel address."`.
`originating_vasp.lei` deve estar vazio ou ter 20 caracteres no formato LEI (18 letras ou dígitos, seguidos de 2 dígitos); qualquer outro valor retorna `400` com `"Invalid LEI: expected 20 alphanumeric characters (ISO 17442)."`.
A Didit verifica apenas esse formato, não os dígitos de verificação da ISO 17442.

| Campo | Tipo | Descrição |
| - | - | - |
| `chain` | string | Chain em que o depósito foi liquidado, com até 32 caracteres. A Didit converte o valor para minúsculas e o usa para encontrar entradas correspondentes no seu [catálogo de endereços](#catálogo-de-endereços-de-carteiras), então use o mesmo token das suas entradas (`eth` corresponde a uma entrada armazenada como `ETH`). Ele também determina se o depósito pode ser analisado: `bitcoin`/`btc`, `ethereum`/`eth`, `solana`/`sol`, `tron`/`trx`, `polygon`/`matic`, `bsc`/`bnb`, `litecoin`/`ltc`, `ripple`/`xrp`, `bitcoin-cash`/`bch` e `dogecoin`/`doge`. |
| `txid` | string | O hash da transação on-chain. Usado para eliminar duplicatas: o mesmo `txid` + `wallet_address` retorna a transferência existente em vez de criar uma duplicada. |
| `wallet_address` | string | A carteira de destino em que você recebeu o depósito. Um X-address de XRP é dividido em seu endereço clássico e tag. |
| `memo` | string | Opcional. A destination tag ou o memo do depósito em uma [rede com memo](#redes-com-memo-e-tag): em um endereço de depósito compartilhado, ele identifica o cliente ao qual o depósito pertence. |
| `amount` | string (decimal) | Valor do depósito. |
| `currency` | string | Ativo do depósito. |
| `originator_data` | object | Dados do remetente fornecidos pelo VASP remetente, se conhecidos, como um objeto plano: a Didit lê `name` (ou `full_name`), `first_name`, `last_name` e `vendor_data`. |
| `beneficiary_data` | object | Dados do beneficiário (seu cliente), como um objeto plano: a Didit compara o `name` dele com o `holder_name` da entrada correspondente do catálogo de endereços e adiciona `wallet_address` e `chain` a ele. |
| `utxo` | object | Opcional, apenas para [chains UTXO](#transferências-utxo). Os `inputs` e `outputs` da transação de depósito: a carteira do remetente é `originator_data.wallet_address` quando você a declara; caso contrário, é o maior input. |
| `originating_vasp` | object | `{ name, lei, travel_address }` opcional que descreve o remetente. `lei` deve seguir o formato LEI acima e `travel_address` deve ser um travel address válido; caso contrário, a requisição retorna `400`. Fica armazenado nesta transferência como `metadata.originating_vasp`; nunca cria nem altera uma entrada compartilhada do [diretório](#como-as-entradas-chegam-ao-diretório). |

Didit cria uma transação `travelRule` de entrada (ou reutiliza um depósito de entrada que você já enviou com o mesmo hash e a mesma carteira, se ele ainda não tiver uma transferência Travel Rule) e confere a transferência com o seu [catálogo de endereços de carteiras](#catálogo-de-endereços-de-carteiras), pelo endereço e pelo seu memo:

* Nenhuma entrada correspondente -> `ON_HOLD`.
  Resolva com [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira): `confirmed: true` adiciona a carteira ao seu catálogo de endereços como verificada e executa a correspondência de nomes; se houver correspondência, a transferência passa para `COMPLETED` e depois para `FINISHED`.
* A entrada existe, mas a propriedade não foi comprovada -> `UNCONFIRMED_OWNERSHIP`.
* O nome do beneficiário não corresponde ao `holder_name` da entrada -> `COUNTERPARTY_MISMATCHED_DATA`.
* Entrada verificada e o nome corresponde -> `COMPLETED` e, logo em seguida, `FINISHED` (o depósito já foi liquidado).

Com a entrada verificada do catálogo de endereços registrada no [exemplo acima](#catálogo-de-endereços-de-carteiras), a resposta é:

```json theme={null}
{
  "transaction_id": "44444444-5555-6666-7777-888888888888",
  "txn_id": "tr-in-0xf103cfc37f6d390b61827987b9dc631b5e1d2bfeb008a780c1e38047ae5d557b-6151d81b366e",
  "created": true,
  "travel_rule": {
    "uuid": "55555555-6666-7777-8888-999999999999",
    "status": "FINISHED",
    "direction": "INBOUND",
    "rail": null,
    "protocol": null,
    "ivms_version": "ivms101.2023",
    "required": true,
    "ownership_confirmed": true,
    "deadline_at": null,
    "timeline": [
      { "status": "COMPLETED", "at": "2026-07-06T10:15:02.114208+00:00", "detail": "matched verified wallet address book entry" },
      { "status": "FINISHED", "at": "2026-07-06T10:15:02.131544+00:00", "detail": "on-chain deposit already settled" }
    ],
    "counterparty_vasp": null,
    "originator_data": { "name": "Carlos Ruiz", "wallet_address": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7" },
    "beneficiary_data": { "name": "Ana Diaz", "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", "chain": "eth" },
    "created_at": "2026-07-06T10:15:02.087412Z"
  }
}
```

O `txn_id` da nova transação é `tr-in-`, seguido dos primeiros 80 caracteres do `txid` e de um hash de 12 caracteres do `txid` e da carteira.
`created` é `true` (HTTP `201`) quando esta chamada registrou o depósito, e `false` (HTTP `200`) quando o mesmo `txid` e o mesmo `wallet_address` já estavam registrados; nesse caso, a transferência existente é retornada sem alterações.
No caminho da entrada verificada, as duas transições acontecem antes de o endpoint responder, então a resposta síncrona já mostra o status final `FINISHED`. A etapa intermediária `COMPLETED` continua registrada no `timeline` da transferência.
Cada transição dispara um webhook `travel_rule.status.updated` (`COMPLETED` e `FINISHED` disparam um cada).
Quando Didit cria uma nova transação, envia primeiro [`transaction.created`](https://docs.didit.me/pt-br/integration/webhooks#tipos-de-evento) e, depois dele, esses eventos.
O registro não gera tarifa de Travel Rule nem de monitoramento.
Quando o monitoramento de cripto está ativado e a `chain` é uma que Didit consegue analisar, um depósito recém-criado também passa por triagem e é cobrado uma única vez pela tarifa de Wallet Verification & Screening.

### Widget de propriedade da carteira

Para tirar uma transferência de `UNCONFIRMED_OWNERSHIP`, ou para pré-verificar uma carteira antes da chegada de qualquer transferência, gere um widget hospedado de propriedade da carteira com `POST /v3/travel-rule/widget-session/` e envie o seu cliente para a `url` retornada. O widget comprova o controle da carteira por assinatura de mensagem (incluindo contas de smart contract EVM, por meio de ERC-1271 e ERC-6492), teste de Satoshi, captura de tela ou autodeclaração e, em seguida, marca como verificada a entrada correspondente do catálogo de endereços para que a troca possa continuar.
A captura de tela é a exceção: ela nunca verifica a carteira sozinha. Por isso, a sua equipe de conformidade a analisa e confirma uma transferência em `UNCONFIRMED_OWNERSHIP` com [`POST .../travel-rule/ownership/`](#confirmação-de-propriedade-da-carteira).

Consulte [Widget de propriedade da carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md) para ver o fluxo completo, os métodos de comprovação e o aviso importante de que o widget deve ser aberto em um navegador real, nunca dentro de uma webview de SDK móvel.

## Diretório

`GET /v3/travel-rule/vasps/` pesquisa o diretório de VASPs: as entradas do diretório compartilhado e os membros da [rede Didit](#a-rede-didit). Cada linha informa como sua aplicação pode alcançar esse VASP hoje.

```bash theme={null}
curl "https://verification.didit.me/v3/travel-rule/vasps/?search=counterparty" \
  -H "x-api-key: YOUR_API_KEY"
```

```json theme={null}
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
      "kind": "directory",
      "name": "Example Counterparty VASP",
      "lei": "529900EXAMPLECPTY001",
      "jurisdiction": "DE",
      "domains": ["counterparty.example"],
      "reachable": true,
      "aliases": [{ "name": "Example Counterparty", "kind": "trading_name" }],
      "networks": [
        {
          "network": "GTR",
          "code": "EXAMPLE01",
          "listed_name": "Example Counterparty VASP",
          "country": "DE",
          "verified_at": "2026-10-12T09:30:00Z",
          "last_seen_at": "2026-10-12T09:30:00Z",
          "source": "staff"
        }
      ],
      "routes": [
        { "rail": "GTR", "status": "unavailable", "reason": "no_membership", "via": "" },
        { "rail": "EMAIL", "status": "available", "reason": "", "via": "contact" }
      ],
      "umbrella": null,
      "entities": [],
      "contacts": [
        {
          "id": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
          "email": "travelrule@counterparty.example",
          "name": "Travel Rule desk",
          "source": "staff",
          "scope": "platform",
          "verified_at": null
        }
      ],
      "dd_status": "NOT_STARTED",
      "dd_score": 62,
      "dd_score_breakdown": {
        "jurisdiction": { "points": 25.0, "max": 25, "reason": "jurisdiction_not_high_risk", "detail": "DEU is not on the high-risk jurisdiction list" },
        "verification": { "points": 3.8, "max": 15, "reason": "dd_status_not_started", "detail": "due diligence status NOT_STARTED" },
        "protocol": { "points": 6.0, "max": 15, "reason": "email_only", "detail": "reachable over the email fallback only" },
        "lei": { "points": 10.0, "max": 10, "reason": "lei_valid", "detail": "valid LEI on record" },
        "history": { "points": 5.0, "max": 10, "reason": "no_history", "detail": "no exchange history" },
        "essentials": { "points": 7.5, "max": 15, "reason": "no_essential_checks", "detail": "no decided essential check yet" },
        "responsiveness": { "points": 5.0, "max": 10, "reason": "responsiveness_unknown", "detail": "0 decided recent requests, too few to judge" }
      },
      "dd_assessed_at": "2026-10-12T09:30:00Z",
      "dd_score_semantic": "higher_is_safer",
      "risk_level": "MEDIUM",
      "responsiveness": { "status": "UNKNOWN", "answered": 0, "total": 0, "computed_at": "2026-10-12T09:30:00Z" },
      "essential_checks": {},
      "reachable_rails": ["GTR", "EMAIL"],
      "is_didit_customer": false,
      "decision": {
        "decision": "APPROVED",
        "reason": "Licensed in DE",
        "decided_by": "",
        "updated_at": "2026-10-14T10:05:00Z",
        "inherited_from": null
      },
      "entity_screening": {
        "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
        "status": "Approved",
        "total_hits": 0,
        "score": null,
        "screened_at": "2026-10-14T09:58:00Z",
        "fresh": true,
        "flagged": false
      },
      "questionnaires": []
    }
  ]
}
```

`search` corresponde a um trecho de nome ou alias, a um LEI exato ou a um domínio (`counterparty.example` ou uma URL nele). Restrinja os resultados com:

| Parâmetro | Efeito |
| - | - |
| `network` | `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` ou `TRISA`: apenas as entradas que o diretório de membros dessa rede lista atualmente. |
| `jurisdiction` | Código de país ISO 3166 alfa-2 ou alfa-3. |
| `reachable` | `true`: apenas os VASPs para os quais sua aplicação tem uma rota disponível. `false`: apenas as entradas que ela não consegue alcançar hoje. |
| `kind` | `directory` para entradas compartilhadas, `didit` para membros da rede Didit. |
| `risk` | `LOW`, `MEDIUM` ou `HIGH`: apenas as entradas do diretório cujo `risk_level` está nessa faixa. Consulte [Pontuação e nível de risco](#pontuação-e-nível-de-risco). |
| `responsiveness` | `RESPONSIVE`, `UNRESPONSIVE` ou `UNKNOWN`: apenas as entradas do diretório com esse `responsiveness.status`. Consulte [Responsividade](#capacidade-de-resposta). |

Os membros da rede Didit não recebem pontuação, portanto `risk` e `responsiveness` retornam apenas entradas do diretório. Os resultados são ordenados por nome e paginados com `limit` (padrão `50`) e `offset`. Uma rede, um código de país, uma faixa de risco ou um status de responsividade desconhecido retorna `400` indicando o campo. `GET /v3/travel-rule/vasps/{vasp_id}/` retorna uma linha pelo seu `id`. Seu próprio perfil de VASP nunca aparece nos seus próprios resultados.

`dd_status`, `dd_score`, `dd_score_breakdown`, `dd_assessed_at`, `dd_score_semantic`, `risk_level`, `responsiveness` e `essential_checks` trazem a avaliação de due diligence compartilhada de uma entrada do diretório. `decision`, `entity_screening` e `questionnaires` são os registros próprios da sua aplicação sobre o VASP, e nenhum outro cliente os vê. Consulte [Due diligence de contrapartes](#due-diligence-de-contrapartes) para saber o que cada um significa, e condicione o fluxo a eles com os [campos de regra de contraparte](#campos-e-presets-de-regras) em vez de criar ramificações no código com base neles. Os membros da rede Didit não recebem pontuação: `dd_status` é `COMPLETED`, `dd_score` é `null`, `risk_level` fica vazio e o detalhamento fica vazio.

### Rotas

`routes` lista as formas de entrega ao VASP disponíveis para sua aplicação, na ordem em que a sequência de roteamento as tenta, e `reachable` é `true` quando pelo menos uma está `available`:

* `TRP` quando a entrada traz um endpoint TRP verificado pelo diretório.
* `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` quando uma rede lista o VASP sob um código. A rota fica `available` somente quando sua aplicação pode enviar por essa rede hoje (`via: own_membership` para a sua própria associação conectada, `via: didit_membership` para a da Didit). Caso contrário, fica `unavailable` com `reason: no_membership` ou `reason: network_switched_off`, e nunca é exibida como uma forma de alcançar o VASP. As associações da própria Didit às redes ainda não estão ativas, portanto hoje uma rota de rede só fica disponível por meio de uma associação que você conectou no Marketplace.
* `EMAIL` quando existe um contato de conformidade para a entrada.
* `INTERNAL` para um membro da rede Didit.

Uma listagem `TRISA` aparece em `networks` e informa a identidade do VASP na TRISA, mas a Didit não tem um canal TRISA, portanto ela nunca é uma rota.

Uma aplicação de sandbox envia apenas para o [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md), portanto nenhuma rota do diretório fica disponível para ela: todas as rotas ficam `unavailable` com `reason: sandbox_application`, todas as linhas têm `reachable: false` e `reachable=true` não retorna nenhuma linha.

### Marcas e suas entidades

Uma marca que opera por meio de várias entidades reguladas é uma única linha cujas `entities` são as entidades jurídicas que recebem suas transferências; uma linha de entidade aponta de volta para sua marca em `umbrella`. Uma transferência que indica a marca vai para uma de suas entidades, escolhida entre todas elas: a que está na jurisdição informada em `beneficiary_data.counterparty_vasp_jurisdiction`; senão, a entidade que a [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) vinculou à carteira de destino; senão, a única entidade da marca quando nenhuma jurisdição é informada. Só então essa entidade precisa estar acessível; se não estiver, a transferência nunca é enviada a outra entidade nem à marca em seu lugar. Quando nenhuma entidade se encaixa (duas se encaixam igualmente, ou foi informada uma jurisdição em que nenhuma delas está), é usada a rota da própria marca e, sem ela, a transferência fica `COUNTERPARTY_VASP_NOT_FOUND`. Qual entidade jurídica recebe os dados do remetente nunca é um palpite, e nunca é decidida pela entidade que por acaso tenha um contato.

Várias entradas com o mesmo nome, como empresas de um grupo que compartilham um nome comercial, são diferenciadas pela mesma regra: a que está na jurisdição informada; senão, a que a atribuição por análise de blockchain vinculou. Quando nenhum dos dois critérios escolhe uma, nenhuma é usada, e os dados são tratados como se não indicassem nenhuma entrada do diretório.

### Contatos

`contacts` são os endereços de e-mail para os quais o canal `EMAIL` envia mensagens. Os contatos `scope: platform` atendem a todos os clientes da Didit: a Didit os seleciona (`source: staff`), ou um endereço em um dos domínios do próprio VASP respondeu a uma requisição pelo seu link de resposta (`source: learned`). Os contatos `scope: application` são privados da sua aplicação: os que você adiciona (`source: application`) e um endereço fora dos domínios do próprio VASP que respondeu a uma de suas requisições (`source: learned`). Uma transferência envia e-mail primeiro ao contato da sua própria aplicação, depois a um contato da plataforma que já respondeu antes (`verified_at` preenchido) e, em seguida, aos demais.

Gerencie os contatos da sua própria aplicação com a API de contatos de contrapartes:

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/counterparty-contacts/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91", "email": "compliance@counterparty.example", "name": "Compliance desk"}'
```

* `GET /v3/travel-rule/counterparty-contacts/` lista todos os contatos para os quais sua aplicação pode enviar, incluindo contatos da plataforma e os que retornaram com falha de entrega, do mais recente para o mais antigo, paginados com `limit` e `offset`. Filtre com `?counterparty=` e o `id` de uma entrada do diretório; um valor que não seja um UUID retorna `400`.
* `POST` adiciona um contato privado (`counterparty`, `email`, `name` opcional) e retorna `201`. Adicionar um endereço que a entrada já tem entre os seus próprios contatos retorna esse contato. Uma entrada desconhecida retorna `400` (`"No directory entry with this id."`).
* `DELETE /v3/travel-rule/counterparty-contacts/{contact_uuid}/` exclui um dos seus próprios contatos (`204`). Os contatos da plataforma não podem ser excluídos e retornam `404`.

Um contato cujo e-mail retornou com falha de entrega ou que gerou reclamação tem `is_invalid: true`, com `invalid_reason` (`hard_bounce`, `soft_bounce`, `spam_complaint` ou `suppressed`), `invalid_detail` e `invalid_at`, e o canal `EMAIL` o ignora. `created_by` fica vazio nos contatos da plataforma e nos contatos adicionados por uma chave de API.

### Como as entradas chegam ao diretório

* O registro provisório MiCA da ESMA de prestadores de serviços de criptoativos, lido toda semana: o nome, o LEI e o estado-membro de origem de cada prestador.
* O diretório público da TRISA, lido toda semana: quem é cada membro, seu país e sua listagem na TRISA. Uma listagem que o diretório deixa de exibir por três semanas é removida.
* O registro global de LEI informa o LEI, outros nomes jurídicos e o país de uma entrada, e encontra o LEI de uma entrada pelo seu nome jurídico exato no seu país.
* A [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) adiciona ou associa o VASP dono de uma carteira de destino e mantém o nome atribuído como alias.
* A equipe da Didit faz a curadoria das entradas: identificadores de roteamento e listagens de rede que verificou, contatos de conformidade, aliases, marcas e suas entidades, duplicatas mescladas e entradas ocultas.

Os dados que um cliente informa sobre uma contraparte, como um `originating_vasp` de entrada ou um Travel Address, ficam na transferência desse cliente e nunca alteram uma entrada compartilhada. As entradas são associadas primeiro pelo LEI, depois pelo nome exato ou alias, e são enriquecidas em vez de duplicadas.

### A rede Didit

Seu perfil de VASP é membro da rede Didit, de modo que outros clientes da Didit o encontram no diretório e no seletor de VASP do usuário final, somente enquanto todas estas condições forem atendidas:

* sua aplicação está em produção (não em sandbox) e a Travel Rule está ativada;
* `is_discoverable` é `true` e `legal_name` está definido;
* `compliance_email` está definido e confirmado: envie a solicitação de confirmação com `POST /v3/travel-rule/settings/compliance-email/confirmation/` e abra o link recebido por e-mail. Alterar o endereço exige uma nova confirmação;
* a Didit não marcou a aplicação como de teste, demonstração ou interna.

O próprio canal `INTERNAL` faz a entrega para uma carteira cuja titularidade você comprovou, conforme descrito em [Envio de uma transferência](#envio-de-uma-transferência): ele exige sua aplicação em produção, a Travel Rule ativada e `is_discoverable`, e não o restante da lista.

`GET /v3/travel-rule/settings/` retorna `didit_network`: `listed`, `compliance_email_confirmed` e, em `missing`, cada condição ainda não atendida (`travel_rule_off`, `sandbox_application`, `not_discoverable`, `legal_name_missing`, `compliance_email_missing`, `compliance_email_unconfirmed`, `excluded_by_staff`, `internal_organization`).

### Identificadores de roteamento

O roteamento de saída consulta uma entrada do diretório sempre que sua transferência identifica a contraparte por `counterparty_vasp_lei` ou `counterparty_vasp_name` (um alias também funciona). Uma entrada contém um identificador para cada rede pela qual pode ser alcançada, um endpoint TRP verificado e seus contatos de conformidade, e `routes` mostra quais deles sua aplicação pode usar. Você sempre pode ignorar o diretório em uma única transferência informando os campos explícitos em [Campos de resolução da contraparte](#campos-de-resolução-da-contraparte).

## Due diligence de contrapartes

Antes que os fundos dos seus clientes cheguem a outro VASP, você precisa saber quem é esse VASP e se você o aceita. A due diligence de uma contraparte tem duas camadas:

* **A avaliação compartilhada.** Cada entrada do diretório traz uma pontuação de due diligence, seu nível de risco, um status de capacidade de resposta e um relatório de verificações essenciais. A Didit os calcula a partir dos próprios dados da plataforma, então todos os clientes veem os mesmos valores.
* **Seus próprios registros.** Sua decisão sobre o VASP, sua triagem de sanções e mídia adversa dele e os questionários de due diligence que você trocou com ele pertencem apenas à sua aplicação. Nenhum outro cliente os vê, e eles nunca alteram a entrada compartilhada.

Seus próprios registros funcionam tanto para uma entrada do diretório quanto para um membro da [rede Didit](#a-rede-didit): referencie-os pelo `id` que o [diretório](#diretório) mostra.

| Endpoint | O que faz |
| - | - |
| `GET` / `PUT` / `DELETE /v3/travel-rule/vasps/{vasp_id}/decision/` | Lê, define ou remove [sua decisão](#sua-decisão-sobre-uma-contraparte) sobre a contraparte. |
| `GET` / `POST /v3/travel-rule/vasps/{vasp_id}/screening/` | Lê sua [triagem da contraparte](#triagem-da-contraparte) mais recente ou executa uma nova. |
| `GET` / `POST /v3/travel-rule/vasps/{vasp_id}/questionnaires/` | Lista seus [questionários de due diligence](#questionário-de-due-diligence) com a contraparte ou envia um. |
| `GET /v3/travel-rule/transfers/?counterparty={vasp_id}` | Suas [transferências com essa contraparte](#transferências-com-uma-contraparte). |

### Pontuação e nível de risco

`dd_score` vai de 0 a 100 e **quanto maior, mais seguro**. Todo resultado indica isso em `dd_score_semantic`, que é sempre `higher_is_safer`. `risk_level` é a faixa em que a pontuação se encaixa:

| `risk_level` | `dd_score` |
| - | - |
| `LOW` | 70 ou mais |
| `MEDIUM` | 40 a 69 |
| `HIGH` | Abaixo de 40 |

A pontuação é a soma de sete componentes. `dd_score_breakdown` mostra cada um como `{points, max, reason, detail}`: `max` é o peso do componente, `reason` é um código legível por máquina que você pode traduzir, e `detail` é uma explicação de uma linha em inglês.

| Componente | Peso | Como pontua | Códigos de `reason` |
| - | - | - | - |
| `jurisdiction` | 25 | Total quando o país da entrada não está na lista padrão de jurisdições de alto risco (`IRN`, `PRK`, `SYR`, `AFG`, `RUS`, `MMR`), nenhum quando está, metade quando o país é desconhecido. | `jurisdiction_not_high_risk`, `jurisdiction_high_risk`, `jurisdiction_unknown` |
| `verification` | 15 | O status de verificação da entrada pela Didit (`dd_status`): total para `COMPLETED`, metade para `IN_PROGRESS`, um quarto para `NOT_STARTED`, nenhum para `REJECTED`. | `dd_status_completed`, `dd_status_in_progress`, `dd_status_not_started`, `dd_status_rejected` |
| `protocol` | 15 | Total quando um canal de protocolo nativo alcança a entrada (um endpoint TRP ou o canal `INTERNAL`), 40 por cento quando apenas o fallback por e-mail alcança, nenhum sem um canal acessível. | `native_rail`, `email_only`, `no_rail` |
| `lei` | 10 | Total com um LEI válido registrado, nenhum sem ele. | `lei_valid`, `lei_missing` |
| `history` | 10 | A proporção das trocas decididas da entrada que tiveram sucesso, metade quando não há nenhuma. | `history`, `no_history` |
| `essentials` | 15 | A proporção das [verificações essenciais](#verificações-essenciais) decididas que passam, metade enquanto nenhuma estiver decidida. | `essential_checks`, `no_essential_checks` |
| `responsiveness` | 10 | Total para `RESPONSIVE`, nenhum para `UNRESPONSIVE`, metade para `UNKNOWN`. Consulte [Capacidade de resposta](#capacidade-de-resposta). | `responsive`, `unresponsive`, `responsiveness_unknown` |

Os pontos são arredondados para uma casa decimal e o total para um número inteiro. `history` lê as mesmas requisições que a [capacidade de resposta](#capacidade-de-resposta), sem janela de tempo: uma troca `COMPLETED` ou `FINISHED` é um sucesso, e uma troca `EXPIRED`, `COUNTERPARTY_MISMATCHED_DATA` ou `COUNTERPARTY_VASP_GENERAL_DECLINE` é uma falha. Um cancelamento é um ato do próprio remetente e nunca conta.

A Didit recalcula a avaliação quando uma troca com a entrada é concluída, finalizada, expira, apresenta divergência ou é recusada, quando ela atualiza ou faz a curadoria da entrada, e para todas as entradas na atualização semanal do diretório. `dd_assessed_at` indica quando ela foi executada pela última vez; uma entrada ainda não avaliada não tem `dd_assessed_at`, tem `dd_score` igual a `0` e `risk_level` vazio, então leia `risk_level` em vez da pontuação bruta. Os membros da rede Didit não são pontuados: o `dd_score` deles é `null`, o `risk_level` é vazio e o `dd_score_breakdown` é vazio.

### Verificações essenciais

`essential_checks` é um relatório curto sobre quatro verificações que a Didit executa em todas as entradas do diretório, apenas a partir das fontes verificadas da plataforma, nunca a partir de dados informados por um cliente:

| `id` da verificação | Passa quando |
| - | - |
| `registration` | Um registro oficial lista o VASP: o registro provisório MiCA da UE de prestadores de serviços de criptoativos, o diretório público TRISA ou o registro global de LEI com um LEI emitido. |
| `licence` | O registro MiCA contém uma autorização para o VASP que não foi encerrada. |
| `domain` | O domínio da entrada corresponde ao seu endpoint TRP ou ao site informado pelo seu registro. |
| `lei` | O registro de LEI da entrada está ativo e emitido, e seu nome legal e país correspondem à entrada. |

Cada verificação em `checks` informa seu `status` (`pass`, `fail` ou `unknown` quando nenhuma fonte registrada consegue decidi-la), um `reason` legível por máquina e um `detail` de uma linha em inglês. `passed`, `failed`, `unknown` e `total` fazem a contagem delas, `level` é `essential`, e `checked_at` indica quando o relatório foi gerado. O componente `essentials` pontua a proporção das verificações decididas que passam, então uma verificação `unknown` não conta nem a favor nem contra a entrada. O relatório fica vazio até que a atualização semanal do diretório verifique uma entrada pela primeira vez, e é sempre vazio para um membro da rede Didit.

### Capacidade de resposta

`responsiveness` indica se o VASP responde às requisições de Travel Rule:

```json theme={null}
{ "status": "UNRESPONSIVE", "answered": 0, "total": 6, "computed_at": "2026-10-12T09:30:00Z" }
```

`total` conta as requisições que os clientes da Didit iniciaram em direção ao VASP nos últimos 90 dias cujo resultado está decidido, e `answered` conta as que ele respondeu:

* **Contadas:** requisições enviadas por um canal de rede ou de protocolo, e requisições enviadas por e-mail para um endereço compartilhado, que é o endereço de conformidade da entrada ou um contato da plataforma.
* **Nunca contadas:** uma requisição enviada por e-mail para um endereço digitado por um cliente ou para um contato privado de um cliente. Essa troca permanece no histórico de transferências do próprio cliente e nunca rotula o VASP para os demais.
* **Respondidas:** `COMPLETED`, `FINISHED`, `COUNTERPARTY_VASP_GENERAL_DECLINE` ou `COUNTERPARTY_MISMATCHED_DATA`. Uma recusa ou uma divergência é uma resposta: o VASP interagiu.
* **Não respondidas:** `EXPIRED`.
* **Nenhuma das duas:** todos os outros status. Uma requisição `CANCELLED` é um ato do próprio remetente, `COUNTERPARTY_VASP_NOT_REACHABLE` pode ser uma falha do lado do remetente, e uma requisição ainda em andamento ainda não está decidida.

| `status` | Quando |
| - | - |
| `UNKNOWN` | Menos de 5 requisições decididas na janela, para que uma única requisição expirada nunca rotule um VASP. |
| `UNRESPONSIVE` | O VASP respondeu a menos de 10 por cento das suas requisições decididas. |
| `RESPONSIVE` | Nos demais casos. |

Os membros da rede Didit respondem dentro da Didit e sempre mostram `UNKNOWN` com contagens zeradas. Aja sobre uma contraparte que não responde com a [política de não resposta](#políticas-de-sunrise-e-de-não-resposta) ou com o [preset](#campos-e-presets-de-regras) `travel-rule-counterparty-unresponsive`.

### Sua decisão sobre uma contraparte

Registre o parecer da sua equipe de conformidade sobre uma contraparte com `PUT /v3/travel-rule/vasps/{vasp_id}/decision/`:

```bash theme={null}
curl -X PUT https://verification.didit.me/v3/travel-rule/vasps/0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91/decision/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"decision": "BLOCKED", "reason": "Unlicensed in its home jurisdiction"}'
```

```json theme={null}
{
  "decision": {
    "decision": "BLOCKED",
    "reason": "Unlicensed in its home jurisdiction",
    "decided_by": "",
    "updated_at": "2026-10-14T10:05:00Z",
    "inherited_from": null
  }
}
```

| `decision` | Significado | Preset que age sobre ela |
| - | - | - |
| `APPROVED` | Sua equipe aprovou a contraparte. | Nenhum |
| `RESTRICTED` | As transferências para ela podem prosseguir após revisão. | `travel-rule-counterparty-restricted` as retém para revisão. |
| `BLOCKED` | Sua equipe recusou a contraparte. | `travel-rule-counterparty-blocked` as recusa. |

* A decisão é privada da sua aplicação: nenhum outro cliente a vê, e ela nunca altera a entrada compartilhada.
* Uma decisão não altera nada por si só e nunca muda a forma como uma transferência é roteada. Ela chega às suas transações por meio do [campo de regra](#campos-e-presets-de-regras) `counterparty_dd_status`: instale os presets ou escreva sua própria regra sobre ele.
* Uma decisão sobre uma marca abrange cada uma das suas [entidades](#marcas-e-suas-entidades) que não tenha decisão própria, e a entidade mostra a marca em `inherited_from`. Uma decisão sobre a entidade substitui a da marca para essa entidade.
* `GET` retorna a decisão que se aplica, ou `{"decision": null}`. `DELETE` remove a sua própria decisão e retorna o que passa a se aplicar: a decisão da marca, no caso de uma entidade, ou então `null`. Ele responde `404` quando sua aplicação não tem decisão própria sobre a contraparte.
* `reason` é opcional, tem até 255 caracteres, e cada `PUT` o substitui. `decided_by` é o usuário do console que tomou ou alterou por último a decisão, e fica vazio quando foi uma chave de API.

### Triagem da contraparte

A triagem da contraparte verifica o próprio VASP da contraparte, como empresa, contra sanções e mídia adversa. Ela é **opcional e cobrada**: ative-a com `counterparty_screening_enabled` nas suas [configurações](#configuração). Enquanto estiver desativada, nada é verificado nem cobrado.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/vasps/0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91/screening/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"refresh": false}'
```

```json theme={null}
{
  "outcome": "screened",
  "screening": {
    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
    "status": "In Review",
    "total_hits": 2,
    "score": 85.0,
    "screened_at": "2026-10-14T09:58:00Z",
    "fresh": true,
    "flagged": true
  }
}
```

* **Faturamento.** Cada nova triagem custa o [preço](https://docs.didit.me/pt-br/getting-started/pricing.md) de Análise AML de empresas da sua organização. `GET /v3/travel-rule/vasps/{vasp_id}/screening/` retorna esse `price`, `fresh_days` e se a triagem está `enabled`, sem custo. Uma triagem com menos de 30 dias é recente: `POST` a retorna novamente com `200` e `outcome: reused` e não cobra nada, a menos que você envie `refresh: true`. Uma nova triagem responde `201` com `outcome: screened`. Aplicações de sandbox nunca são verificadas nem cobradas.
* **Triagem automática.** Com a triagem ativada, a Didit também verifica a contraparte alcançada por uma troca de saída quando a troca começa, antes de suas regras avaliarem a transação, com a mesma reutilização e o mesmo faturamento. Uma recusa ou falha nesse ponto nunca faz a transferência falhar.
* **Resultado.** `status` é `Approved` quando nenhuma possível correspondência exige atenção, e `In Review` ou `Declined` para uma possível correspondência em sanções ou mídia adversa. `flagged` é `true` enquanto uma triagem recente estiver `In Review` ou `Declined`.
* **Efeito.** Enquanto sua triagem mais recente de uma contraparte estiver sinalizada e a triagem permanecer ativada, `counterparty_risk_level` é `HIGH` nas suas regras, de modo que o preset `travel-rule-counterparty-high-risk`, uma vez instalado, retém as transferências dela. O `risk_level` compartilhado no diretório não muda.
* **Privacidade.** A triagem é privada da sua aplicação: nenhum outro cliente a vê, e ela nunca altera a entrada compartilhada. O diretório mostra a mais recente como `entity_screening`.
* **Recusas.** `409` quando a triagem está desativada, para uma aplicação de sandbox ou enquanto uma triagem da mesma contraparte já estiver em andamento. `403` com `code: insufficient_credits` quando seu saldo não cobre o preço. `502` quando a triagem não pôde ser concluída. Nenhuma delas gera cobrança.

### Questionário de due diligence

Solicite a uma contraparte suas respostas de due diligence com o questionário padrão da Didit. `POST /v3/travel-rule/vasps/{vasp_id}/questionnaires/` o envia por e-mail para um endereço de conformidade registrado da contraparte, com um link de uso único para uma página de respostas:

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/vasps/0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91/questionnaires/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sent_to": "travelrule@counterparty.example"}'
```

```json theme={null}
{
  "id": "3f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
  "status": "SENT",
  "form_version": "1",
  "sent_to": "travelrule@counterparty.example",
  "sent_at": "2026-10-14T10:00:00Z",
  "expires_at": "2026-11-13T10:00:00Z",
  "answered_at": null,
  "valid_until": null,
  "current": false,
  "answers": {}
}
```

* **Para onde vai.** `sent_to` deve ser um endereço de conformidade registrado: para uma entrada do diretório, seu endereço de conformidade ou um contato que sua aplicação vê em `contacts`; para um membro da rede Didit, seu e-mail de conformidade confirmado. Omita-o para usar o endereço para o qual vai um e-mail de Travel Rule à contraparte: primeiro o seu próprio contato, depois um contato da plataforma e, por fim, o endereço de conformidade da entrada. A Didit nunca envia o questionário para nenhum outro lugar e responde `400` quando a contraparte não tem endereço de conformidade registrado.
* **Respostas.** O link abre `/v3/travel-rule/questionnaires/{token}/`, uma página para uma pessoa da contraparte que não exige conta nem chave de API. Ela responde a todas as perguntas, com até 2.000 caracteres cada (`N/A` quando uma não se aplica), e envia uma única vez. Uma contraparte também pode enviar `{"answers": {"<question id>": "<answer>"}}` para o mesmo link. Um link que já foi usado, foi substituído ou passou do prazo mostra uma página de expiração. O e-mail e a página são traduzidos; as perguntas em si estão sempre em inglês, para que seu significado nunca mude entre idiomas.
* **Prazos.** A contraparte tem 30 dias para responder (`expires_at`). As respostas permanecem válidas por 365 dias (`valid_until`), e `current` é `true` até lá. Um questionário sem resposta após o prazo, e respostas após sua validade, passam a `EXPIRED`.
* **Um questionário aberto por contraparte.** Um novo envio substitui seu questionário anterior sem resposta para a mesma contraparte: ele passa a `EXPIRED` e seu link deixa de funcionar. Um e-mail por minuto pode ser enviado a um endereço; um envio mais rápido responde `429`.
* **Leitura das respostas.** `GET /v3/travel-rule/vasps/{vasp_id}/questionnaires/` lista seus questionários com a contraparte, do mais recente para o mais antigo, com `answers` indexado pelo id da pergunta depois de respondido. O diretório os mostra como `questionnaires`. Eles são privados da sua aplicação.

A versão `1` do formulário faz estas doze perguntas:

| ID da pergunta | Pergunta |
| - | - |
| `legal_name` | Razão social da pessoa jurídica e jurisdição de constituição. |
| `licensing` | Licenças ou registros mantidos para serviços de ativos virtuais: regulador, número da licença e status em cada jurisdição. |
| `jurisdictions` | Jurisdições em que você opera e aquelas em que você é excluído ou sofre restrições. |
| `aml_program` | Resumo do seu programa de PLD/FT (AML/CFT): políticas, procedimentos e data da última auditoria ou revisão independente. |
| `compliance_officer` | Nome e função do seu responsável por conformidade e como contatá-lo. |
| `sanctions_screening` | Como você verifica clientes e contrapartes em relação a sanções e mídia adversa: provedor ou listas, frequência e escalonamento. |
| `transaction_monitoring` | Como você monitora transações em busca de atividade suspeita: ferramentas, limiares e prática de comunicação às autoridades. |
| `travel_rule` | Como você cumpre a Travel Rule: protocolos e redes utilizados e seu tempo de resposta típico a uma requisição. |
| `custody` | Arranjos de custódia dos ativos de clientes: custodiante qualificado, seguro e segregação. |
| `ownership` | Beneficiários finais com 25 por cento ou mais e qualquer entidade controladora ou guarda-chuva. |
| `record_keeping` | Prática de manutenção de registros e período de retenção dos dados da Travel Rule e de transações. |
| `data_protection` | Como você protege os dados pessoais compartilhados para fins de conformidade e onde eles são armazenados. |

### Transferências com uma contraparte

[`GET /v3/travel-rule/transfers/?counterparty={vasp_id}`](https://docs.didit.me/pt-br/management-api/travel-rule/list-transfers) lista as transferências da Travel Rule da sua aplicação com uma contraparte, das mais recentes para as mais antigas, pelo `id` exibido no diretório: as suas transferências cuja contraparte é essa entrada do diretório ou as suas trocas `INTERNAL` com esse membro da rede Didit. Um valor que não seja um ID válido retorna `400`.
Cada linha traz `reason` logo depois de `status`: o próprio [`reason`](#por-que-uma-transferência-fica-travada) da transferência, para que a lista diferencie um e-mail de conformidade devolvido de uma contraparte sem rota sem que seja preciso abrir cada transferência.

### Políticas de sunrise e de não resposta

Quando uma transferência expira (`confirmation_timeout_hours` se esgotou enquanto ela estava em `AWAITING_COUNTERPARTY`), `timeout_outcome` decide o que acontece com a transação correspondente. Duas configurações permitem tratar de forma diferente dois motivos comuns de expiração:

| Configuração | Aplica-se quando a contraparte é uma entrada do diretório que |
| - | - |
| `sunrise_policy` | Está em uma jurisdição listada em `sunrise_jurisdictions`: um país que ainda não aplica a Travel Rule, de modo que o VASP não é obrigado a responder. |
| `non_responsive_policy` | Tem `responsiveness.status` igual a `UNRESPONSIVE`. |

Ambas aceitam `HOLD`, `REJECT` ou `PROCEED`, com o mesmo significado que têm em `timeout_outcome`, ou uma string vazia para seguir `timeout_outcome`. Ambas ficam vazias por padrão, então nada muda até que você defina uma delas:

```bash theme={null}
curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sunrise_policy": "PROCEED", "non_responsive_policy": "HOLD"}'
```

A primeira das opções a seguir que se aplicar decide o resultado:

1. `sunrise_policy`, quando está definida e a jurisdição da contraparte está em `sunrise_jurisdictions`.
2. `non_responsive_policy`, quando está definida e a contraparte está `UNRESPONSIVE`.
3. `timeout_outcome` em todos os outros casos, inclusive em uma transferência para um membro da rede Didit ou para uma contraparte sem entrada no diretório.

`sunrise_jurisdictions` é somente leitura e atualmente vale `["CO", "KH", "VN"]`. Apenas esses países são considerados em período de sunrise: qualquer outra jurisdição, assim como uma vazia ou desconhecida, segue `timeout_outcome`, de modo que uma contraparte nunca recebe a sua política de sunrise por acidente. A linha do tempo da transferência expirada informa o resultado aplicado, por exemplo `sunrise_policy=PROCEED (counterparty jurisdiction CO does not enforce the Travel Rule yet)`. Suas regras continuam sendo executadas após a expiração, portanto uma regra como a `tr_eu_expired_review` do EU TFR ainda pode mover a transação para revisão com `PROCEED`.

### Campos e presets de regras

Quatro campos de [regra](https://docs.didit.me/pt-br/transaction-monitoring/rules.md) contêm o que a sua aplicação sabe sobre a contraparte alcançada pela troca da Travel Rule de uma transação: a entrada dela no diretório ou, em uma troca `INTERNAL`, o cliente Didit que a recebeu. Cada campo fica vazio quando a troca não alcançou nenhuma contraparte conhecida.

| Campo | Valor |
| - | - |
| `counterparty_dd_status` | A sua [decisão](#sua-decisão-sobre-uma-contraparte): `APPROVED`, `RESTRICTED` ou `BLOCKED`, com uma entidade seguindo a decisão da sua marca. Vazio quando você não tomou nenhuma. Nunca a decisão de outro cliente. |
| `counterparty_risk_level` | O `risk_level` da entrada (`LOW`, `MEDIUM` ou `HIGH`), ou `HIGH` enquanto a sua própria [triagem](#triagem-da-contraparte) da contraparte estiver sinalizada. Vazio para uma entrada ainda não avaliada e para um membro da rede Didit, a menos que a sua triagem dele esteja sinalizada. |
| `counterparty_jurisdiction` | O país da contraparte, obtido da entrada do diretório ou do perfil do membro da rede Didit. Códigos ISO-2 e ISO-3 são comparados, como nos outros campos de país. |
| `counterparty_responsiveness` | O `responsiveness.status` da entrada: `RESPONSIVE`, `UNRESPONSIVE` ou `UNKNOWN`. Vazio para um membro da rede Didit. |

Cinco presets do pacote `travel_rule` atuam sobre esses campos. Instale-os em **Transactions → Rules → Library** no Business Console ou com a [API da biblioteca de regras](https://docs.didit.me/pt-br/management-api/transactions/rules-install.md):

| `library_key` | Gatilho | Ação padrão |
| - | - | - |
| `travel-rule-counterparty-blocked` | `counterparty_dd_status` é `BLOCKED` | +90 de pontuação, `DECLINED` |
| `travel-rule-counterparty-restricted` | `counterparty_dd_status` é `RESTRICTED` | +50 de pontuação, `IN_REVIEW` |
| `travel-rule-counterparty-high-risk` | `counterparty_risk_level` é `HIGH` | +40 de pontuação, `IN_REVIEW` |
| `travel-rule-counterparty-high-risk-jurisdiction` | `counterparty_jurisdiction` está na lista padrão de alto risco (`IRN`, `PRK`, `SYR`, `AFG`, `RUS`, `MMR`) | +60 de pontuação, `IN_REVIEW` |
| `travel-rule-counterparty-unresponsive` | `counterparty_responsiveness` é `UNRESPONSIVE` | +30 de pontuação, `IN_REVIEW` |

Os cinco se aplicam somente a transações da Travel Rule.

## Webhooks

Inscreva um destino no evento `travel_rule.status.updated` para ser notificado a cada transição de status de cada transferência da sua aplicação, de saída e de entrada, incluindo os trechos pela rede `INTERNAL`.
O roteamento é executado após a resposta à criação da transação, então resultados como `COUNTERPARTY_VASP_NOT_FOUND`, `COUNTERPARTY_VASP_NOT_REACHABLE` ou uma troca `INTERNAL` que é liquidada imediatamente chegam até você por esse evento, e não na resposta de criação.

```json theme={null}
{
  "event_id": "9c0c8b8a-1111-4222-9333-666666666666",
  "webhook_type": "travel_rule.status.updated",
  "timestamp": 1774970000,
  "created_at": 1774970000,
  "application_id": "11111111-2222-3333-4444-555555555555",
  "environment": "live",
  "transaction_id": "22222222-3333-4444-5555-666666666666",
  "txn_id": "trv-2026-07-05-001",
  "travel_rule_status": "COMPLETED",
  "rail": "INTERNAL",
  "direction": "OUTBOUND"
}
```

`rail` fica vazio até que um trilho seja selecionado.
Para uma mesma transação, a Didit envia `travel_rule.status.updated` depois de `transaction.created`: quando a Didit cria a transação (seu `POST /v3/transactions/`, um registro de sunrise, uma consulta `TRP` de entrada ou a perna de entrada do trilho `INTERNAL`), ela envia `transaction.created` primeiro.
Cada evento é entregue e reenviado de forma independente, então um `transaction.created` que precisou ser reenviado ainda pode chegar depois de um evento de status: indexe seu handler por `transaction_id` e consulte a transação quando um evento de status mencionar uma que você ainda não viu.
Uma transferência enviada por `TRUST` não recebe evento `COMPLETED`: o TRUST não devolve nada que a Didit consiga ler, então, a menos que o envio falhe ou você o cancele, seu último evento é `EXPIRED`. Em `GTR`, `VERIFYVASP` e `SYGNA`, o evento segue a resposta que a Didit lê da rede.
Aplicações de sandbox também enviam esse evento, com `"environment": "sandbox"`; uma transferência respondida pelo [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) inclui `rail: "TEST_VASP"`, `test_vasp: true` e `test_vasp_scenario`.

Consulte o [guia de webhooks](https://docs.didit.me/pt-br/integration/webhooks.md#tipos-de-evento) para ver o catálogo completo de eventos, a verificação de assinatura e a política de novas tentativas.

## Preços

A tarifa da Travel Rule é de **\$0.02 por troca de saída iniciada**, cobrada uma única vez quando a transação é criada, independentemente de quantas transições de status a troca tenha depois. Um `resend` nunca gera nova cobrança.

* Ela se aplica a uma transação `travelRule` de saída em uma aplicação com a Travel Rule ativada, cujo valor seja igual ou superior ao seu `threshold_amount`, de modo que a Didit inicia uma troca gerenciada para ela. Uma transferência para uma carteira autocustodiada, ou para a própria carteira verificada do seu usuário, também conta: a prova de propriedade é a sua troca.
* Toda outra transação de saída que carrega dados da Travel Rule é faturada como Triagem de transações padrão, que o seu plano inclui até a sua [franquia mensal de transações](https://docs.didit.me/pt-br/getting-started/pricing.md#monitoramento-de-transações-kyt) e cobra a \$0.001 além dela: uma transferência abaixo do seu limiar, um pagamento Lightning ao qual a Travel Rule não se aplica e uma transferência registrada passivamente enquanto a Travel Rule está desativada. Uma transação é faturada em uma das duas linhas, nunca nas duas.
* Transações `travelRule` de entrada não têm tarifa de Travel Rule nem de monitoramento: a transação de entrada que a Didit cria na aplicação do beneficiário pelo trilho `INTERNAL`, as consultas `TRP` de entrada e os [registros após o depósito](#registro-sunrise-após-o-depósito).
* Uma aplicação que aderiu à Travel Rule gratuitamente não paga nenhuma das duas tarifas em transações `travelRule` de saída até ativar o faturamento de saída com `POST /v3/travel-rule/workspace/billing/`; o recebimento continua gratuito.
* Aplicações de sandbox nunca são cobradas.
* A tarifa da Travel Rule é de $0.02 e a Triagem de transações custa $0.001 além da sua franquia. Cada transação é cobrada pelo preço da linha em que é faturada.
* Se a triagem de AML cripto e de carteiras também for executada na mesma transação (por exemplo, um depósito de entrada com `currency_kind: "crypto"` e monitoramento ativado), ela é faturada separadamente pela tarifa padrão de Verificação e triagem de carteiras; não está incluída na tarifa da Travel Rule.
* A [triagem de contrapartes](#triagem-da-contraparte) é opcional e faturada separadamente, pelo preço da Análise AML de empresas por triagem; uma triagem com menos de 30 dias é reutilizada sem custo. Decisões, questionários e a avaliação de due diligence do diretório não custam nada.

### Preços da atribuição

A [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) exige uma consulta de carteira junto ao provedor de análise, e você sempre recebe o valor completo dessa consulta:

* **O monitoramento cripto já fez a triagem da carteira nesta transação**: o resultado armazenado é reutilizado. Uma chamada de análise, uma cobrança de Verificação e triagem de carteiras (a já efetuada pelo monitoramento cripto). A atribuição não acrescenta nada.
* **O monitoramento cripto não foi executado**: a Didit faz a chamada de análise necessária uma única vez e repassa todo o seu valor: a transação é cobrada pela tarifa padrão de Verificação e triagem de carteiras (\$0.15 com análise gerenciada pela Didit) e recebe em troca o resultado completo da triagem cripto (pontuação de risco, categoria de risco da carteira, snapshot da rede), e não apenas o nome do VASP. O item de uso é marcado com o gatilho `travel_rule_attribution` para que a cobrança seja explicável.
* **Chave de análise própria**: a mesma tarifa de plataforma que se aplica ao monitoramento cripto com a sua própria chave se aplica aqui (\$0.02 por chamada). O seu provedor cobra a consulta subjacente diretamente de você.
* **Consultas com falha nunca são cobradas**, reenvios reutilizam a atribuição registrada sem nova chamada nem cobrança, e aplicações de sandbox nunca são cobradas.

Assim, uma transferência de saída que precisou de atribuição custa \$0.02 (Travel Rule) + uma cobrança de Verificação e triagem de carteiras; e, quando os dois produtos estão ativados, a chamada de análise e a sua cobrança acontecem apenas uma vez.

## Pacote de regras EU TFR

Quatro regras predefinidas vêm no pacote `travel_rule_eu_tfr`, criadas especificamente para as obrigações do EU TFR.
Como qualquer outro [pacote predefinido](https://docs.didit.me/pt-br/transaction-monitoring/rules-library.md), ative-o no Business Console em **Transactions → Rules → Library**.

| Regra (`library_key`) | Gatilho | Ação |
| - | - | - |
| `tr_eu_mismatch_hold` | O status da transferência é `COUNTERPARTY_MISMATCHED_DATA` | Pontuação `+50`, transação definida como `IN_REVIEW` |
| `tr_eu_unverified_selfhosted_review` | O status da transferência é `UNCONFIRMED_OWNERSHIP` e o valor na moeda padrão é de pelo menos `1000` | Transação definida como `IN_REVIEW` |
| `tr_eu_vasp_not_found_score` | O status da transferência é `COUNTERPARTY_VASP_NOT_FOUND` | Pontuação `+25`, com a tag `travel-rule-sunrise` |
| `tr_eu_expired_review` | O status da transferência é `EXPIRED` | Transação definida como `IN_REVIEW` |

Essas regras disparam em toda transição relevante: na criação da transferência, na confirmação de propriedade, na resposta à coleta por e-mail e na varredura de expiração. Assim, uma transferência que nunca é resolvida ainda aparece para revisão de conformidade, em vez de ser liquidada silenciosamente.

## Por que isso funciona melhor em uma única plataforma

A conformidade com a Travel Rule é um problema de identidade disfarçado de problema de pagamentos, e a Didit já já tem os dados de identidade:

* **Dados verificados disponíveis.** O titular de cada transferência está vinculado por `vendor_data` ao perfil KYC que a Didit verificou no onboarding (OCR do documento, prova de vida, correspondência facial), então você pode montar `originator_data` a partir de campos verificados na mesma plataforma.
  Para um usuário com uma verificação KYC aprovada, a Didit transmite a identidade verificada em vez dos valores que você digitou (veja [Dados verificados e procedência](#dados-verificados-e-procedência)).
* **Biometria adicional para transferências de risco.** Uma [regra](https://docs.didit.me/pt-br/transaction-monitoring/rules.md) pode reter qualquer transferência de alto valor até que o usuário passe por uma nova verificação biométrica em comparação com o rosto capturado no onboarding, a resposta mais forte possível ao sequestro de conta no momento do saque. Veja o [exemplo prático](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md#exemplo-biometria-adicional-para-um-saque-de-alto-valor).
* **Um único grafo de dispositivos.** As transferências enviadas pelo SDK trazem a mesma inteligência de dispositivo das sessões de KYC, então "novo dispositivo + valor alto + beneficiário pela primeira vez" é uma única regra, e não um join no data warehouse.
* **Triagem, regras, casos e a troca em um só lugar.** A triagem de carteiras que identifica a VASP da contraparte é a mesma triagem que suas regras e seus analistas veem: uma cobrança, um console, uma trilha de auditoria.
* **Preços publicados.** [\$0.02 por intercâmbio de saída](#preços), sem níveis de volume, sem necessidade de falar com vendas.

## Perguntas frequentes

### Como funciona a troca

> [accordion] A Didit executa a troca VASP a VASP por conta própria ou apenas registra os dados da Travel Rule depois que outra rede conclui o handshake?
>
> A própria Didit executa a troca.
> Quando você envia uma transferência `travelRule`, a Didit faz a descoberta da contraparte em tempo real, envia os dados do remetente e do beneficiário ao VASP de destino pelos trilhos que os transportam e só marca a transferência como `COMPLETED` quando o lado da contraparte a confirma. É um handshake gerenciado, não um registro feito após a liquidação.
> A resposta da contraparte é processada em todos os trilhos, exceto `TRUST`, que apenas envia; por isso, uma transferência por ele expira em vez de ser concluída. Em `GTR`, `VERIFYVASP` e `SYGNA`, a Didit lê a resposta na resposta da rede ou consultando-a a cada 5 minutos, e nenhuma troca por esses trilhos foi concluída ainda contra uma rede em produção; em `TRP`, uma resposta que a contraparte não dá de imediato depende do host TRP público da Didit, que ainda não está no ar (consulte [Redes da Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md)).
> A Didit também mantém o registro completo e o status de conformidade de cada troca (um [ciclo de vida](#ciclo-de-vida) com 13 estados, [webhooks](#webhooks) e uma trilha de auditoria).
> Se você preferir conduzir a Travel Rule pelo seu próprio processo, a Didit pode, em vez disso, registrar os dados de forma passiva como seu sistema de registro único (consulte a pergunta sobre registro passivo abaixo).
> Os dois modos estão disponíveis: a troca ativa é executada quando você define `is_enabled: true` nas [configurações](#configuração) (o padrão é `false`) e, até lá, a Didit registra os dados de forma passiva.

> [accordion] A troca é nativa da Didit ou depende de um provedor externo de interoperabilidade (Notabene, Sygna, VerifyVASP, TRP)?
>
> É nativa. A Didit executa sua própria implementação do Travel Rule Protocol (TRP), servida em `trp.didit.me` assim que esse host público estiver no ar (ele ainda não responde, então hoje as contrapartes não conseguem alcançar você pelo TRP), e implementa diretamente os protocolos das redes do setor: `GTR` (Global Travel Rule), `TRUST`, `VerifyVASP` e `Sygna Bridge` (implementado de forma nativa, incluindo o IVMS 101 criptografado com ECIES e as requisições de permissão assinadas da Sygna). A Didit não revende uma única camada de interoperabilidade de terceiros. Alcançar uma contraparte que está em uma rede de filiação específica acontece necessariamente por essa rede, pois não existe um canal universal único na Travel Rule, mas a descoberta, o handshake, a verificação e a manutenção de registros são todos executados pela Didit.
> Hoje, todos os trilhos de rede exigem sua própria filiação, e `TRUST` apenas envia: consulte a [Visão geral](#visão-geral).

> [accordion] Quais redes e protocolos da Travel Rule a Didit suporta?
>
> Implementados de forma nativa, tentados em ordem estrita de prioridade: `INTERNAL` (os dois VASPs na Didit), `TRP` (OpenVASP Travel Rule Protocol), `GTR`, `TRUST`, `VerifyVASP`, `Sygna Bridge` e um fallback por `EMAIL` para contrapartes sem ferramentas.
> Hoje, os trilhos de rede exigem sua própria filiação, `TRUST` apenas envia e o recebimento por uma rede ainda não está ativado: consulte [Redes da Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md).
> CODE, TRISA, Notabene e Veriscope aparecem no Marketplace da Didit como blocos de solicitação de acesso, ainda sem integração.
> Consulte [Como a Didit roteia uma troca](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-interoperability.md#como-a-didit-roteia-uma-transferência) para ver a tabela de roteamento completa e [Redes da Travel Rule](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md) para saber o que cada uma alcança hoje.

> [accordion] Qual rede devo usar e preciso ter minhas próprias filiações?
>
> `TRP` é a base que recomendamos: não exige filiação compartilhada, pois compartilhar seu [Travel Address](#endereços-de-viagem) permite que qualquer VASP que fale TRP alcance você. Quando uma contraparte é conhecida apenas pelo endereço da carteira, a [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain) a roteia pelo TRP somente se a entrada atribuída no diretório já tiver um endpoint TRP.
> No envio, a Didit transmite por ele os ativos listados em [Identificadores de ativos TRP](#identificadores-de-ativos-trp), e uma contraparte que não responde de imediato depende do host TRP público da Didit, que ainda não está no ar.
> Para redes de filiação, escolha de acordo com onde suas contrapartes operam: a GTR oferece ampla cobertura global, a TRUST é voltada para VASPs dos EUA e a VerifyVASP (que agora também opera a Sygna Bridge) tem forte cobertura na Ásia.
> Sim, hoje você precisa da sua própria filiação: a Didit ainda não tem filiação de plataforma nessas redes e está em processo de onboarding como provedor.
> Conecte sua filiação em **Marketplace**; você não fica preso a uma única rede.
> Lembre-se de que `TRUST` apenas envia, então uma transferência por ela não é concluída, e de que nenhuma troca por uma rede foi concluída ainda contra uma rede em produção.

> [accordion] Como a Didit encontra o VASP da contraparte quando tenho apenas um endereço de carteira?
>
> Por meio de uma cadeia de resolução: outro cliente da Didit que comprovou o controle da carteira (o trilho `INTERNAL`), seu próprio [catálogo de endereços de carteiras](#catálogo-de-endereços-de-carteiras) com um Travel Address armazenado, depois os trilhos de protocolo e de rede e, por fim, a [atribuição por análise de blockchain](#atribuição-por-análise-de-blockchain).
> Se a transferência trouxer apenas uma carteira de destino, a Didit a resolve com dados de análise de blockchain para atribuir a exchange ou o serviço de custódia da contraparte e o cataloga no [diretório de VASPs](#diretório).
> A transferência só é roteada automaticamente se essa entrada no diretório já tiver uma rota, como um endpoint `TRP`; caso contrário, ela termina em `COUNTERPARTY_VASP_NOT_FOUND` com o nome da contraparte registrado, e você pode reenviá-la quando houver uma rota, por exemplo depois de armazenar o `travel_address` da contraparte na entrada do seu catálogo de endereços para essa carteira (para os ativos listados em [Identificadores de ativos TRP](#identificadores-de-ativos-trp)).

### Preços e licenciamento

> [accordion] Quanto custa a Travel Rule e ela está incluída no meu plano de KYC ou de verificação?
>
> A Travel Rule é um produto separado, cobrado por uso.
> Ela não vem incluída na verificação de identidade.
> Custa \*\*$0.02 por troca de envio iniciada** ([preços publicados](#preços), sem níveis por volume, sem necessidade de falar com vendas).
>         Quando o roteamento precisa de uma consulta de análise de blockchain para identificar o VASP da contraparte, essa consulta é cobrada uma única vez pela [tarifa de atribuição](#preços-da-atribuição): a partir de $0.15 no modo gerenciado, ou \$0.02 com uma chave de provedor já existente.
> Ela não é cobrada novamente se o monitoramento de cripto já tiver analisado a mesma carteira.
> Uma transferência abaixo do seu limiar, ou registrada enquanto a Travel Rule está desativada, é cobrada como Transaction Screening; transferências recebidas, como as transferências que a Didit cria no lado do beneficiário, não são cobradas com a tarifa da Travel Rule.

> [accordion] Serei cobrado em dobro quando a Travel Rule e o monitoramento de cripto forem executados juntos?
>
> Não.
> Uma transação `travelRule` é cobrada em uma única linha: a tarifa da Travel Rule (\$0.02) quando ela inicia uma troca de envio e, caso contrário, o Transaction Screening padrão. A consulta de análise de blockchain é cobrada uma única vez: se o monitoramento de cripto já tiver analisado a carteira de destino na transação, a [atribuição](#atribuição-por-análise-de-blockchain) reutiliza esse resultado armazenado sem custo adicional.
> As transferências de recebimento que a Didit cria no lado do beneficiário nunca são cobradas com a tarifa da Travel Rule.

> [accordion] A Didit pode fornecer documentação ou uma declaração de capacidades para o meu processo de licenciamento de VASP ou para o regulador?
>
> Sim. Os recursos de KYT e monitoramento de transações, triagem de AML e sanções, risco de carteiras por análise de blockchain e Travel Rule da Didit estão todos documentados publicamente em docs.didit.me, e você pode citar essas páginas livremente em um processo regulatório. Para uma declaração formal de capacidades do produto adaptada a uma submissão específica, por exemplo um pedido de licença de VASP junto à AIFC/AFSA, sob o MiCA ou outro, entre em contato com a equipe responsável pela sua conta na Didit informando o formato exigido pelo seu regulador.

### Operações e dados

> [accordion] O que acontece com transferências abaixo do meu limiar?
>
> Elas são resolvidas imediatamente como `NOT_APPLICABLE`: nenhum rail é acionado e nenhum dado de identidade sai da Didit.
> A transação é cobrada como triagem de transações padrão, e não pela tarifa da Travel Rule.
> A Didit compara o limiar com o valor convertido para a moeda padrão da sua aplicação.
> Se a Didit não conseguir converter o valor, o limiar não é aplicado e a transferência segue pelo processo de troca.
> O TFR da UE não tem valor mínimo, então CASPs da UE devem manter `threshold_amount` em `0.00`.

> [accordion] E se a contraparte nunca responder?
>
> A transferência fica em `AWAITING_COUNTERPARTY` até que `confirmation_timeout_hours` se esgote. Em seguida, um processo de varredura a move para `EXPIRED` e aplica o seu `timeout_outcome` à transação subjacente: `HOLD` para revisão, `REJECT` para recusar ou `PROCEED` para deixá-la intacta. A regra predefinida `tr_eu_expired_review` também exibe toda expiração para os seus analistas. Uma contraparte que nunca chega a receber a mensagem é um caso diferente: a Didit tenta novamente o envio e, após a sexta tentativa malsucedida, a transferência passa para `COUNTERPARTY_VASP_NOT_REACHABLE` (veja [Entrega e novas tentativas](#entrega-e-novas-tentativas)).

> [accordion] Minha contraparte não tem nenhuma ferramenta de Travel Rule. Ainda consigo estar em conformidade?
>
> Sim, para isso existe o rail `EMAIL`. O contato de conformidade da contraparte recebe um link de acesso de uso único e pode confirmar ou recusar a troca de dados em uma página hospedada, sem conta na Didit, sem chave de API e sem integração. Para depósitos que já foram liquidados antes que qualquer troca fosse possível, use o [registro sunrise após o depósito](#registro-sunrise-após-o-depósito).

> [accordion] Como funcionam os saques para a carteira do próprio usuário?
>
> Declare o destino como uma carteira autocustodiada (`payment_method.method_type: "unhosted_wallet"`). A Didit ignora o roteamento entre VASPs e, em vez disso, coleta a prova de que o seu cliente controla a carteira (assinatura de mensagem, teste Satoshi, captura de tela ou autodeclaração) por meio do [widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md). Essa é a obrigação do TFR da UE para carteiras autocustodiadas em forma de API.

> [accordion] Os dados pessoais da contraparte ficam protegidos durante a troca?
>
> Sim.
> Até que a propriedade da carteira seja confirmada do seu lado, os dados pessoais da contraparte em uma transferência de entrada ficam mascarados, tanto no objeto da transferência quanto na parte referente à contraparte na transação (veja [Dados mascarados da contraparte](#dados-mascarados-da-contraparte)).
> As páginas de retirada por e-mail mostram apenas o resumo da transferência (nome do VASP remetente, valor, carteira de destino), nunca os payloads de dados pessoais.
> As trocas pelos rails são feitas via HTTPS, e os rails de rede (`GTR`, `TRUST`, `VERIFYVASP`, `SYGNA`) também criptografam o payload IVMS com a chave pública do VASP receptor.

> [accordion] Já acompanho a conformidade com a Travel Rule com meu próprio processo. Posso apenas registrá-la?
>
> Sim. Com a Travel Rule desativada, quaisquer `travel_rule_details` que você enviar (incluindo um `status` informado por você, atual ou legado) são registrados passivamente na transação: nenhum rail é acionado e nada é negociado. Use isso para preencher dados retroativamente ou executar seu próprio processo, mantendo um único sistema de registro.

> [accordion] Como testo isso antes de entrar em produção?
>
> Use uma aplicação de sandbox com a Travel Rule ativada. O sandbox ignora regras, faturamento e os webhooks `transaction.created` e `transaction.status.updated`, e toda troca de **saída** vai para o [Didit Test VASP](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md) no rail `TEST_VASP`, que responde dentro da Didit com o cenário que você escolher: aceitar, recusar, divergência de nome, inalcançável, tempo esgotado ou carteira autocustodiada. Você recebe webhooks `travel_rule.status.updated` marcados com `environment: sandbox`, e nenhuma mensagem chega a uma contraparte real.
> Para **entrada**, peça ao VASP de teste que envie uma transferência para você com [Trigger Test VASP Inbound Transfer](https://docs.didit.me/pt-br/management-api/travel-rule/trigger-test-vasp-inbound.md), ou registre uma com `POST /v3/travel-rule/inbound/`; ambas têm a decisão determinada com base no seu catálogo de endereços de carteira: `ON_HOLD`, `UNCONFIRMED_OWNERSHIP`, `COUNTERPARTY_MISMATCHED_DATA` ou `COMPLETED` e depois `FINISHED`.
> Para uma troca entre duas partes com outra aplicação real, use duas das suas próprias aplicações em **produção** no rail `INTERNAL`: a receptora deve ser localizável e provar o controle da carteira de destino com uma mensagem assinada ou um depósito de teste.

## Próximos passos

> [card] [Widget de propriedade de carteira](https://docs.didit.me/pt-br/transaction-monitoring/wallet-ownership-widget.md)
>
> Prove que um cliente controla uma carteira por assinatura, teste Satoshi, captura de tela ou autodeclaração.

> [card] [Interoperabilidade](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-interoperability.md)
>
> Os endpoints voltados à contraparte que outros VASPs usam para chegar até você: TRP, callbacks, retirada por e-mail, sunrise.

> [card] [Redes](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-networks.md)
>
> O que cada rail e rede alcança hoje e o que ainda depende de uma adesão.

> [card] [Teste no sandbox](https://docs.didit.me/pt-br/transaction-monitoring/travel-rule-sandbox.md)
>
> Teste todos os resultados com o Didit Test VASP antes de entrar em produção.

> [card] [Envio de transações](https://docs.didit.me/pt-br/transaction-monitoring/transactions.md)
>
> Como incluir dados da Travel Rule no payload de Create Transaction.

> [card] [Biblioteca de regras](https://docs.didit.me/pt-br/transaction-monitoring/rules-library.md)
>
> O catálogo completo de regras predefinidas, incluindo o pacote da Travel Rule.

> [card] [Webhooks](https://docs.didit.me/pt-br/integration/webhooks.md)
>
> Assine travel\_rule.status.updated e todas as outras famílias de eventos.

> [card] [Guia do console](https://docs.didit.me/pt-br/transaction-monitoring/console.md)
>
> Visualização do status da Travel Rule na tela de detalhes da transação.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.