Transfers
Create and manage travel-rule transfers through their lifecycle.
Retrieve a paginated overview of all transfers initiated between entities, with support for filtering by VASP identifiers, blockchain addresses, transfer status, and date ranges.
150A page of transfers.
successUnauthorized
Internal Server Error
GET /api/v2/travelrule/transfers HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"status": "success",
"data": {
"items": [
{
"transfer_id": "067fd57d-efe3-7eab-8000-04d8f072e418",
"reference_id": "reference-transfer-01",
"amount": 4.2,
"amount_str": "4.2",
"dti": "4H95J0R2X",
"chain": "bitcoin",
"symbol": "BTC",
"protocol": "flow",
"originator_vasp_id": "UVWDEP",
"beneficiary_vasp_id": "MLESJF",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"originator_address_is_self_hosted": false,
"beneficiary_address_is_self_hosted": false,
"routing_number": "1234XYZ",
"originator_account_reference_id": "random-ref-id-101",
"beneficiary_account_reference_id": "random-ref-id-102",
"transfer_status": "INITIATED",
"transfer_type": "INSTRUCTION",
"direction": "outgoing"
}
],
"total": 1,
"page": 1,
"size": 50,
"pages": 1
}
}Initiate a Travel Rule transfer between crypto service providers or to a self-hosted wallet. Combines account creation, wallet address verification, and transfer initiation into a single call. Supports VASP-to-VASP withdrawals, self-hosted wallet withdrawals, and self-hosted wallet deposits.
reference_id is the idempotency key, scoped to your account. A request repeating a reference_id you have already used creates nothing: it returns that original transfer unchanged and ignores the rest of the body, answering 200 OK with the header Idempotent-Replayed: true. A fresh create answers 201 Created and carries no such header. A request without a reference_id never replays.
POST /travelrule/transfers
^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$Digital Token Identifier (ISO 24165) of the asset being transferred, and the documented way to name it — list the accepted identifiers with GET /travelrule/tokens. Optional only because one legacy alternative is still accepted: a request that names no asset at all is rejected.
The rail to send this transfer over, from GET /travelrule/protocols. Required whenever the transfer resolves to an instruction. A record dispatches nothing and carries no protocol: any value sent on one is accepted and discarded, and the transfer reads back with a null protocol. A self-hosted leg has no counterparty VASP to instruct, so naming any rail other than the deprecated 'flow' on one — or naming none — is rejected unless is_record is true.
Declare that this transfer's originator wallet is self-hosted — nobody operates it on the sender's behalf. It describes this transfer, so the transfer reads back with exactly what you send: absent or false means this is not a self-hosted transfer, whatever any earlier transfer declared about the same wallet. A self-hosted leg can only ride a record — set is_record — and the reserved 'SLFHST' VASP ID is applied automatically, so do not send originator_vasp_id with it.
falseDeclare that this transfer's beneficiary wallet is self-hosted — nobody operates it on the recipient's behalf. It describes this transfer, so the transfer reads back with exactly what you send: absent or false means this is not a self-hosted transfer, whatever any earlier transfer declared about the same wallet. A self-hosted leg can only ride a record — set is_record — and the reserved 'SLFHST' VASP ID is applied automatically, so do not send beneficiary_vasp_id with it.
falseDeprecated and inert: the server derives the transfer type from the transfer's shape. Any value sent is accepted and discarded — it never reaches the persisted transfer.
Book this transfer as a unilateral record rather than an instruction to a counterparty: nothing is dispatched and only the creating tenant ever sees it. A record carries no protocol — send none, and any value sent is discarded. True narrows the derived transfer type to RECORD; false or absent defers to the derivation, and it can never promote a derived RECORD to an INSTRUCTION. Use it for a self-recorded VASP-VASP deposit, and for a self-hosted leg: naming originator_vasp_id, or a self-hosted address, with protocol 'flow' and no is_record is the deprecated spelling of the same thing. On a self-hosted leg it is the only spelling under any other rail, or under none — those are rejected.
falseIdempotent replay. This reference_id already identifies one of your transfers, so nothing was created: the original transfer is returned unchanged and the rest of the request body was ignored.
Transfer Created Successfully
Unauthorized
Payment Required - VASP Customer Status
Not Found
Unprocessable Entity - Validation and Business Logic Errors
Internal Server Error
POST /api/v2/travelrule/transfers HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 973
{
"amount": 4.2,
"dti": "4H95J0R2X",
"protocol": "flow",
"reference_id": "reference-transfer-01",
"beneficiary_vasp_id": "MLESJF",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"originator_address_is_self_hosted": false,
"originator_account_reference_id": "random-ref-id-101",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"beneficiary_address_is_self_hosted": false,
"beneficiary_account_reference_id": "random-ref-id-102",
"routing_number": "1234XYZ",
"transaction_hash": "80003fee6bcbb2726b4d6466d690fce6caaa03771aada747eb0651637514b893",
"originator_account": {
"account_type": "individual",
"account_category": "customer",
"customer_id": "random-cust-id-101",
"individual": {
"individual_name": {
"name_type": "LEGL",
"name_first": "Mark",
"name_last": "Rover"
}
}
},
"beneficiary_account": {
"account_type": "individual",
"account_category": "non-customer",
"customer_id": "random-cust-id-102",
"individual": {
"individual_name": {
"name_type": "LEGL",
"name_first": "Robert",
"name_last": "Harding"
}
}
}
}{
"status": "success",
"data": {
"transfer_id": "067fd57d-efe3-7eab-8000-04d8f072e418",
"reference_id": "reference-transfer-01",
"amount": 4.2,
"dti": "4H95J0R2X",
"chain": "bitcoin",
"symbol": "BTC",
"protocol": "flow",
"originator_vasp_id": "UVWDEP",
"beneficiary_vasp_id": "MLESJF",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"originator_address_is_self_hosted": false,
"beneficiary_address_is_self_hosted": false,
"routing_number": "1234XYZ",
"originator_account_reference_id": "random-ref-id-101",
"beneficiary_account_reference_id": "random-ref-id-102",
"transaction_hash": "80003fee6bcbb2726b4d6466d690fce6caaa03771aada747eb0651637514b893",
"transfer_status": "INITIATED",
"transfer_type": "INSTRUCTION"
}
}Retrieve comprehensive details about a specific Travel Rule transfer, including originator and beneficiary information, amount, timestamps, and transfer status.
System-generated identifier unique to each transfer.
The full transfer, with both sides' records and VASPs. A counterparty's own declared record, when the wire carried one, sits beside ours rather than merged into it -- the disagreement between the two is the compliance artifact.
successUnauthorized
Not Found
Internal Server Error
GET /api/v2/travelrule/transfers/{transfer_id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"status": "success",
"data": {
"transfer_data": {
"transfer_id": "067fd57d-efe3-7eab-8000-04d8f072e418",
"reference_id": "reference-transfer-01",
"amount": 4.2,
"dti": "4H95J0R2X",
"chain": "bitcoin",
"symbol": "BTC",
"protocol": "flow",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"originator_address_is_self_hosted": false,
"beneficiary_address_is_self_hosted": false,
"routing_number": "1234XYZ",
"transfer_status": "REVIEW",
"transfer_type": "INSTRUCTION",
"created": "2026-08-31T09:14:22.418293",
"created_by_desc": "api"
},
"originator_record": {
"display_name": "John Doe",
"reference_id": "random-ref-id-101",
"account_type": "individual",
"name_first": "John",
"name_last": "Doe",
"date_of_birth": "1990-01-01",
"place_of_birth": "Singapore, Singapore",
"nationality_code": "SG",
"residence_country_code": "US"
},
"beneficiary_record": {
"display_name": "Grace Receiver",
"reference_id": "random-ref-id-102",
"account_type": "individual",
"name_first": "Grace",
"name_last": "Receiver"
},
"originator_vasp": {
"vasp_id": "UVWDEP",
"name_legal": "Northwind Digital Assets",
"registration_country_code": "SG"
},
"beneficiary_vasp": {
"vasp_id": "MLESJF",
"name_legal": "Meridian Exchange Ltd",
"registration_country_code": "SG"
}
}
}Update the details of an existing transfer.
System-generated identifier unique to each transfer.
The transfer was updated with its on-chain transaction hash.
successUnauthorized
Not Found
Unprocessable Entity - Validation Error
Internal Server Error
PATCH /api/v2/travelrule/transfers/{transfer_id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 87
{
"transaction_hash": "80003fee6bcbb2726b4d6466d690fce6caaa03771aada747eb0651637514b893"
}{
"status": "success",
"data": {
"transfer_id": "067fd57d-efe3-7eab-8000-04d8f072e418",
"reference_id": "reference-transfer-01",
"amount": 4.2,
"amount_str": "4.2",
"dti": "4H95J0R2X",
"chain": "bitcoin",
"symbol": "BTC",
"protocol": "flow",
"originator_vasp_id": "UVWDEP",
"beneficiary_vasp_id": "MLESJF",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"originator_address_is_self_hosted": false,
"beneficiary_address_is_self_hosted": false,
"routing_number": "1234XYZ",
"originator_account_reference_id": "random-ref-id-101",
"beneficiary_account_reference_id": "random-ref-id-102",
"transaction_hash": "80003fee6bcbb2726b4d6466d690fce6caaa03771aada747eb0651637514b893",
"transfer_status": "INITIATED",
"transfer_type": "INSTRUCTION"
}
}Perform an action on a transfer based on its current status, such as accepting, rejecting, canceling, or completing it.
System-generated identifier unique to each transfer.
Action to apply to the transfer, such as accept, reject, cancel, or complete.
Optional, accept only: the beneficiary Payment Address to answer the counterparty's Inquiry with, for an inbound transfer whose Inquiry named no beneficiary wallet. The wallet must already be registered against one of your own customer accounts. Supplying it on a transfer that already has one is accepted when the two agree and refused when they do not.
The lifecycle action was applied; the body reports the landed status.
successUnauthorized
Not Found
Validation and Business Logic Errors
Internal Server Error
PATCH /api/v2/travelrule/transfers/{transfer_id}/{action} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 87
{
"transaction_hash": "80003fee6bcbb2726b4d6466d690fce6caaa03771aada747eb0651637514b893"
}{
"status": "success",
"data": {
"transfer_id": "067fd57d-efe3-7eab-8000-04d8f072e418",
"reference_id": "reference-transfer-01",
"amount": 4.2,
"amount_str": "4.2",
"dti": "4H95J0R2X",
"chain": "bitcoin",
"symbol": "BTC",
"protocol": "flow",
"originator_vasp_id": "UVWDEP",
"beneficiary_vasp_id": "MLESJF",
"originator_address": "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy",
"beneficiary_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"originator_address_is_self_hosted": false,
"beneficiary_address_is_self_hosted": false,
"routing_number": "1234XYZ",
"originator_account_reference_id": "random-ref-id-101",
"beneficiary_account_reference_id": "random-ref-id-102",
"transfer_status": "ACCEPTED",
"transfer_type": "INSTRUCTION"
}
}Last updated

