zerohash-hosted Remediation
A fully zerohash-hosted Travel Rule information recovery experience, with no collection UI to build on your end.
Overview
When a transfer is missing Travel Rule information, zerohash contacts the end customer directly and collects what the regulation requires. Your Platform is told what is happening through webhooks, but it never has to render a form, decide which fields apply, or handle a document upload.
This path is implicit for Platforms integrated to Account Funding or crypto deposits via SDK: the customer is redirected into information submission inside the SDK and emailed a link. For API integrations it is the recommended option, and the one that needs the least work to adopt.
Why platforms choose it
- Zero build required. You get a ready-made, compliant remediation experience without designing, building or maintaining your own collection flow.
- Complexity is handled. What must be collected varies by wallet type, by customer type and by transaction amount. zerohash manages that variation so your Platform does not have to encode it.
- Always up to date. As the regulation evolves, the remediation experience is updated on zerohash's side. There is nothing for you to ship when the rules change.
- Purpose-built UX. End customers get an interface designed for Travel Rule remediation, which matters for conversion on a step that would otherwise read as an unexplained delay.
Deposit received missing sending wallet travel rule information
How it works
- The customer sends crypto to zerohash.
- zerohash checks whether the sending wallet's Travel Rule information is available and meets TFR requirements, against Notabene, TRUST and the zerohash allow list.
- If the check passes, the deposit is credited to the customer and converted to fiat where applicable. Nothing further happens.
- If it fails, the deposit is held in collateral, a 48-hour timer begins, and your Platform receives a webhook indicating deposit was received and is missing travel rule information.
- zerohash emails the customer a Travel Rule information collection link, and sends a reminder email after 24 hours if they have not responded.
- The customer logs into the zerohash portal and provides the information. SDK-integrated Platforms can will have the submission flow surfaced inside the SDK as well.
- At the end of the 48-hour window, zerohash re-checks whether sufficient TFR data is available for the sending wallet.
- If it is, the deposit is credited to the customer and your Platform receives a webhook indicating the deposit has been successfuly processed. The customer receives confirmation from your Platform or from zerohash.
- If it is not, the deposit is credited to a quarantine account label for recovery and your Platform receives a webhook, indicating whether the customer failed to respond or the information they gave was rejected.
The funds are not lost in any branch of this flow. A quarantined deposit is recoverable.
Webhooks
Deposit received missing travel rule information
A deposit is held in collateral because Travel Rule information is missing. The 48-hour timer starts here.
{
"account_id": "da885ef0-49f0-5cfd-adcf-08488b8d04b3",
"amount": "500",
"asset": "ETH",
"deposit_id": "3af60e44-be66-4c7a-ab07-e324ec1760e3",
"participant_code": "G5JD0S",
"platform_code": "MERCH1",
"received_address": "0xdff7a4d40869F420fC21e04f02d8597A70c11726",
"source_address": "0xe3940dFC61e7E097b72c66892aC01aBa0Ae6a391",
"state": "pending_compliance_review",
"state_reason": "required_travel_rule_info",
"timestamp": 1790871269101,
"transaction_hash": "0xb863467b6eade708f804ddf64ecc8ef25b01fb2824fa8abad046dfda14c00b8b"
}Travel rule information submitted & received
Travel rule information has been submitted through POST /travel-rule/submit
{
"account_id": "b970f560-8d28-57cf-a750-b2f1db6b1c44",
"amount": "500",
"asset": "ETH",
"deposit_id": "3af60e44-be66-4c7a-ab07-e324ec1760e3",
"participant_code": "G5JD0S",
"platform_code": "MERCH1",
"received_address": "0xdff7a4d40869F420fC21e04f02d8597A70c11726",
"source_address": "0xe3940dFC61e7E097b72c66892aC01aBa0Ae6a391",
"state": "completed",
"state_reason": "travel_rule_info_received",
"timestamp": 1790871429030,
"transaction_hash": "0xb863467b6eade708f804ddf64ecc8ef25b01fb2824fa8abad046dfda14c00b8b"
}Travel rule information verified
Travel rule information has been verified by zerohash
{
"account_group": "YTEYJV",
"account_label": "general",
"account_type": "collateral",
"asset": "ETH",
"balance": "0",
"movements": [
{
"account_id": "c21cdbd2-3d51-58cf-8728-da0cdb07fd90",
"change": "-0.130000000000000000",
"movement_id": "8f73cce0-d11b-458d-965a-ce0aa92d0a5f",
"movement_timestamp": 1790873653576,
"movement_type": "transfer",
"parent_link_id": "a72d9ffa-ee0c-4cc3-bbe2-e6cec18f4b01",
"transfer_request_id": "99909",
"transfer_type": "travel_rule_deposit_info_verified"
}
],
"participant_code": "3JIAB3",
"run_id": "146709",
"run_type": "transfer",
"timestamp": 1790873653630
}Travel rule review timeout
The 48-hour window closed without the customer providing sufficient travel rule information.
Travel rule review rejected
The information the customer supplied was rejected.
Collecting travel rule information for a withdrawal's receiving wallet
How it works
- Your Platform requests an auth token with POST /client_auth_token for "crypto-account-link", then renders the SDK for the customer.
- The customer inputs the receiving wallet address.
- zerohash checks to see if travel rule information is available and sufficient to meet requirements for a withdrawal. If travel rule information is not available for the receiving wallet, the customer is prompted to provide the missing information in the SDK.
- zerohash stores the receiving wallet information.
- When a withdrawal is initiated, zerohash checks whether the receiving wallet address holds sufficient TFR data for that wallet type and withdrawal request amount.
- If it does, zerohash returns the auth token, the customer is able to initiate the withdrawal.
- If it does not, zerohash returns a Travel Rule information missing response to your Platform, and the customer is redirected to supply the missing fields inside the SDK before the withdrawal can proceed.
Because the requirements vary by amount, a linked wallet that was sufficient for one withdrawal can be insufficient for a larger one. Handle the missing-information response on every withdrawal attempt, not only the first.
Submitting information yourself
zerohash-hosted remediation does not stop Platforms from submitting Travel Rule information directly. Two cases where it is worth doing:
- Whitelisting self-custody wallets at onboarding. A deposit from an address already on the allow list with sufficient information does not undergo additional Travel Rule screening, so it never enters remediation. This is the most effective way to avoid holds entirely.
- Me-to-me transfers. Where the participant owns the address, their existing KYC or KYB record can be used instead of collecting anything from them.The endpoint is the same one used on the platform-hosted path.
| Field | Required | Description |
address | Yes | The wallet address the information relates to: the deposit source address, or the receiving wallet address for a withdrawal. |
participant_code | Yes | Identifies the end customer the wallet is associated with. |
address_owner_type | Yes | individual or business. Determines which PII object applies. |
wallet_type | Yes | self_custody or exchange. |
casp_did | Conditional | Required when wallet_type is exchange. The decentralised identifier of the exchange, for example did:example:kraken. Retrieve the supported list from GET /vasps. |
participant_is_address_owner | No | Set this when the participant identified by participant_code owns the address. Use it for me-to-me transfers to avoid submitting individual_pii or business_pii; zerohash uses the participant's existing KYC or KYB record instead. |
individual_pii | Conditional | Identity of the individual who owns the address. Required when address_owner_type is individual and participant_is_address_owner is not set. Fields: first_name, last_name, address, date_of_birth, place_of_birth. |
business_pii | Conditional | Identity of the entity that owns the address. Required when address_owner_type is business and participant_is_address_owner is not set. Fields: legal_entity_name, legal_entity_identifier (LEI), legal_entity_address. |
wallet_proof_of_ownership | Conditional | Self-custody wallets only, and only when more than €1,000 has moved to or from the wallet in the last 12 hours. Fields: document (base64-encoded screenshot showing the address), mime, file_name. |
deposit_id | No | The deposit this submission relates to, where there is one. Not relevant for withdrawals or for whitelisting at onboarding. |
Sample Request
Whitelisting a self-custody wallet for a business customer at onboarding:
{
"address": "0xABC123",
"participant_code": "CUST01",
"address_owner_type": "business",
"business_pii": {
"legal_entity_name": "Business XYZ",
"legal_entity_identifier": "123456789",
"legal_entity_address": "1 Example St, Dublin"
},
"wallet_type": "self_custody",
"wallet_proof_of_ownership": {
"document": "aGVsbG8gd29ybGQ=",
"mime": "pdf",
"file_name": "proof_of_ownership.pdf"
}
}Sample Request
A me-to-me transfer, where the participant owns the address and no PII object is needed:
{
"address": "0xABC123",
"participant_code": "CUST01",
"address_owner_type": "business",
"business_pii": {
"legal_entity_name": "Business XYZ",
"legal_entity_identifier": "123456789",
"legal_entity_address": "1 Example St, Dublin"
}Sample Response
The response returns the resulting permission state for the address, and for self-custody wallets the verification state of any proof of ownership:
{
"address": "0xABC123",
"participant_code": "CUST01",
"address_owner_type": "business",
"wallet_type": "self_custody",
"wallet_proof_of_ownership_status": "submitted_pending_verification",
"deposit": {
"status": "allowed"
},
"withdrawal": {
"status": "allowed"
}
}Travel Rule data for exchange wallets expires and must be re-submitted after 24 hours, which is why exchange-hosted wallets cannot be whitelisted at onboarding. The platform-hosted guide covers the exchange variants and the full response reference.
Things to know
- This is newly enacted regulation and the requirements are subject to change. That is the main argument for this path: changes are absorbed on zerohash's side rather than in your release cycle.
- This is process is often an edge case. When the sending CASP is TFR compliant, the required information reaches zerohash through Notabene or TRUST automatically and no remediation happens at all. Build for it, but do not expect it to be a common branch.
Updated about 1 hour ago