Prefer a managed UI? See Travel Rule withdrawal via the Travel Rule Widget — it handles the proof collection form for you.
Prerequisites
- The user has completed onboarding and has the required capabilities enabled.
Walkthrough
Detect the requirement
When a quote is returned, check therequirements array. If it contains travel-rule, the requirement must be resolved before the transaction can be created. If requirements is empty, proceed directly to creating the transaction.
List quote RFIs
Call List request for information withreference set to the quote ID to find the pending travel-rule RFI.
Resolve the Travel Rule RFI
The RFI’sproofOptions field lists which proof mechanisms can resolve it — only the mechanisms that actually apply to this withdrawal are present (a satoshiTest option only appears for networks where a microtransfer is a viable proof). See Proof types for what each mechanism means and when it’s used.
For a type: "travel-rule" RFI on a withdrawal, proof is submitted as beneficiaryProof — you’re proving who the external receiver is. Submit it with Update request for information.
Self-declaration
Submit the attestation plus the compliance details described byproofOptions.selfDeclaration.schema:
Message signing
Have the user signproofOptions.messageSigning.message with their wallet, then submit the signature:
did and status:
Satoshi test
Nothing is submitted through this endpoint — resolution is deferred until Uphold detects and confirms the on-chain microtransfer to the address described inproofOptions.satoshiTest. Poll Get request for information to know when it clears.
Once confirmed, the RFI resolves with a flat proof — unlike the other two types, it’s not wrapped in beneficiaryProof:
status: "failed") or expires, resolve the Travel Rule requirement again.
Create the transaction
Once the RFI is resolved (status: "ok"), create the transaction using the quote ID. If the original quote expired while during the RFI process, create a new quote and proceed — no additional Travel Rule data needs to be passed, as the resolved RFI is tied to the destination address rather than a specific quote.
core.transaction.status-changed webhook with status: failed and statusDetails.reason: travel-rule-verification-failed. Common causes are the transaction being created before the RFI was fully resolved, or the beneficiary VASP being unrecognized or invalid. Notify the user and ask them to retry with a different destination.
Testing
To trigger a Travel Rule requirement on a withdrawal, use a GB user account and create an XRP withdrawal quote to an external address for 30 XRP. Verify the following:- The quote response includes
"travel-rule"in therequirementsarray. - List requests for information returns an RFI with
type: travel-rule,status: pending, and a populatedproofOptions. - Update request for information with a valid proof returns
200withstatus: "ok". - Create transaction with the
quoteIdsucceeds. - A
core.transaction.status-changedwebhook is received withstatus: completed(orfailedif the counterparty rejects the data).