curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \
-H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \
-d '{"beneficiary_wallet_address":"0xYourSandboxWallet","scenario":"accept","reference":"demo-001"}'import requests
url = "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/"
payload = {
"beneficiary_wallet_address": "0xYourSandboxWallet",
"scenario": "accept",
"amount": "1",
"reference": "demo-001"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
beneficiary_wallet_address: '0xYourSandboxWallet',
scenario: 'accept',
amount: '1',
reference: 'demo-001'
})
};
fetch('https://verification.didit.me/v3/travel-rule/test-vasp/inbound/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'beneficiary_wallet_address' => '0xYourSandboxWallet',
'scenario' => 'accept',
'amount' => '1',
'reference' => 'demo-001'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/"
payload := strings.NewReader("{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/travel-rule/test-vasp/inbound/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/travel-rule/test-vasp/inbound/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}"
response = http.request(request)
puts response.read_body{
"transaction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"txn_id": "<string>",
"scenario": "<string>",
"travel_rule_status": "<string>",
"detail": "<string>",
"test_vasp": true,
"travel_rule": {
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "AWAITING_COUNTERPARTY",
"direction": "INBOUND",
"rail": "INTERNAL",
"protocol": "<string>",
"ivms_version": "ivms101.2023",
"required": true,
"ownership_confirmed": true,
"deadline_at": "2023-11-07T05:31:56Z",
"timeline": [
{
"status": "<string>",
"at": "2023-11-07T05:31:56Z",
"detail": "<string>",
"name_match": {
"score": 50,
"matched": true,
"method": "none",
"strictness": "NONE",
"compared_with": "wallet_holder",
"transfer_name": "<string>",
"compared_name": "<string>",
"matched_names": [
"<string>"
],
"mismatched_names": [
"<string>"
]
},
"reason": "<string>"
}
],
"counterparty_vasp": {
"name": "<string>",
"lei": "<string>",
"dd_score": 123,
"dd_score_breakdown": {},
"dd_assessed_at": "2023-11-07T05:31:56Z"
},
"originator_data": {},
"beneficiary_data": {},
"name_match": {
"score": 50,
"matched": true,
"method": "none",
"strictness": "NONE",
"compared_with": "wallet_holder",
"transfer_name": "<string>",
"compared_name": "<string>",
"matched_names": [
"<string>"
],
"mismatched_names": [
"<string>"
]
},
"data_match": {
"matched": true,
"mismatched_fields": [
"name"
],
"fields": {}
},
"mismatched_fields": [
"<string>"
],
"data_unmasked": {
"at": "2023-11-07T05:31:56Z",
"reason": "ownership_confirmed",
"actor": "<string>"
},
"data_masked": true,
"created_at": "2023-11-07T05:31:56Z",
"delivery": {
"kind": "SEND",
"status": "QUEUED",
"rail": "INTERNAL",
"attempts": 1,
"last_error": "email undeliverable",
"next_attempt_at": "2023-11-07T05:31:56Z",
"delivered_at": "2023-11-07T05:31:56Z"
},
"discovery": [
{
"step": "internal_address_book",
"outcome": "match",
"reason": "<string>",
"vasp": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"rail": "<string>",
"at": "2023-11-07T05:31:56Z"
}
],
"reason": "<string>",
"next_actions": [
{
"action": "select_counterparty_vasp",
"url": "<string>"
}
],
"chain_details": {
"chain": "<string>",
"shape": "utxo",
"originator": {
"address": "<string>",
"memo": "<string>",
"source": "declared"
},
"beneficiary": {
"address": "<string>",
"memo": "<string>",
"source": "declared"
},
"utxo": {
"inputs": [
{
"address": "<string>",
"amount": "0.0125",
"txid": "<string>",
"vout": 1
}
],
"outputs": [
{
"address": "<string>",
"amount": "0.0125",
"txid": "<string>",
"vout": 1
}
],
"change_output_indexes": [
123
],
"beneficiary_output_index": 123
},
"lightning": {},
"warnings": [
"declared_originator_not_an_input"
],
"not_applicable_reason": "LIGHTNING_NO_PAYEE_IDENTIFIER"
}
}
}{}{
"detail": "<string>"
}Trigger Test VASP Inbound Transfer
Sandbox applications only. The Didit Test VASP sends your application an inbound Travel Rule transfer, so you can exercise the receiving side of an exchange end to end before going live. The transfer is booked and decided by the same logic a real inbound transfer from a network runs against your wallet address book, so the inbox, the decision and the wallet ownership flow behave as they do live. Nothing leaves Didit. A live application receives 400. Send the same reference again to get the transfer the first call booked instead of a second one.
curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \
-H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \
-d '{"beneficiary_wallet_address":"0xYourSandboxWallet","scenario":"accept","reference":"demo-001"}'import requests
url = "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/"
payload = {
"beneficiary_wallet_address": "0xYourSandboxWallet",
"scenario": "accept",
"amount": "1",
"reference": "demo-001"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
beneficiary_wallet_address: '0xYourSandboxWallet',
scenario: 'accept',
amount: '1',
reference: 'demo-001'
})
};
fetch('https://verification.didit.me/v3/travel-rule/test-vasp/inbound/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'beneficiary_wallet_address' => '0xYourSandboxWallet',
'scenario' => 'accept',
'amount' => '1',
'reference' => 'demo-001'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/travel-rule/test-vasp/inbound/"
payload := strings.NewReader("{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/travel-rule/test-vasp/inbound/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/travel-rule/test-vasp/inbound/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"beneficiary_wallet_address\": \"0xYourSandboxWallet\",\n \"scenario\": \"accept\",\n \"amount\": \"1\",\n \"reference\": \"demo-001\"\n}"
response = http.request(request)
puts response.read_body{
"transaction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"txn_id": "<string>",
"scenario": "<string>",
"travel_rule_status": "<string>",
"detail": "<string>",
"test_vasp": true,
"travel_rule": {
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "AWAITING_COUNTERPARTY",
"direction": "INBOUND",
"rail": "INTERNAL",
"protocol": "<string>",
"ivms_version": "ivms101.2023",
"required": true,
"ownership_confirmed": true,
"deadline_at": "2023-11-07T05:31:56Z",
"timeline": [
{
"status": "<string>",
"at": "2023-11-07T05:31:56Z",
"detail": "<string>",
"name_match": {
"score": 50,
"matched": true,
"method": "none",
"strictness": "NONE",
"compared_with": "wallet_holder",
"transfer_name": "<string>",
"compared_name": "<string>",
"matched_names": [
"<string>"
],
"mismatched_names": [
"<string>"
]
},
"reason": "<string>"
}
],
"counterparty_vasp": {
"name": "<string>",
"lei": "<string>",
"dd_score": 123,
"dd_score_breakdown": {},
"dd_assessed_at": "2023-11-07T05:31:56Z"
},
"originator_data": {},
"beneficiary_data": {},
"name_match": {
"score": 50,
"matched": true,
"method": "none",
"strictness": "NONE",
"compared_with": "wallet_holder",
"transfer_name": "<string>",
"compared_name": "<string>",
"matched_names": [
"<string>"
],
"mismatched_names": [
"<string>"
]
},
"data_match": {
"matched": true,
"mismatched_fields": [
"name"
],
"fields": {}
},
"mismatched_fields": [
"<string>"
],
"data_unmasked": {
"at": "2023-11-07T05:31:56Z",
"reason": "ownership_confirmed",
"actor": "<string>"
},
"data_masked": true,
"created_at": "2023-11-07T05:31:56Z",
"delivery": {
"kind": "SEND",
"status": "QUEUED",
"rail": "INTERNAL",
"attempts": 1,
"last_error": "email undeliverable",
"next_attempt_at": "2023-11-07T05:31:56Z",
"delivered_at": "2023-11-07T05:31:56Z"
},
"discovery": [
{
"step": "internal_address_book",
"outcome": "match",
"reason": "<string>",
"vasp": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"rail": "<string>",
"at": "2023-11-07T05:31:56Z"
}
],
"reason": "<string>",
"next_actions": [
{
"action": "select_counterparty_vasp",
"url": "<string>"
}
],
"chain_details": {
"chain": "<string>",
"shape": "utxo",
"originator": {
"address": "<string>",
"memo": "<string>",
"source": "declared"
},
"beneficiary": {
"address": "<string>",
"memo": "<string>",
"source": "declared"
},
"utxo": {
"inputs": [
{
"address": "<string>",
"amount": "0.0125",
"txid": "<string>",
"vout": 1
}
],
"outputs": [
{
"address": "<string>",
"amount": "0.0125",
"txid": "<string>",
"vout": 1
}
],
"change_output_indexes": [
123
],
"beneficiary_output_index": 123
},
"lightning": {},
"warnings": [
"declared_originator_not_an_input"
],
"not_applicable_reason": "LIGHTNING_NO_PAYEE_IDENTIFIER"
}
}
}{}{
"detail": "<string>"
}Authorizations
Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is missing, wrong, revoked or expired; 403 means the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.
Body
The destination wallet address. The Didit Test VASP sends to it, matched against your wallet address book on the chain of the asset. A wallet with no matching entry is accepted and the inbound transaction is booked ON_HOLD.
What the Didit Test VASP declares the beneficiary to be. accept declares the holder's own name; name_mismatch declares a name no holder agrees with. The decision itself is always yours.
accept, name_mismatch Chain of the asset.
Amount as a decimal string.
Asset code.
Optional idempotency key. A repeat with the same value returns the transfer the first call booked.
Response
The inbound transfer was booked and decided. A repeat with the same reference returns the same body.
Didit transaction UUID of the inbound transfer.
Didit-generated txn_id.
The scenario that ran.
The status your application's own decision resolved to.
Why the transfer resolved to that status.
Always true: the sender was the Didit Test VASP.
Full transfer object returned by the ownership-confirmation and finish/cancel endpoints. While an inbound transfer's wallet ownership is unconfirmed, the counterparty's originator_data and beneficiary_data come back masked (the first letter of each word is kept; the wallet, chain and VASP routing stay readable) and data_masked is true.
Show child attributes
Show child attributes