After Deposit: Create incoming data exchange
Learn how to submit compliant after on-chain incoming transfer when receiving a blockchain transaction.
Use this flow when your VASP receives an on-chain deposit, but no corresponding Travel Rule data exchange was delivered. In such case, you need to request the missing Travel Rule information after the on-chain transfer.
In this scenario, VASPs become part of the after-on-chain verification process. You will act as a beneficiary, whereas the counterparty will act as the originator.
Typical reasons for this include:
- Technical issue or system failure prevented delivery of the original data exchange.
- Originator operates in a jurisdiction where Travel Rule data exchange is not required before the transfer.
Tip
- If the blockchain transaction has already been received on-chain, use After deposit: create incoming data exchange flow.
- If another VASP has already initiated a request for your user's wallet, use Respond to incoming transfer requests flow.
Checking for existing transactions
Before creating a new incoming Travel Rule data exchange transaction, check whether a matching transaction has already been created to avoid creating duplicate inbound Travel Rule transactions for the same deposit.
Use this API method to look for an existing transfer with similar parameters, such as:
- Blockchain transaction ID
- Sender wallet address
- Other matching transfer identifiers available in your system
Request example:
curl -X GET \
'https://api.sumsub.com/resources/kyt/txns/query/-;data.type=travelRule;data.applicant.paymentMethod.accountId=0x611Fb08528080848Dd3439242fdfg993d18ADd95dsd;data.info.direction=in;data.info.paymentTxnId=000000000000000000013f2851d71e6ea8dfcc9151654ca4cbbbfd759122589f?order=-createdAt&limit=1' \
-H 'accept: application/json'// Searches Travel Rule transactions with USDT/ETH currency where amount is from '100' to '500' which happened on '2025-10-07'.
curl -X GET \
'https://api.sumsub.com/resources/kyt/txns/query/-;data.info.direction=in;data.info.amount__gte=100;data.info.amount__lte=500;data.info.currencyCode=USDT;data.info.cryptoParams.cryptoChain=ETH;data.txnDate__gte=2025-10-07%2000%3A00%3A00;data.txnDate__lte=2025-10-07%2023%3A59%3A59;data.type=travelRule?order=-data.txnDate&limit=1' \
-H 'accept: application/json'How creation of incoming data exchange works
Once you submit an after-deposit Travel Rule data exchange transaction with all its details, including:
- Information about the beneficiary and the beneficiary VASP.
- Information about the originator and, if known, the originating VASP.
- Blockchain transaction ID of the deposit.
Once the transaction is submitted, Sumsub attempts to identify the originating VASP:
- If the originating VASP is identified and reachable, we will notify them about the request and ask to confirm wallet ownership and provide the required Travel Rule data. The transaction then enters the
awaitingCounterpartystatus.NoteTo learn more about Travel Rule transaction statuses, see this article.
- If the originating VASP is not identified or cannot be reached, the transaction follows the corresponding fallback status path.
Once the originating VASP provides the required data, Sumsub cross-checks it against the beneficiary data already collected during KYC or included in your request. This leads to one of two main outcomes:
- Data match — the Travel Rule data exchange transaction gets completed and obtains the corresponding status — completed.
- Data mismatch or other issues — the transaction is rejected with a status such as
counterpartyMismatchedDataorcounterpartyVaspGeneralDecline
Create incoming data exchange transaction
The following is a sequence of steps to be taken to create the after on-chain incoming transfer.
Step 1: Enable required rules
To apply the Travel Rule solution to the after on-chain incoming transfer, do the following:
- In the Dashboard, open the Rules Library.
- Select the Travel Rule bundle and install the rules.
We recommend installing all the rules available in the bundle, as it is the quickest and easiest way to cover all of the check steps.
NoteThe rules you install remain in Test mode until you activate them.
Step 2: Set up timeout timers
You can set a timeout for the response and manage it accordingly if the response is not provided within the specified time:
- In the Dashboard, open the Transactions and Travel Rule section, go to Settings, and choose Confirmation Timeout.
- To set up the desired conditions for the data exchange transaction, select the threshold and how to treat the data.
- To apply the set parameters, click Save.
Step 3: Generate app token
Once you have installed and enabled the rules, you will need to generate an app token to sign your API calls. For more information on how to generate a token, refer to this article.
Step 4: Send Travel Rule data exchange transaction
After completing the setup of the desired conditions and generating the token, you will be able to submit a Travel Rule data exchange transaction.
NoteFor this flow:
- The
info.directionfield of your transaction should contain the in value.- The blockchain ID should be included in the following field — info.paymentTxnId.
To submit the Travel Rule data exchange transaction, use this API method, as the following example demonstrates:
{
"txnId": "loi6voxz567zfu8aq9", // Unique transaction identifier in your system.
"type": "travelRule", // Must be "travelRule" for Travel Rule transactions.
"applicant": {
"type": "individual", // Required. Entity type.
"externalUserId": "gca9xsk3l4o9e3ozs3tk2c", // User identifier in your system; required for the applicant in Travel Rule transactions.
"nameType": "birthName",
"dob": "1992-05-08", // Required for individuals when using the GTR protocol.
"placeOfBirth": "Paris",
"address": {
"country": "FRA",
"town": "Paris",
"postCode": "75001",
"street": "Rue de Rivoli",
"buildingNumber": "1"
},
"paymentMethod": {
"type": "crypto", // Must be "crypto" for crypto Travel Rule transactions.
"accountId": "bc1q080rkmk3kj86pxvf5nkxecdrw6nrx3zzy9xl7q" // Required. Applicant wallet address.
},
"idDoc": {
"number": "FR42234089",
"country": "FRA",
"idDocType": "PASSPORT",
"registrationAuthority": "Ille-de-France 01"
},
"residenceCountry": "FRA",
"firstName": "John", // Required for all Travel Rule protocols.
"firstNameEn": "John", // Required for all Travel Rule protocols.
"lastName": "Posek", // Required for all Travel Rule protocols.
"lastNameEn": "Posek" // Required for all Travel Rule protocols.
},
"counterparty": {
"externalUserId": "qvt79uggfq7q8newtg", // Optional; required for aggregation-based rules. Must be consistent across transactions for the same counterparty.
"type": "individual", // Required. Entity type.
"address": {
"country": "DEU",
"street": "Chauseestr.",
"town": "Berlin",
"postCode": "10115",
"buildingNumber": "60"
},
"paymentMethod": {
"type": "crypto", // Payment method type; use "crypto" for hosted wallets or "unhostedWallet" for unhosted wallets.
"accountId": "0xa79e8726DaF031f753477C79653d0d56AA0D5DF6" // Required. Counterparty wallet address.
},
"firstName": "Jack", // Required for all Travel Rule protocols.
"firstNameEn": "Jack", // Required for all Travel Rule protocols.
"lastName": "Posek", // Required for all Travel Rule protocols.
"lastNameEn": "Posek", // Required for all Travel Rule protocols.
"nameType": "birthName",
"dob": "1991-04-07", // Required for individuals when using the GTR protocol.
"placeOfBirth": "Berlin, Germany",
"idDoc": {
"number": "DE42234089",
"idDocType": "PASSPORT",
"country": "DEU",
"registrationAuthority": "BerlinMitte"
},
"residenceCountry": "DEU",
"institutionInfo": {
"internalId": "65fd80a177aa675eeb9f6b71" // Optional counterparty VASP identifier; strongly recommended to improve Travel Rule success and avoid costly, less reliable attribution via analytics or address book.
}
},
"info": {
"direction": "in", // Required. Indicates transaction direction relative to the applicant ("in" or "out").
"amount": 150.0, // Amount in the transaction currency.
"amountInDefaultCurrency": 150.0, // Optional; recommended for accurate FX conversion, especially for unsupported or illiquid assets.
"defaultCurrencyCode": "USD", // Required if "amountInDefaultCurrency" is provided.
"currencyCode": "USDT", // Asset code (ticker symbol).
"paymentDetails": "Private transfer",
"currencyType": "crypto", // Currency type; must be "crypto" for all Travel Rule transactions.
"cryptoParams": {
"cryptoChain": "ETH", // Required for non-native tokens to identify the blockchain.
"contractAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7" // Required to resolve token ambiguity.
},
"paymentTxnId": "0xd3b111a2932da3657d571e340c00ee4e4323632d9a932838f3dd02ed49c6dbd8" // Required for after on-chain transactions.
},
"props": {
"customProperty": "Custom value that can be used in rules",
"dailyOutLimit": "10000"
},
"zoneId": "UTC+1",
"txnDate": "2025-01-31 10:53:17+0000"
}Step 5: Receive webhook updates
After submission, Sumsub processes the transaction and sends webhook updates based on the outcome. The webhook indicates the status of the data exchange transaction after checking the transfer against the installed rules.
If the originating VASP is available in the Sumsub network and needs to take action, the Travel Rule transaction status changes to awaitingCounterparty. At this stage, you may receive a you will receive the applicantKyKytAwaingUser webhook, indicating that the request is waiting for the counterparty response:
{
"applicantId": "6447b564728bf40939a7664f",
"applicantType": "individual",
"correlationId": "7310f3ffddbff223cdf10221cdf12064",
"sandboxMode": false,
"externalUserId": "customExternalUserId",
"type": "applicantKytTxnAwaitingUser",
"reviewStatus": "awaitingUser",
"createdAt": "2023-12-11 10:41:54+0000",
"createdAtMs": "2023-12-11 10:41:54.431",
"clientId": "coolClientId",
"kytTxnId": "6576e772b2f80732714d1de0",
"kytDataTxnId": "m26m980m9jd7pozq72se4",
"kytTxnType": "travelRule"
}If the originating VASP cannot be identified or reached, the Travel Rule transaction status may change to counterpartyVaspNotFound or counterpartyVaspNotReachable. In these cases, you can expect the applicantKytTxnRejected webhook and should follow your configured fallback handling.
{
"applicantId": "634829375766b80001a40152",
"applicantType": "individual",
"correlationId": "0f5a7c828bab750775564534fc0470a8",
"sandboxMode": false,
"externalUserId": "customExternalUserId",
"type": "applicantKytTxnRejected",
"reviewResult": {
"reviewAnswer": "RED",
"reviewRejectType": "FINAL"
},
"reviewStatus": "completed",
"createdAt": "2024-04-24 11:15:09+0000",
"createdAtMs": "2024-04-24 11:15:09.446",
"clientId": "coolClientId",
"kytTxnId": "64a7dc05fbf57c624afcb72d",
"kytDataTxnId": "j8bqz29yn491vksi9qfydw",
"kytTxnType": "travelRule"
}Step 6: Review counterparty VASP response
Once the beneficiary data is provided by the originating VASP, Sumsub cross-checks it against the beneficiary data you already collected during KYC or supplied in the transaction.
If the data provided by the originator matches your KYC data, then the Travel Rule data exchange transaction will get completed, and the Travel Rule status will be changed to completed.
You will be notified about the outcome with the applicantKytTxnApproved webhook:
{
"applicantId": "634829375766b80001a40152",
"applicantType": "individual",
"correlationId": "f24f6616020245053139a6537303a251",
"sandboxMode": false,
"externalUserId": "customExternalUserId",
"type": "applicantKytTxnApproved",
"reviewResult": {
"reviewAnswer": "GREEN"
},
"reviewStatus": "completed",
"createdAt": "2024-04-24 11:15:09+0000",
"createdAtMs": "2024-04-24 11:15:09.446",
"clientId": "coolClientId",
"kytTxnId": "64a7dc05fbf57c624afcb72d",
"kytDataTxnId": "uauu08x44xexbohyh4lkp9",
"kytTxnType": "travelRule"
}If the data provided by the originator does not match your KYC data, or there were some other issues identified, then the Travel Rule data exchange transaction will get rejected. The Travel Rule status will be changed to counterpartyMismatchedData or counterpartyVaspGeneralDecline.
You will be notified about the outcome with the applicantKytTxnRejected webhook:
{
"applicantId": "634829375766b80001a40152",
"applicantType": "individual",
"correlationId": "0f5a7c828bab750775564534fc0470a8",
"sandboxMode": false,
"externalUserId": "customExternalUserId",
"type": "applicantKytTxnRejected",
"reviewResult": {
"reviewAnswer": "RED",
"reviewRejectType": "FINAL"
},
"reviewStatus": "completed",
"createdAt": "2024-04-24 11:15:09+0000",
"createdAtMs": "2024-04-24 11:15:09.446",
"clientId": "coolClientId",
"kytTxnId": "64a7dc05fbf57c624afcb72d",
"kytDataTxnId": "j8bqz29yn491vksi9qfydw",
"kytTxnType": "travelRule"
}Updated about 3 hours ago