Deposits, Travel Rule data first
When a counterparty institution sends funds to one of your customers, its Travel Rule data usually reaches you before the funds do. Notabene receives the transfer for you, checks the deposit address, receives the sender’s data and runs your policies, and once the sender settles the transfer, you credit your customer.
Most deposits need no call from you: your backend listens to the webhooks and credits the customer. You call Notabene only when it asks you something, in steps 2 to 4.
Before you start
- An access token, as described in Authentication. The examples use the sandbox base URL.
- Your customers and their deposit addresses registered with Notabene, as described in Customers and Wallets, so that step 2 never comes up.
- A webhook endpoint, as described in Webhooks.
1. Receive the transfer
When the sender creates the transfer, your webhook endpoint receives transfer.created.v3, with direction set to Incoming. The ref belongs to the sender, so it is empty on your copy.
{
"eventType": "transfer.created.v3",
"payload": {
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"for": "did:web:beneficiary.example:pt",
"from": "did:web:originator.example:pt",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt",
"asset": "eip155:1/slip44:60",
"amount": "0.5",
"ref": ""
}
}
{
"eventType": "transfer.created.v3",
"payload": {
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"for": "did:web:beneficiary.example:pt",
"from": "did:web:originator.example:pt",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt",
"asset": "eip155:1/slip44:60",
"amount": "0.5",
"ref": ""
}
}Read the transfer with include_ivms=true to see the sender’s personal data, which appears under originator.ivms once the deposit address is confirmed. Until then, originator holds only an id, and requires_action is true while something waits on you.
curl --get https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80 \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --data-urlencode 'include_ivms=true'const url = new URL('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80'); url.searchParams.set('include_ivms', 'true'); const response = await fetch(url, { method: 'GET', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', }, }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.get( 'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, params={ "include_ivms": "true" }, ) answer = None if response.status_code == 204 else response.json()
What to replace
8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80: The transfer’s id, from the webhook
{
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"status": "Active",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt",
"asset": "eip155:1/slip44:60",
"amount": "0.5",
"requires_action": true,
"originator": {
"id": "urn:uuid:c4eaf254-57e0-49f2-b10a-985f497eb389",
"ivms": {
"naturalPerson": {
"name": {
"nameIdentifier": [
{
"primaryIdentifier": "Silva",
"secondaryIdentifier": "Ana",
"naturalPersonNameIdentifierType": "LEGL"
}
]
}
}
}
},
"beneficiary": {
"id": "urn:uuid:e7d14b39-8a2c-4f05-b6e1-2c9f7a3d5b18"
}
}curl --get https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80 \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--data-urlencode 'include_ivms=true'const url = new URL('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80');
url.searchParams.set('include_ivms', 'true');
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
},
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.get(
'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
params={
"include_ivms": "true"
},
)
answer = None if response.status_code == 204 else response.json(){
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"status": "Active",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt",
"asset": "eip155:1/slip44:60",
"amount": "0.5",
"requires_action": true,
"originator": {
"id": "urn:uuid:c4eaf254-57e0-49f2-b10a-985f497eb389",
"ivms": {
"naturalPerson": {
"name": {
"nameIdentifier": [
{
"primaryIdentifier": "Silva",
"secondaryIdentifier": "Ana",
"naturalPersonNameIdentifierType": "LEGL"
}
]
}
}
}
},
"beneficiary": {
"id": "urn:uuid:e7d14b39-8a2c-4f05-b6e1-2c9f7a3d5b18"
}
}A transfer only reaches you once the sending institution’s policies have approved it. If the sender never sends its data, the requirement to receive it is skipped after 1 minute, and the skip is recorded in your audit trail.
2. If Notabene cannot match the address, register it
When Notabene cannot match the address, it sends requirements.pending.v3 with a WalletAddressConfirmation requirement whose agentId is your DID. The sender keeps its personal data until the address is confirmed.
Register the address with the customer it belongs to, and Notabene confirms it by itself within seconds, on this transfer and on any other open transfer to it. If the address is not yours, reject it instead.
curl https://sandbox.notabene.id/api/v1/wallets \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", "customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27" }'const response = await fetch('https://sandbox.notabene.id/api/v1/wallets', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ "address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", "customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27" }), }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.post( 'https://sandbox.notabene.id/api/v1/wallets', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, json={ "address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", "customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27" }, ) answer = None if response.status_code == 204 else response.json()
curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "outcome": "rejected" }'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ "outcome": "rejected" }), }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.post( 'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, json={ "outcome": "rejected" }, ) answer = None if response.status_code == 204 else response.json()
What to replace
eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed: The deposit address, as CAIP-10urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27: The id of your customer who owns the address8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80: The transfer’s id, from the webhook
{
"id": "did:pkh:eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"chain": "eip155:1",
"customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27",
"created_at": "2026-10-20T09:14:03Z"
}HTTP/1.1 204 No Contentcurl https://sandbox.notabene.id/api/v1/wallets \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27"
}'const response = await fetch('https://sandbox.notabene.id/api/v1/wallets', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27"
}),
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.post(
'https://sandbox.notabene.id/api/v1/wallets',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
json={
"address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27"
},
)
answer = None if response.status_code == 204 else response.json(){
"id": "did:pkh:eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"address": "eip155:1:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
"chain": "eip155:1",
"customer_id": "urn:uuid:3c9a7e52-41f6-4b8d-a0e2-6d1f9b4c8a27",
"created_at": "2026-10-20T09:14:03Z"
}curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"outcome": "rejected"
}'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"outcome": "rejected"
}),
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.post(
'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/wallet-address-confirmation/resolve',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
json={
"outcome": "rejected"
},
)
answer = None if response.status_code == 204 else response.json()HTTP/1.1 204 No ContentRejecting the address answers 204 and rejects the transfer. The sender is told that the address is not yours, so it stops treating it as yours.
3. If you match names, report the result
If you turned on beneficiary name matching, in the dashboard under Authorization Rules › Requirements, compare the beneficiary’s name with your customer’s once the sender’s data has arrived. Reporting the result answers 204.
curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "outcome": "matched" }'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ "outcome": "matched" }), }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.post( 'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, json={ "outcome": "matched" }, ) answer = None if response.status_code == 204 else response.json()
What to replace
8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80: The transfer’s id, from the webhookmatched: matched, partial_match or mismatch
HTTP/1.1 204 No Contentcurl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"outcome": "matched"
}'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"outcome": "matched"
}),
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.post(
'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/requirements/beneficiary-name-match/resolve',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
json={
"outcome": "matched"
},
)
answer = None if response.status_code == 204 else response.json()HTTP/1.1 204 No Content| Outcome | What happens |
|---|---|
matched | The check is satisfied, and your side goes on to your policies. |
partial_match | The transfer is held for a person on your team to review. |
mismatch | Your side rejects the transfer. |
| Outcome | What happens |
|---|---|
matched | The check is satisfied, and your side goes on to your policies. |
partial_match | The transfer is held for a person on your team to review. |
mismatch | Your side rejects the transfer. |
4. If your policies flag it, review the transfer
When your policies approve the transfer and nothing else is open on your side, your side is authorized automatically. When they flag it, a person on your team approves or rejects it, in the dashboard under Inbox › Transactions, or through the API.
curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "reason": "Reviewed by compliance" }'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ "reason": "Reviewed by compliance" }), }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.post( 'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, json={ "reason": "Reviewed by compliance" }, ) answer = None if response.status_code == 204 else response.json()
curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "reason": "Beneficiary account closed" }'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ "reason": "Beneficiary account closed" }), }); const answer = response.status === 204 ? null : await response.json();import requests response = requests.post( 'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject', headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'}, json={ "reason": "Beneficiary account closed" }, ) answer = None if response.status_code == 204 else response.json()
What to replace
8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80: The transfer’s id, from the webhookReviewed by compliance: Why your team approves it, kept on the transfer’s timelineBeneficiary account closed: Why your team rejects it, shared with the sender
{
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"status": "Rejected",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt"
}curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"reason": "Reviewed by compliance"
}'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason": "Reviewed by compliance"
}),
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.post(
'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/force-authorize',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
json={
"reason": "Reviewed by compliance"
},
)
answer = None if response.status_code == 204 else response.json()curl https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"reason": "Beneficiary account closed"
}'const response = await fetch('https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason": "Beneficiary account closed"
}),
});
const answer = response.status === 204 ? null : await response.json();import requests
response = requests.post(
'https://sandbox.notabene.id/api/v1/transfers/8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80/reject',
headers={'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
json={
"reason": "Beneficiary account closed"
},
)
answer = None if response.status_code == 204 else response.json(){
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"status": "Rejected",
"direction": "Incoming",
"counterparty": "did:web:originator.example:pt"
}Both calls answer as they do on Withdrawals, and a rejection tells the sender your reason.
Until you change your general default, which is set in Policies, a new account sends every deposit to review as well.
5. Credit your customer
The sender broadcasts the funds and records the transaction hash, so you do not record it yourself. Your webhook endpoint then receives transfer.status_changed.v3 with toStatus set to Settled and the hash in settlementId. Like every event, it can repeat or arrive out of order, so handle it as described in Webhooks.
{
"eventType": "transfer.status_changed.v3",
"payload": {
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"for": "did:web:beneficiary.example:pt",
"fromStatus": "ReadyToSettle",
"toStatus": "Settled",
"settlementId": "eip155:1:tx/0x7d3c9e1f0a2b4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d"
}
}
{
"eventType": "transfer.status_changed.v3",
"payload": {
"id": "8f3c2a1e-5b7d-4c90-a1f2-3e4d5c6b7a80",
"for": "did:web:beneficiary.example:pt",
"fromStatus": "ReadyToSettle",
"toStatus": "Settled",
"settlementId": "eip155:1:tx/0x7d3c9e1f0a2b4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d"
}
}Check the hash against the deposit your wallet received, then credit your customer. If the sender records the hash before your side is authorized, the status reads SettledIncompleteAuthorization until it is.
If your wallet receives a deposit that no transfer explains, it came without Travel Rule data, as described in Deposits, funds first.
When a call fails
| Answer | What it means |
|---|---|
400 with expected required property reason to be present | Approving needs a reason. |
400 with cannot force-authorize a concluded tx | The transfer is already Settled or Rejected. |
| 401 | The token is missing, malformed or expired. Authentication explains how to get a new one. |
| 409 on approve | The transfer’s compliance inputs changed while it was being approved. Send the request again. |
| Answer | What it means |
|---|---|
400 with expected required property reason to be present | Approving needs a reason. |
400 with cannot force-authorize a concluded tx | The transfer is already Settled or Rejected. |
401 | The token is missing, malformed or expired. Authentication explains how to get a new one. |
409 on approve | The transfer’s compliance inputs changed while it was being approved. Send the request again. |
Common mistakes
| Mistake | What happens | Instead |
|---|---|---|
| Reading the sender’s data before the address is confirmed | The originator and the beneficiary carry no personal data yet, since the sender sends it only once your institution has confirmed the address. | Register the address in step 2, then read the transfer. |
Reading the transfer without include_ivms=true | The originator and the beneficiary come with their ids only. | Add include_ivms=true when you need their personal data. |
| Rejecting the address to reject the transfer | The sender also learns that the address is not yours, and stops treating it as yours. | Reject the address only when it is not your customer’s. Otherwise reject the transfer. |
| Mistake | What happens | Instead |
|---|---|---|
| Reading the sender’s data before the address is confirmed | The originator and the beneficiary carry no personal data yet, since the sender sends it only once your institution has confirmed the address. | Register the address in step 2, then read the transfer. |
Reading the transfer without include_ivms=true | The originator and the beneficiary come with their ids only. | Add include_ivms=true when you need their personal data. |
| Rejecting the address to reject the transfer | The sender also learns that the address is not yours, and stops treating it as yours. | Reject the address only when it is not your customer’s. Otherwise reject the transfer. |
How it works
Done by Notabene
On the counterparty’s side
Only when needed
A counterparty institution creates a transfer to the address of one of your customers, and your webhook endpoint is told. The event and the call that reads the transfer are in 1. Receive the transfer.
Notabene checks that the deposit address belongs to you, receives the sender’s personal data once the address is confirmed, and runs your policies on the transfer.
- When you registered the address, or confirmed it on an earlier transfer, Notabene confirms it by itself.
- If the sender never sends its data, the requirement to receive it is skipped after its time-out and the skip is recorded in your audit trail. The time-out is 1 minute with either requirements preset.
Only when Notabene cannot match the address to you. Registering it with its customer confirms it, and rejecting it tells the sender it is not yours. The calls are in 2. If Notabene cannot match the address, register it.
Only if you turned on beneficiary name matching, which works with either requirements preset. The call and its answers are in 3. If you match names, report the result.
When the rules you configured approve the transfer and nothing else is open on your side, your side is authorized automatically, and there is no call to make.
When your policies flag the transfer, a person on your team approves or rejects it, in the dashboard under Inbox › Transactions, or through the API. The calls are in 4. If your policies flag it, review the transfer.
- Rejecting tells the sending institution, with your reason.
The sending institution broadcasts the funds on chain and records the transaction hash on the transfer. Your copy of the transfer follows.
- You do not record the settlement yourself: the sender does.
When the transfer is settled, check the hash against the deposit your wallet received, then credit your customer. The event is in 5. Credit your customer.
Related
Updated about 3 hours ago
