Skip to content

This workflow covers outgoing transfers where PII (Personally Identifiable Information) is required. You collect PII from your end user and submit it via the API before creating the transfer intent.

Prerequisites

Process flow

BlockchainNotabeneCustodyEnd UserCustomerBlockchainNotabeneCustodyEnd UserCustomeralt[Screening failed][Screening passed or notconfigured]alt[AUTO_APPROVED][AUTO_REJECTED]1. Create Travel Rule messageForward to NotabeneReturn transfer detailsReturn suggestedIntentId, travelRuleId2. Get transfer status (check PII requirements)Return presentation-definition with policyId3. Request PIIProvide PII4. Submit PII via APIForward PIIPII attachedConfirmed5. Create Transfer Order Intent (using suggestedIntentId)6. Screen risk (if configured)AUTO_REJECTED (no Travel Rule check)7. Travel Rule check8. Compliance decision9. Execute transactionNotify settlementNotify rejection
BlockchainNotabeneCustodyEnd UserCustomerBlockchainNotabeneCustodyEnd UserCustomeralt[Screening failed][Screening passed or notconfigured]alt[AUTO_APPROVED][AUTO_REJECTED]1. Create Travel Rule messageForward to NotabeneReturn transfer detailsReturn suggestedIntentId, travelRuleId2. Get transfer status (check PII requirements)Return presentation-definition with policyId3. Request PIIProvide PII4. Submit PII via APIForward PIIPII attachedConfirmed5. Create Transfer Order Intent (using suggestedIntentId)6. Screen risk (if configured)AUTO_REJECTED (no Travel Rule check)7. Travel Rule check8. Compliance decision9. Execute transactionNotify settlementNotify rejection

Step 1: Create Travel Rule message

Create a Travel Rule message with counterparty information:

POST /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages

Request body:

FieldTypeDescription
originatorobjectOriginator identifier (contains @id - DID or identifier for the party)
beneficiaryobjectBeneficiary identifier (contains @id - DID or identifier for the party)
assetstringAsset identifier (e.g., bip122:000000000019d6689c085ae165831e93/slip44:0). See Notabene asset registry for supported formats.
amountstringTransfer amount
refstringReference identifier for the transfer
agentsarrayAgents involved in the transfer. Each agent has @id, for, and role (values: VASP, Custodian, SettlementAddress, SourceAddress, Gateway, Unknown)

Response:

FieldTypeDescription
createTransfer201Response.transferobjectTransfer details from Notabene
suggestedIntentIdstring (uuid)The intent ID to use when creating the transfer intent

Step 2: Check PII requirements

Get the transfer status to check what PII is required:

GET /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages/{travelRuleId}

The response includes a presentation-definition that specifies the required PII fields. It also contains a policyId that you can use when submitting encrypted PII (see Step 4, Option C).

Step 3: Collect PII from end user

Collect required PII from your end user according to the IVMS-101 standard and the requirements in the presentation-definition.

Step 4: Submit PII via API

Submit the collected PII using one of three API endpoints. All PII is encrypted with the receiver's public key.

Option A: Append PII (stored on both sides)

Use this option when both sender and receiver need access to the PII.

POST /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages/{travelRuleId}/pii

Request body:

FieldTypeRequiredDescription
ivms101objectYesIVMS-101 formatted PII data
originatorobjectNoOriginator details
beneficiaryobjectNoBeneficiary details

Response: 200 OK

Option B: Present encrypted PII (stored on receiver side only)

Use this option for end-to-end encrypted PII that only the receiver can decrypt.

POST /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages/{travelRuleId}/encrypted-pii

Request body:

FieldTypeRequiredDescription
ivms101objectYesEnd-to-end encrypted IVMS-101 data

Response: 202 Accepted (asynchronous processing)

Option C: Present encrypted PII with policy (stored on receiver side only)

Use this option when sender and receiver have different jurisdictional requirements. The policyId from Step 2 specifies the applicable compliance policy.

POST /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages/{travelRuleId}/policies/{travelRulePolicyId}/encrypted-pii

Request body: Same as Option B.

Response: 202 Accepted (asynchronous processing)

Options B and C use end-to-end encryption with the receiver's public key. The sender cannot decrypt this data after submission.

Step 5: Create Transfer Order intent

Create the Transfer Order intent using the suggestedIntentId returned in Step 1.

Transfer Order intent payload:

FieldTypeRequiredDescription
payload.accountIdstring (uuid)YesSource account ID
payload.ledgerIdstringNoLedger identifier
payload.parameters.operationobjectYesTransfer operation details including destination, amount, and type
payload.typestringYesMust be v0_CreateTransferOrder
Critical

Use the suggestedIntentId from Step 1 when creating the intent. This links the compliance check to your transaction.

Step 6: Risk screening

If transaction screening is configured (Chainalysis or Elliptic), Ripple Custody screens the transaction first.

  • If screening fails (high risk score): The transaction is immediately rejected. No Travel Rule check occurs.
  • If screening passes: The workflow proceeds to the Travel Rule check.

Step 7: Travel Rule check

Notabene verifies counterparty information and PII.

Step 8: Compliance decision

Ripple Custody evaluates the results:

Screening ResultTravel Rule ResultDecision
ApprovedApprovedAUTO_APPROVED
RejectedAUTO_REJECTED (Travel Rule skipped)
ApprovedRejectedAUTO_REJECTED
InconclusiveInconclusiveNEED_EXPLICIT_DECISION

If the decision is NEED_EXPLICIT_DECISION, manual review is required in Ripple Custody.

If only one check is configured (screening only or Travel Rule only), the decision is based on that single check.

Step 9: Execution and settlement

  • If AUTO_APPROVED: Transaction executes on blockchain, then Notabene is notified of settlement.
  • If AUTO_REJECTED: Intent closes, then Notabene is notified of rejection.

Verify transfer status

Poll the Travel Rule transfer status to confirm successful execution:

GET /v1/domains/{domainId}/compliance/travel-rule/providers/{provider}/messages/{travelRuleId}

Key response fields:

FieldTypeDescription
transfer.statusstringNotabene transfer status (e.g., SETTLED, REJECTED)
transfer.directionstringOUTGOING for this workflow

Next steps