Identity Verification
Check Transfer Compliance
Ask the identity register whether a transfer between two wallets would pass
POST
/
customers
/
api
/
identity
/
can-transfer
curl -X POST "https://api.trusset.org/customers/api/identity/can-transfer" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"from": "0xaBc123DEf456789012345678901234567890aBCD",
"to": "0x1234567890AbcdEF1234567890aBcdef12345678",
"amount": "1000000000000000000000",
"fromBalance": "5000000000000000000000",
"toBalance": "200000000000000000000"
}'
const response = await fetch(
'https://api.trusset.org/customers/api/identity/can-transfer',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
from: '0xaBc123DEf456789012345678901234567890aBCD',
to: '0x1234567890AbcdEF1234567890aBcdef12345678',
amount: '1000000000000000000000',
fromBalance: '5000000000000000000000',
toBalance: '200000000000000000000'
})
}
);
const { data } = await response.json();
if (!data.allowed) {
console.error(`Transfer refused, reason ${data.reason}`);
}
{
"success": true,
"data": {
"allowed": true,
"reason": 0,
"senderStatus": "active",
"receiverStatus": "active"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "revoked"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "none",
"registerKind": "TREX"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
Asks the identity register your instance writes to whether a transfer between two wallets would pass its checks. Use it as a pre-flight check, so a refused transfer does not revert on chain.
On a Trusset register, the register checks the sender, then the receiver. Each must hold an identity that is not revoked, not hard-expired and not frozen. A soft-expired identity still passes. The register then asks each compliance module active on it, which sees
An ERC-3643 register only answers
On an ERC-3643 register,
allowed: true only means both wallets are verified on the register. No compliance rule is evaluated there, and amount and both balances are ignored.amount and both balances.
Body Parameters
string
required
Sender wallet.
string
required
Receiver wallet.
string
default:"0"
The amount as a whole number in the token’s smallest unit, such as
"1000000000000000000000" for 1,000 tokens with 18 decimals. A decimal string such as "1000.5" fails with CHECK_FAILED.string
default:"0"
The sender’s balance before the transfer, in the same unit.
string
default:"0"
The receiver’s balance before the transfer, in the same unit.
The basic compliance module refuses a transfer larger than
fromBalance. With the default of 0, any nonzero amount fails wherever that module is active. Send the real balances.Response Fields
object
Show child attributes
Show child attributes
boolean
Whether the transfer passes.
integer
0 when allowed. Otherwise the first check that failed, from the table below.string
On a Trusset register,
active, soft_expired, hard_expired or revoked. A wallet that was never verified also reads revoked. On an ERC-3643 register, active or none.string
The same, for the receiver.
string
ERC-3643 only. Always
TREX.reason | Meaning |
|---|---|
0 | Allowed |
1 | The sender holds no active identity. A revoked or never-verified sender lands here |
2 | The receiver holds no active identity. A revoked or never-verified receiver lands here |
3 | The sender is frozen |
4 | The receiver is frozen |
5 | The sender’s identity is hard-expired |
6 | The receiver’s identity is hard-expired |
10 | A compliance module refused the transfer |
11 | A compliance module failed when asked |
0, 1 or 2. A register that cannot be read answers 500 CHECK_FAILED, never allowed: false.
curl -X POST "https://api.trusset.org/customers/api/identity/can-transfer" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"from": "0xaBc123DEf456789012345678901234567890aBCD",
"to": "0x1234567890AbcdEF1234567890aBcdef12345678",
"amount": "1000000000000000000000",
"fromBalance": "5000000000000000000000",
"toBalance": "200000000000000000000"
}'
const response = await fetch(
'https://api.trusset.org/customers/api/identity/can-transfer',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
from: '0xaBc123DEf456789012345678901234567890aBCD',
to: '0x1234567890AbcdEF1234567890aBcdef12345678',
amount: '1000000000000000000000',
fromBalance: '5000000000000000000000',
toBalance: '200000000000000000000'
})
}
);
const { data } = await response.json();
if (!data.allowed) {
console.error(`Transfer refused, reason ${data.reason}`);
}
{
"success": true,
"data": {
"allowed": true,
"reason": 0,
"senderStatus": "active",
"receiverStatus": "active"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "revoked"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "none",
"registerKind": "TREX"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
INVALID_INPUT | 400 | from or to is missing or not a valid address |
CHECK_FAILED | 500 | The register could not be read, or on a Trusset register amount or a balance is not a whole number |
⌘I
curl -X POST "https://api.trusset.org/customers/api/identity/can-transfer" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"from": "0xaBc123DEf456789012345678901234567890aBCD",
"to": "0x1234567890AbcdEF1234567890aBcdef12345678",
"amount": "1000000000000000000000",
"fromBalance": "5000000000000000000000",
"toBalance": "200000000000000000000"
}'
const response = await fetch(
'https://api.trusset.org/customers/api/identity/can-transfer',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
from: '0xaBc123DEf456789012345678901234567890aBCD',
to: '0x1234567890AbcdEF1234567890aBcdef12345678',
amount: '1000000000000000000000',
fromBalance: '5000000000000000000000',
toBalance: '200000000000000000000'
})
}
);
const { data } = await response.json();
if (!data.allowed) {
console.error(`Transfer refused, reason ${data.reason}`);
}
{
"success": true,
"data": {
"allowed": true,
"reason": 0,
"senderStatus": "active",
"receiverStatus": "active"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "revoked"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
{
"success": true,
"data": {
"allowed": false,
"reason": 2,
"senderStatus": "active",
"receiverStatus": "none",
"registerKind": "TREX"
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-09-30T12:00:00.000Z"
}
}
