Travel Rule Webhooks

These webhooks are sent when an incoming crypto deposit is held for EU Travel Rule (TFR) compliance and a user action is required, and when that action completes.

Travel Rule webhooks are delivered to the /tx endpoint appended to your Webhook URL (the same TRANSACTION channel as transaction status updates). Filter on the type field. These events are separate from the standard deposit and withdrawal TRANSACTION webhooks you receive when funds actually move after a hold clears.

Travel Rule hold webhooks are sent immediately when the hold is placed — there is no grace-period delay.

Event types

typeWhen
COUNTERPARTY_DECLARATION_REQUIREDA held deposit's source address has no declaration for this user.
WALLET_VERIFICATION_REQUIREDA held deposit needs wallet-ownership proof for an OWNED self-hosted counterparty above threshold.
VASP_COUNTERPARTY_USER_INFO_REQUIREDA held deposit from a declared VASP needs per-transaction originator counterparty user info created + linked.
BLOCKED_DUE_TO_TRAVEL_RULEThe transfer is blocked (e.g. third-party self-hosted at/above threshold).
USER_ACTION_COMPLETED_FOR_TRAVEL_RULEThe user action a held deposit was waiting on completed — the hold's blocking condition is satisfied.
WALLET_VERIFICATION_IN_REVIEWA Sumsub liveness wallet verification was submitted and is awaiting Sumsub's decision.
WALLET_VERIFICATION_COMPLETEDA counterparty wallet reached the VERIFIED state (signature or liveness).
WALLET_VERIFICATION_FAILEDA Sumsub liveness wallet verification terminally failed (non-retryable).

Payload shapes

ShapeIdentified bySent by
Hold placedtxHash, sourceAddress, destinationAddress (or counterpartyAddress on VASP_COUNTERPARTY_USER_INFO_REQUIRED)COUNTERPARTY_DECLARATION_REQUIRED, WALLET_VERIFICATION_REQUIRED, VASP_COUNTERPARTY_USER_INFO_REQUIRED, BLOCKED_DUE_TO_TRAVEL_RULE
CompletiontxId, txHash (or paymentHash), counterpartyId, memoUSER_ACTION_COMPLETED_FOR_TRAVEL_RULE
Verification pendingwalletVerificationId, address, network, methodWALLET_VERIFICATION_IN_REVIEW
Verification resultwalletVerificationId, address, network, method, memoWALLET_VERIFICATION_COMPLETED, WALLET_VERIFICATION_FAILED

Deposit Hold Webhooks

When an incoming deposit is placed on a Travel Rule hold, a single webhook is sent whose type reflects the required action — one of COUNTERPARTY_DECLARATION_REQUIRED, WALLET_VERIFICATION_REQUIRED, VASP_COUNTERPARTY_USER_INFO_REQUIRED, or BLOCKED_DUE_TO_TRAVEL_RULE. The payload shape is identical across these types; counterpartyId is present only when a counterparty record already exists for the source address.

txId is included for on-chain deposits and matches the txId on the corresponding USER_ACTION_COMPLETED_FOR_TRAVEL_RULE event, so you can correlate hold and completion events for the same deposit.

Action: Surface the required action to the user and resolve it via the counterparty API or widget.

For example, the notification below is sent when the source address has not been declared for the user -

{
  "uid": "37edf199-dcd1-4b95-8ddc-160e86d3b874",
  "type": "COUNTERPARTY_DECLARATION_REQUIRED",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "txHash": "0x7dc24b5316767f4269bbba3e9fb01a4af8af14d5e46e867d47dde3055cbbb262",
  "sourceAddress": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "destinationAddress": "0xd9f344019a5f2f26755f02a41548b4310be8F8fE",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "currency": "USDC",
  "network": "ETH",
  "amountInSmallestUnit": "10000000",
  "ts": 1779773742601
}

For example, the notification below is sent when a declared OWNED wallet at or above the threshold still needs a wallet-ownership signature -

{
  "uid": "8d2f0a1c-4b77-4a90-9d2e-2a6f1c9b7e10",
  "type": "WALLET_VERIFICATION_REQUIRED",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "txHash": "0x7dc24b5316767f4269bbba3e9fb01a4af8af14d5e46e867d47dde3055cbbb262",
  "sourceAddress": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "destinationAddress": "0xd9f344019a5f2f26755f02a41548b4310be8F8fE",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "currency": "USDC",
  "network": "ETH",
  "amountInSmallestUnit": "10000000",
  "ts": 1779773742601
}

For example, the notification below is sent when a deposit is blocked (e.g., a third-party self-hosted wallet at or above the threshold) -

{
  "uid": "b7c1a2d3-9e44-4f12-8a7b-1c2d3e4f5a6b",
  "type": "BLOCKED_DUE_TO_TRAVEL_RULE",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "txHash": "0x7dc24b5316767f4269bbba3e9fb01a4af8af14d5e46e867d47dde3055cbbb262",
  "sourceAddress": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "destinationAddress": "0xd9f344019a5f2f26755f02a41548b4310be8F8fE",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "currency": "USDC",
  "network": "ETH",
  "amountInSmallestUnit": "10000000",
  "ts": 1779773742601
}

Counterparty User Info Required (VASP)

The following webhook is sent when an incoming deposit from a declared VASP counterparty needs per-transaction originator (counterparty user info) created and linked to that transaction. Also re-sent for outstanding held deposits when you declare the VASP counterparty after the fact. For a Lightning deposit, counterpartyAddress and txHash are replaced by paymentHash.

Action: Create the originator record (POST /counterparty/vasp/counterparty-user-info) and link it to the held transaction (POST /counterparty/vasp/counterparty-user-info/link with txHash, or paymentHash for Lightning), or guide the user through the widget.

After a successful link, funds are credited.

{
  "uid": "9b895d1e-b4b3-4baa-a247-8423b7019232",
  "type": "VASP_COUNTERPARTY_USER_INFO_REQUIRED",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "txHash": "0x7dc24b5316767f4269bbba3e9fb01a4af8af14d5e46e867d47dde3055cbbb262",
  "counterpartyAddress": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "currency": "USDC",
  "network": "ETH",
  "amountInSmallestUnit": "10000000",
  "memo": "Travel Rule VASP counterparty user info required for transaction(txId: bf4dbe08-2cb6-43c2-9892-a887e8f4937f) to be completed.",
  "ts": 1779773900313
}

User Action Completed

Sent when the user action a held deposit was waiting on completes — a counterparty was declared (self-hosted or VASP), VASP counterparty user info was linked, or wallet ownership was verified for a held OWNED deposit. The hold's blocking condition is satisfied; the deposit may still wait for screening, monitoring review, an inbound TFR message, or other compliance before credit.

When it fires

  • Self-hosted declaration / wallet verification — settlement after declare or verify emits this before attempting release.
  • VASP user-info link — settlement after POST /counterparty/vasp/counterparty-user-info/link emits this before credit. If screening is already clear, the deposit may credit in the same pass; otherwise it stays held until screening clears or other compliance completes.

Action: None required. The user's obligation for that hold is satisfied.

This event is transaction-scoped — keyed by txId and the deposit's locator.

{
  "uid": "0c67d4c2-997d-491b-b90d-230182aa3f03",
  "type": "USER_ACTION_COMPLETED_FOR_TRAVEL_RULE",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "txHash": "0x7dc24b5316767f4269bbba3e9fb01a4af8af14d5e46e867d47dde3055cbbb262",
  "sourceAddress": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "destinationAddress": "0xd9f344019a5f2f26755f02a41548b4310be8F8fE",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "currency": "USDC",
  "network": "ETH",
  "amountInSmallestUnit": "10000000",
  "memo": "Travel Rule user action completed for transaction(txId: bf4dbe08-2cb6-43c2-9892-a887e8f4937f).",
  "ts": 1779774080209
}

For a Lightning deposit the locator collapses to a single paymentHash (no sourceAddress / destinationAddress / txHash) -

{
  "uid": "1f0aa2b3-5c61-49de-8a01-7b2c3d4e5f60",
  "type": "USER_ACTION_COMPLETED_FOR_TRAVEL_RULE",
  "txId": "bf4dbe08-2cb6-43c2-9892-a887e8f4937f",
  "paymentHash": "8ac740817d5f7794f550764945c3ac35f830364ea11e8427e36cf0319d0e3f71",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "currency": "BTC",
  "network": "BTC",
  "amountInSmallestUnit": "1500",
  "memo": "Travel Rule user action completed for transaction(txId: bf4dbe08-2cb6-43c2-9892-a887e8f4937f).",
  "ts": 1779774080209
}

Wallet-signature verification is synchronous, not a webhook. POST /counterparty/self-hosted/verify-wallet returns the result in its HTTP response — { "status": "VERIFIED", "walletVerificationId": "<uuid>", "counterparty": { ... } }. When the verified address has deposits on hold, those settle and emit USER_ACTION_COMPLETED_FOR_TRAVEL_RULE as above; expect normal TRANSACTION credit webhooks once each deposit clears.

Wallet Verification In Review

Sent when a wallet-ownership verification is submitted through Sumsub liveness and is awaiting Sumsub's decision. This fires at two points in the liveness lifecycle:

  • Initial submission — the user completes the Sumsub flow for the first time and Sumsub begins processing it.
  • Each retry attempt — if Sumsub returns a retryable result and the user resubmits, a new WALLET_VERIFICATION_IN_REVIEW is sent for that attempt.

Action: Update your UX to a "pending review" state. Wait for the follow-up WALLET_VERIFICATION_COMPLETED (success) or WALLET_VERIFICATION_FAILED (terminal failure).

Wallet-signature verification never produces this event — it completes synchronously.

{
  "uid": "c9d2a1e4-7f83-4b90-a1c2-d3e4f5a6b7c8",
  "type": "WALLET_VERIFICATION_IN_REVIEW",
  "walletVerificationId": "b2808090-f12a-48fc-8a7e-ddc77adb3a9e",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "syncedOwnerId": "940f999e-3625-47d2-baaa-c024814bd583",
  "userId": "940f999e-3625-47d2-baaa-c024814bd583",
  "address": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "network": "ETH",
  "method": "SUMSUB_LIVENESS",
  "ts": 1779774080209
}

Wallet Verification Completed

Sent when a counterparty wallet reaches the VERIFIED state — through either a wallet-ownership signature (WALLET_SIGNATURE) or a successful Sumsub liveness check (SUMSUB_LIVENESS). This event is verification-scoped (keyed by walletVerificationId) and fires once per verified wallet, independent of whether any deposit was waiting on it.

It is the success counterpart to WALLET_VERIFICATION_FAILED.

{
  "uid": "4743c02a-c6ef-4584-8b9e-04205f94f4bf",
  "type": "WALLET_VERIFICATION_COMPLETED",
  "walletVerificationId": "fa06c687-6d0f-4d50-8f36-0f16af066502",
  "counterpartyId": "0e2700c1-cd87-42b3-a7a4-97c5377f0231",
  "syncedOwnerId": "940f999e-3625-47d2-baaa-c024814bd583",
  "userId": "940f999e-3625-47d2-baaa-c024814bd583",
  "address": "0xed8052b2d9b85fa9c55d63ad297fcb86c177ff73",
  "network": "ETH",
  "method": "WALLET_SIGNATURE",
  "memo": "Travel Rule wallet verification completed (walletVerificationId: fa06c687-6d0f-4d50-8f36-0f16af066502).",
  "ts": 1780587322144
}

Verification applies to on-chain addresses only; Lightning paymentHash counterparties have no signable wallet and never produce this event.

Wallet Verification Failed

Sent when a wallet verification submitted through Sumsub liveness reaches a terminal, non-retryable failure. Notification-only — no hold or balance changes. You will not also receive a USER_ACTION_COMPLETED_FOR_TRAVEL_RULE for this verification; WALLET_VERIFICATION_FAILED is the single terminal-failure signal, because the user has to start verification again.

Action: Surface to the user and let them start verification again.

{
  "uid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "type": "WALLET_VERIFICATION_FAILED",
  "walletVerificationId": "b2808090-f12a-48fc-8a7e-ddc77adb3a9e",
  "counterpartyId": "9808388e-bd29-4110-b5d3-b183b59ca49e",
  "syncedOwnerId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "userId": "104894c7-95fc-4dde-97dd-cb25b2587b91",
  "address": "0x54d03EC0C462e9a01F77579C090cdE0FC2617817",
  "network": "ETH",
  "method": "SUMSUB_LIVENESS",
  "memo": "Travel Rule SumSub liveness wallet verification failed (walletVerificationId: b2808090-f12a-48fc-8a7e-ddc77adb3a9e). The user can start verification again.",
  "ts": 1779773900000
}

Retryable Sumsub outcomes do not emit this webhook. Wallet-signature verification never produces it — it completes synchronously through the verify-wallet HTTP response. Verification applies to on-chain addresses only; Lightning paymentHash counterparties have no signable wallet.