Skip to main content
Requests for Information (RFIs) are compliance checkpoints that may be triggered during transaction processing. When additional information is required to meet compliance requirements, a transaction is placed on hold until the necessary data is provided. This flow guides you through detecting and resolving RFIs to allow transactions to proceed.

Prerequisites

  • A transaction with status on-hold and reason pending-requests-for-information
  • Your system is set up to listen to webhooks for transaction status changes
  • Understanding of the transaction flow that triggered the RFI (deposit, withdrawal, etc.)

Detect held transaction

Monitor webhook events to detect when a transaction is placed on hold:
{
  "transaction": {
    "id": "223c24c5-76c6-4553-91bc-5af519441f03",
    "status": "on-hold",
    "statusDetails": {
      "reason": "pending-requests-for-information"
    },
    ...
  }
}

List pending RFIs

Retrieve the pending requests for information using List Requests for Information endpoint.
GET /core/transactions/{transactionId}/requests-for-information
A successful response includes a list of pending RFIs.
{
  "requestsForInformation": [
    {
      "id": "3f6d0c1e-a1bf-4b25-9802-2a3ee492d3c8",
      "type": "travel-rule",
      "status": "pending",
      "data": {},
      "createdAt": "2024-07-24T15:22:39Z",
      "updatedAt": "2024-07-24T15:22:39Z"
    }
  ]
}

Travel Rule

Travel Rule is a regulatory requirement that mandates the collection and transmission of information about the originator and beneficiary of certain crypto transactions.

The flow

Create the widget session

When a travel-rule RFI is pending, create a widget session using Create Session endpoint.
POST /widgets/travel-rule/sessions
{
  "flow": "deposit-form",
  "data": {
    "requestForInformationId": "3f6d0c1e-a1bf-4b25-9802-2a3ee492d3c8"
  }
}
A successful response includes a url and token for the widget session, and data containing additional context to setup and prefill the Travel Rule form.
{
  "session": {
    "flow": "deposit-form",
    "url": "https://widgets.uphold.com/travel-rule/sessions/xyz789",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "data": {
      "provider": "notabene",
      "parameters": {
        // additional context to setup and prefill the form
      }
    }
  }
}

Open the widget

Launch the widget to guide the user through the Travel Rule information collection process.
The example code below is for web applications. For native applications using a WebView, you’ll still need to implement communication through a bridge to send events to the native side. Check out the Native App Integration page for more details.
import { TravelRuleWidget } from '@uphold/enterprise-travel-rule-widget-web-sdk';

// 1. Create Travel Rule widget instance
const widget = new TravelRuleWidget<'deposit-form'>(session, { debug: true });

// 2. Listen to relevant events
widget.on('complete', (event) => {
  const { value: travelRule } = event.detail;

  // Send travelRule data to your backend to update the RFI

  widget.unmount();
});
widget.on('cancel', error => ...);
widget.on('error', error => ...);

// 3. Select the container element
const container = document.getElementById('tr-deposit');

// 4. Mount the deposit form widget
widget.mountIframe(container);
Check out Widgets > Travel Rule documentation for more details.

Update the RFI

Once the widget emits the complete event, update the RFI using Update Request for Information endpoint.
PUT /core/transactions/{transactionId}/requests-for-information/{requestForInformationId}
{
  "data": {
    // Travel Rule data from complete event
  }
}
A successful response confirms the RFI has been updated.
{
  "requestForInformation": {
    "id": "3f6d0c1e-a1bf-4b25-9802-2a3ee492d3c8",
    "type": "travel-rule",
    "status": "ok",
    "data": { ... },
    "createdAt": "2024-07-24T15:22:39Z",
    "updatedAt": "2024-07-24T15:25:12Z"
  }
}
The travel-rule RFI has been successfully resolved, and the transaction will proceed automatically.

Monitor transaction completion

Once the RFI is resolved, the transaction will automatically resume processing. Prefer webhooks for real-time updates, or fall back to polling if webhooks are not feasible.
  • Webhook events (recommended):
    • core.transaction.status-changed
      • status: processing → transaction is being processed
      • status: completed → transaction finalized and funds credited
      • status: failed → transaction failed, check statusDetails for more info
  • Polling (fallback):
This flow can be triggered as part of:
  • Crypto Deposit - When incoming deposits require compliance information