> ## 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.

# Travel Rule Interoperability

> The counterparty-facing side of Didit's Travel Rule: travel addresses, public TRP endpoints, callbacks, email pickup, and sunrise registration for VASPs exchanging with a Didit customer.

This page is for the **other side** of a [Didit Travel Rule](/transaction-monitoring/travel-rule) exchange: the counterparty VASP (or its engineering team) that needs to send Travel Rule data to, or receive it from, a VASP that runs on Didit.

Everything documented here is public infrastructure operated by Didit.
You do not need a Didit account, an API key, or any commercial relationship with Didit to interoperate - the deepest integration requires only HTTPS and JSON.

## How Didit routes an exchange

When a Didit customer sends a transfer, Didit tries these rails in strict priority order and uses the first one that can reach you:

| Priority | Rail         | What it means for you                                                                                                                                                                            |
| -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1        | `INTERNAL`   | Both VASPs run on Didit - the exchange settles inside the platform and no external call is made.                                                                                                 |
| 2        | `TRP`        | You expose a Travel Rule Protocol (TRP) endpoint, or the Didit customer knows your [travel address](#travel-addresses). Didit calls your TRP inquiry endpoint machine-to-machine.                |
| 3        | `GTR`        | A Global Travel Rule (GTR) membership is active for the sender (their own, or Didit's platform membership) and you are addressable by a GTR VASP code.                                           |
| 4        | `TRUST`      | A TRUST membership is active for the sender and you are addressable by a TRUST membership id.                                                                                                    |
| 5        | `VERIFYVASP` | A VerifyVASP membership is active for the sender and you are addressable by a VerifyVASP id.                                                                                                     |
| 6        | `SYGNA`      | A Sygna Bridge membership is active for the sender and you are addressable by a Sygna VASP code. Didit speaks the Sygna protocol natively (ECIES-encrypted IVMS101, signed permission requests). |
| 7        | `EMAIL`      | No protocol channel is available - your compliance contact receives a one-time [email pickup link](#email-pickup) instead.                                                                       |

The network rails (`GTR`, `TRUST`, `VERIFYVASP`, `SYGNA`) run over a membership on the sending side - the Didit customer's own connected membership, or Didit's platform membership for that network when it is active.
If you are on one of those networks, share your network identifier with the Didit customer and the exchange arrives over the network you already operate.
The fastest path with zero shared memberships is `TRP`: publish a travel address or TRP endpoint and every Didit VASP can reach you natively.

When none of the rails can identify you, Didit runs one more resolution step: **blockchain analytics attribution**.
The destination wallet is resolved against blockchain analytics data, and when it is attributed to your exchange or custody service, Didit records your name in its VASP directory and retries the rails with it.
This means you can be discovered and contacted even when the sender supplied nothing but a wallet address - and once your directory entry carries a travel address, network id, or compliance email, attributed transfers route to you automatically.
The full resolution chain is therefore: wallet address book, then the protocol and network rails, then blockchain analytics.

## Travel addresses

Every Didit VASP with Travel Rule enabled has a **travel address** - a compact string starting with `ta` that encodes the URL of its personal TRP transfer-inquiry endpoint.
Didit customers read theirs from their Travel Rule settings and share it with counterparties; when a Didit customer gives you theirs, you hold everything needed to reach them over TRP.

The encoding follows the TRP travel address convention:

* Strip the `ta` prefix.
* Base58Check-decode the remainder (Bitcoin alphabet, double-SHA256 checksum).
* The decoded bytes are the inquiry URL without its scheme; prepend `https://`.
* The URL always carries the query pair `t=i` (type: inquiry).

A decoded Didit travel address has this shape:

```
https://trp.didit.me/trp/inquiries/{profile_uuid}/?t=i
```

`{profile_uuid}` identifies the hosted VASP profile - POST your transfer inquiries to that URL, and query the matching [identity endpoint](#get-trpidentityprofile_uuid) to verify who you are talking to first.

## TRP endpoints

Didit speaks TRP API version `3.2.1` at the base URL `https://trp.didit.me`.
All endpoints exchange JSON over HTTPS.

| Method | Path                                   | Purpose                                                         |
| ------ | -------------------------------------- | --------------------------------------------------------------- |
| `GET`  | `/identity`                            | Platform-operator identity (also served at `/trp/identity`).    |
| `GET`  | `/trp/identity/{profile_uuid}/`        | Identity of one hosted VASP profile.                            |
| `POST` | `/trp/inquiries/{profile_uuid}/`       | Submit a transfer inquiry to a hosted VASP.                     |
| `POST` | `/trp/callbacks/resolution/{token}/`   | Resolve an inquiry that **Didit** sent you (approve or reject). |
| `POST` | `/trp/callbacks/confirmation/{token}/` | Confirm or cancel a transfer that Didit approved for you.       |

Two TRP headers matter:

* `api-version` - the TRP protocol version you speak, for example `3.2.1`. Required on inquiries.
* `request-identifier` - your unique id for the request, echoed back in the response headers. Required on inquiries.

Every response from Didit carries `api-version: 3.2.1` and echoes your `request-identifier`.

### GET /identity

Returns the platform operator's identity.
No headers are required.

```bash theme={null}
curl https://trp.didit.me/identity
```

```json theme={null}
{
  "name": "Didit",
  "lei": "",
  "x509": ""
}
```

### GET /trp/identity/{profile_uuid}/

Returns the identity of the specific VASP you are about to exchange with - use it to verify the name and LEI before sending PII.
Didit performs the same check in reverse when it initiates: if the identity your endpoint reports does not match the expected LEI or name, the exchange is aborted.

```bash theme={null}
curl https://trp.didit.me/trp/identity/11111111-2222-3333-4444-555555555555/
```

```json theme={null}
{
  "name": "Bene CASP GmbH",
  "lei": "5493001KJTIIGC8Y1R12",
  "x509": ""
}
```

Returns `404` when the profile does not exist or its Travel Rule setup is disabled.

### POST /trp/inquiries/{profile_uuid}/

Submit a transfer inquiry - you are the originator VASP, the Didit customer is the beneficiary VASP.

```bash theme={null}
curl -X POST https://trp.didit.me/trp/inquiries/11111111-2222-3333-4444-555555555555/ \
  -H "Content-Type: application/json" \
  -H "api-version: 3.2.1" \
  -H "request-identifier: 7f6a1c1e-0a63-4b1f-9f6e-7dcd7c3f1a01" \
  -d '{
    "asset": { "dti": "XB0MQJ1K5" },
    "amount": "250000000000000000",
    "callback": "https://trp.yourvasp.example/callbacks/inquiry/abc123",
    "IVMS101": {
      "Originator": { "...": "..." },
      "Beneficiary": { "...": "..." }
    }
  }'
```

| Field       | Type   | Description                                                                                   |
| ----------- | ------ | --------------------------------------------------------------------------------------------- |
| `asset.dti` | string | The Digital Token Identifier (ISO 24165) of the asset being transferred.                      |
| `amount`    | string | Integer amount in the asset's smallest unit (base units per the DTI's decimals).              |
| `callback`  | string | Absolute `https` URL on your side where Didit posts the inquiry resolution.                   |
| `IVMS101`   | object | The IVMS 101 payload carrying originator and beneficiary natural-person or legal-person data. |

Assets are identified by DTI on this rail; Didit maps `BTC` (`4H95J0R2X`) and `ETH` (`XB0MQJ1K5`) today, with further assets added over time.
An inquiry whose DTI Didit does not recognize is still accepted and surfaced to the beneficiary VASP with the DTI as the asset code.

A `200` response means the inquiry was accepted for processing; `400` means missing TRP headers or an invalid body, and `404` means the profile is unknown or disabled.
Re-sending the same `request-identifier` is idempotent - the original inquiry is reused instead of duplicated.

Didit then creates the inbound transfer on the customer's application and resolves it against the customer's wallet address book and policy.
The **resolution** arrives asynchronously as a POST to your `callback` URL with one of two bodies:

```json theme={null}
{
  "approved": {
    "address": "0xConfirmedDepositAddress",
    "callback": "https://trp.didit.me/trp/callbacks/confirmation/{token}/"
  }
}
```

```json theme={null}
{
  "rejected": "Transfer inquiry declined"
}
```

Approval can be automatic - when the beneficiary VASP enables auto-accept and the beneficiary matches a verified wallet entry - or follow a manual review or a wallet-ownership proof on the beneficiary side, so allow for delay between inquiry and resolution.

After you receive an approval and broadcast the transfer on-chain, close the exchange out by POSTing to the `approved.callback` URL you were given:

```bash theme={null}
curl -X POST "https://trp.didit.me/trp/callbacks/confirmation/{token}/" \
  -H "Content-Type: application/json" \
  -d '{ "txid": "0xchainhash" }'
```

Send `{ "canceled": "reason" }` to the same URL instead if you abort the transfer.
`txid` moves the beneficiary-side transfer to `FINISHED`; `canceled` moves it to `CANCELLED`.

### Resolving inquiries Didit sends you

When a Didit customer originates a transfer to you over TRP, Didit:

1. Fetches your `/identity` and verifies the reported name and LEI against what the customer expects.
2. POSTs a transfer inquiry to your inquiry URL with the same body shape as above - `asset.dti`, base-unit `amount`, a `callback`, and the `IVMS101` payload.

The `callback` in that inquiry points at Didit's resolution endpoint (`/trp/callbacks/resolution/{token}/`).
Respond by POSTing the same resolution bodies Didit uses: `{ "approved": { "address": "...", "callback": "..." } }` to approve (your `callback` is where Didit will post the on-chain confirmation), or `{ "rejected": "reason" }` to decline.

On approval the Didit side moves to `COMPLETED`; once the customer reports the on-chain hash, Didit POSTs `{ "txid": "..." }` to the confirmation callback you supplied (or `{ "canceled": "reason" }` if the transfer is cancelled first).

<Note>
  Callback tokens are single-purpose, unguessable secrets minted per transfer - treat the full callback URLs as confidential, and note that a resolution is only accepted while the transfer is still awaiting one.
</Note>

## Email pickup

If you expose no protocol channel at all, Didit falls back to email: your compliance contact receives a message naming the originator VASP with a one-time secure pickup link.
No account, API key, or integration is needed - the link token is the authentication.

Opening the link shows the pending exchange; the underlying API (which the hosted page drives for you) is public:

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

```json theme={null}
{
  "originator_vasp_name": "Origin CASP SL",
  "amount": "1500.00",
  "currency": "EUR",
  "beneficiary_wallet": "bc1qexternalwallet01",
  "status": "AWAITING_COUNTERPARTY"
}
```

```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": "Carlos Ruiz" }'
```

`decision` is `accept` or `decline`; on accept, supply the beneficiary's name as your records hold it so the originator side can run its name match.
The link expires at the transfer's confirmation deadline - after that both endpoints return `410`.

## Sunrise: transfers that settled before the exchange

When a transfer reaches a Didit customer's wallet before any Travel Rule exchange took place - because no shared rail existed at the time - the data can still be delivered after settlement.

Send the Didit customer (your beneficiary counterparty) the Travel Rule payload through your normal channel and ask them to register it; they call [`POST /v3/travel-rule/inbound/`](/transaction-monitoring/travel-rule#after-deposit-sunrise-registration) with the deposit's chain, `txid`, wallet address, amount, and your originator data.
Include your VASP identity - name, LEI, and ideally your travel address - as `originating_vasp` in that payload: Didit then catalogues you in its [VASP directory](#getting-into-the-didit-vasp-directory), and every future exchange with any Didit VASP can reach you over TRP directly instead of email.

## Getting into the Didit VASP directory

Didit maintains a counterparty VASP registry that its customers' outbound routing consults.
There is no pre-seeded global list - entries are created and enriched from real activity:

* Your inbound TRP inquiries register your name, LEI, and TRP endpoint automatically.
* Outbound TRP exchanges to you record the identity and endpoint Didit verified.
* Sunrise registrations that name you as `originating_vasp` add your identity and travel address.
* Blockchain analytics attribution adds you when a destination wallet is resolved to your exchange or custody service - the entry starts with your attributed name and jurisdiction, and routes as soon as it is enriched with a channel.
* Didit can catalogue you proactively on request - routing identifiers, jurisdiction, and compliance contact.

An entry can carry one routing identifier per rail - `trp_endpoint_url`, `gtr_vasp_code`, `trust_membership_id`, `verifyvasp_id`, `sygna_vasp_code`, and a `compliance_email` for the email fallback.
The richer your entry, the more direct the rail Didit selects when one of its customers sends to you.
To add or correct your entry ahead of any traffic, ask the Didit customer you work with to raise it with Didit support.

## Checklist for counterparty VASPs

* **You run TRP already**: share your travel address (or TRP endpoint URL and LEI) with the Didit customer - exchanges arrive as standard TRP inquiries at your endpoint.
* **You are on GTR, TRUST, or VerifyVASP**: share your network identifier; exchanges arrive over that network whenever the Didit customer holds a membership there.
* **You have no protocol channel yet**: give the Didit customer a monitored compliance email - you will receive pickup links and can respond from the hosted page with zero integration.
* **A transfer already settled**: deliver the data via [sunrise registration](#sunrise-transfers-that-settled-before-the-exchange) through the Didit customer.
* **You also want to originate to Didit VASPs**: ask your counterparty for their travel address from their Didit Travel Rule settings, then follow [POST /trp/inquiries](#post-trpinquiriesprofile_uuid).

## Next steps

<CardGroup cols={2}>
  <Card title="Travel Rule" icon="route" href="/transaction-monitoring/travel-rule">
    The customer-facing product: lifecycle, settings, rails, and the /v3/ API.
  </Card>

  <Card title="Wallet ownership widget" icon="wallet" href="/transaction-monitoring/wallet-ownership-widget">
    How beneficiary-side ownership proofs are collected when a wallet is self-hosted.
  </Card>

  <Card title="Sunrise registration" icon="sun" href="/transaction-monitoring/travel-rule#after-deposit-sunrise-registration">
    Registering Travel Rule data for deposits that already settled on-chain.
  </Card>

  <Card title="Webhooks" icon="bell" href="/integration/webhooks">
    How Didit customers observe every exchange transition on their side.
  </Card>
</CardGroup>
