Skip to main content
This guide walks you through resolving a Travel Rule request for information (RFI) on an on-hold crypto deposit directly through the API — from detecting the on-hold status to submitting proof and allowing the transaction to proceed.
Prefer a managed UI? See Travel Rule deposit via the Travel Rule Widget — it handles the proof collection form for you.

Prerequisites

Walkthrough

Detect the on-hold transaction

When a crypto deposit is placed on hold due to a Travel Rule requirement, Uphold sends a core.transaction.status-changed webhook with status: on-hold and statusDetails.reason: pending-requests-for-information.
Abbreviated — the transaction object includes additional fields.
If you are using polling instead of webhooks, check for status: on-hold and statusDetails.reason: pending-requests-for-information on the transaction object.

Notify the user

Surface the on-hold status to the user out-of-band (email or push notification) — deposits can sit on-hold indefinitely until resolved.

List transaction RFIs

Call List request for information with reference set to the transaction ID, then filter the results to keep only entries where type is “travel-rule”. From that filtered set, check whether any RFI has a status of “pending” — if so, the transaction is still awaiting resolution.
If all travel-rule RFIs have a status of “ok”, the transaction may have already been moved out of on-hold status automatically. Make sure to re-fetch the transaction and check its current status before taking further action.

Resolve the Travel Rule RFI

The RFI’s proofOptions field lists which proof mechanisms can resolve it — only the mechanisms that actually apply to this deposit 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 deposit, proof is submitted as originatorProof — you’re proving who the external sender is. Submit it with Update request for information.

Self-declaration

Submit the attestation plus the compliance details described by proofOptions.selfDeclaration.schema:

Message signing

Have the user sign proofOptions.messageSigning.message with their wallet, then submit the signature:
Uphold verifies the signature and enriches the response with 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 in proofOptions.satoshiTest. Poll Get request for information or re-fetch the transaction to know when it clears. Once confirmed, the RFI resolves with a flat proof — unlike the other two types, it’s not wrapped in originatorProof:

Monitoring for settlement

After the RFI is resolved, the transaction will move from on-hold to processing and then to either completed or failed. Monitor the transaction status using webhooks (recommended) or polling (fallback):
  • Webhook events (recommended):
    • core.transaction.status-changed
      • status: processing → transaction is being processed
      • status: completed → necessary confirmations reached
      • status: failed → transaction failed
  • Polling (fallback): Get transaction
When the transaction reaches completed or failed, notify the user of the outcome.

Testing

To trigger a Travel Rule RFI on a deposit, use a GB user account and send 30 XRP from an unhosted (self-custodial) wallet to the user’s Uphold deposit address. Verify the following:
  1. A core.transaction.status-changed webhook is received with status: on-hold and statusDetails.reason: pending-requests-for-information.
  2. List requests for information returns an RFI with type: travel-rule, status: pending, and a populated proofOptions.
  3. Update request for information with a valid proof returns 200 with status: "ok".
  4. The transaction status updates from processing to completed within a few minutes, assuming no other blockers.
For the equivalent withdrawal guide, see Travel Rule withdrawal via the REST API.