Skip to main content
This page is for the other side of a Didit 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:
PriorityRailWhat it means for you
1INTERNALBoth VASPs run on Didit - the exchange settles inside the platform and no external call is made.
2TRPYou expose a Travel Rule Protocol (TRP) endpoint, or the Didit customer knows your travel address. Didit calls your TRP inquiry endpoint machine-to-machine.
3GTRA 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.
4TRUSTA TRUST membership is active for the sender and you are addressable by a TRUST membership id.
5VERIFYVASPA VerifyVASP membership is active for the sender and you are addressable by a VerifyVASP id.
6SYGNAA 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).
7EMAILNo protocol channel is available - your compliance contact receives a one-time email pickup link 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 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.
MethodPathPurpose
GET/identityPlatform-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.
curl https://trp.didit.me/identity
{
  "name": "Didit",
  "lei": "",
  "x509": ""
}

GET /trp/identity//

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.
curl https://trp.didit.me/trp/identity/11111111-2222-3333-4444-555555555555/
{
  "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//

Submit a transfer inquiry - you are the originator VASP, the Didit customer is the beneficiary VASP.
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": { "...": "..." }
    }
  }'
FieldTypeDescription
asset.dtistringThe Digital Token Identifier (ISO 24165) of the asset being transferred.
amountstringInteger amount in the asset’s smallest unit (base units per the DTI’s decimals).
callbackstringAbsolute https URL on your side where Didit posts the inquiry resolution.
IVMS101objectThe 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:
{
  "approved": {
    "address": "0xConfirmedDepositAddress",
    "callback": "https://trp.didit.me/trp/callbacks/confirmation/{token}/"
  }
}
{
  "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:
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).
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.

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:
curl https://verification.didit.me/v3/travel-rule/pickup/{token}/
{
  "originator_vasp_name": "Origin CASP SL",
  "amount": "1500.00",
  "currency": "EUR",
  "beneficiary_wallet": "bc1qexternalwallet01",
  "status": "AWAITING_COUNTERPARTY"
}
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/ 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, 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 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.

Next steps

Travel Rule

The customer-facing product: lifecycle, settings, rails, and the /v3/ API.

Wallet ownership widget

How beneficiary-side ownership proofs are collected when a wallet is self-hosted.

Sunrise registration

Registering Travel Rule data for deposits that already settled on-chain.

Webhooks

How Didit customers observe every exchange transition on their side.