Eligibility Registers
Request Admission
Queue a customer wallet for a profile eligibility register
POST
/
customers
/
api
/
eligibility
/
admissions
curl -X POST "https://api.trusset.org/customers/api/eligibility/admissions" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"profileKey": "PROFESSIONAL",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"confirmEligibility": true,
"note": "Opt-up to professional client approved by compliance on 2026-10-01"
}'
const response = await fetch('https://api.trusset.org/customers/api/eligibility/admissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
profileKey: 'PROFESSIONAL',
walletAddress: '0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA',
confirmEligibility: true,
note: 'Opt-up to professional client approved by compliance on 2026-10-01'
})
});
const { success, data, error } = await response.json();
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0003l40a2r5w8y1n",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"customerId": "cmgdy2b7r0004l40a9c3e6f2h",
"status": "PENDING",
"source": "API",
"sourceRef": null,
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": null,
"admittedTxHash": null,
"admittedAt": null,
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": null,
"error": null,
"createdAt": "2026-10-05T10:47:09.512Z",
"updatedAt": "2026-10-05T10:47:09.512Z"
},
"alreadyAdmitted": false
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:47:09.530Z"
}
}
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0002l40a8t6x3v9q",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6",
"customerId": "cmgdv8h2c0002l30a4n7q1z5k",
"status": "ADMITTED",
"source": "KYC_LINK",
"sourceRef": "cmgdv7f1b0001l30a9e3m6x2p",
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": "2027-10-05T14:02:11.371Z",
"admittedTxHash": "0xf74c4d459825fd4ed545a14911d0ac951aa378cf40924b9c75036c1e85080f8b",
"admittedAt": "2026-10-05T09:15:24.000Z",
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
"error": null,
"createdAt": "2026-10-05T09:02:51.204Z",
"updatedAt": "2026-10-05T14:02:11.384Z"
},
"alreadyAdmitted": true,
"removalCancelled": true,
"renewed": true
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T14:02:11.402Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "ELIGIBILITY_CONFIRMATION_REQUIRED",
"message": "The customer was onboarded under the RETAIL profile. Admitting the wallet to Professional records your decision that the customer meets its requirements; send confirmEligibility: true to make it."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:46:52.118Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "REVERIFICATION_REQUIRED",
"message": "The admission of 0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6 to the Professional profile is waiting for removal because its re-verification period ran out. Re-verify the customer, or send confirmEligibility: true to record that the customer was re-verified outside Trusset."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T13:58:40.271Z"
}
}
Queues a wallet for admission to the eligibility register of one verification profile. Nothing is written on chain here: the admission waits as
The customer must meet the profile again first. A customer record still
PENDING until your wallet signs it through Build Admission and Confirm Admission. See Eligibility registers.
Most admissions need no request. Trusset queues one when a customer of the profile passes an ID link review or is registered on your instance register. Use this endpoint for a customer onboarded before the profile had a register, or under a different profile.
Who can be admitted
The wallet must belong to a customer record on your instance that is not archived. A wallet no customer holds is refused withCUSTOMER_NOT_FOUND, so onboard the customer first. The customer must also meet the profile:
- The customer’s
statusis notrejectedorrevoked. - The customer’s country is not on the profile’s
blockedCountries. - The customer’s
customerTypematches the profile’sentityType:INDIVIDUALorCOMPANY.
Admitting under another profile
A customer onboarded under one profile, whoseinvestorType names that profile, does not automatically meet another. To admit them anyway, send confirmEligibility: true. That records your decision that the customer meets this profile’s requirements, together with the profile they were onboarded under, on the admission and in the customer audit log. Without it the request is refused with ELIGIBILITY_CONFIRMATION_REQUIRED.
The investorType is compared with the profile key in any letter case. Admissions Trusset queues on its own never need the confirmation, because they follow the profile the customer was verified under.
Registers that take no request
The profile’s register mode, recorded when the register was bound, is checked before the customer. See Which registers can be signed here. When the profile’s register is your instance register itself, registering a wallet there is its admission. Nothing is queued, and the call answers201 with admission: null, mode: INSTANCE_REGISTER and a message. Register the wallet through Verify Identity or the pending queue instead.
When the profile’s register is managed outside your instance, in the EXTERNAL mode, its owner admits wallets with its own tools. The call is refused with 409 ADMISSIONS_MANAGED_EXTERNALLY.
A wallet waiting for removal
An admission inREMOVAL_PENDING has a removal waiting to be signed. A request for that wallet withdraws the removal instead of queuing a new admission. Whether it can depends on why the removal was queued:
removalReason | Withdrawn by this request |
|---|---|
LAPSED, REVOKED, REJECTED | Only with confirmEligibility: true, which records that you re-verified the customer outside Trusset. Otherwise 409 REVERIFICATION_REQUIRED |
MANUAL, COUNTRY_BLOCKED | Yes, without a confirmation |
revoked or rejected is refused with CUSTOMER_NOT_ELIGIBLE, and a country still blocked with COUNTRY_BLOCKED.
A fresh verification of the customer, through an ID link or a registration on your instance register, withdraws a LAPSED, REVOKED or REJECTED removal on its own. It never withdraws a MANUAL or COUNTRY_BLOCKED removal. Only a request from you, here or in the Issuer Portal, does.
The register is read before anything changes, and the outcome follows what it holds:
- The wallet is still on the register. The removal is cancelled and the admission is
ADMITTEDagain:200withalreadyAdmitted: trueandremovalCancelled: true. - The wallet is already off the register, for example because a removal was signed but not yet confirmed. The admission goes back to
PENDINGand waits to be built like a new one:201withalreadyAdmitted: false.
Re-verification
When the profile setsreverifyDays, an admission is due again that many days after it was admitted, and a lapsed admission is queued for removal with reason LAPSED.
The period restarts only on a verification of the customer, through an ID link or a registration on your instance register, or on a request sent with confirmEligibility: true that withdraws a removal while the wallet is still on the register. The response then carries renewed: true, and dueAt counts from now. A request never renews an admission that is already ADMITTED.
An admission made
ADMITTED again without a verification or a confirmation keeps its dueAt. When that date has already passed, the admission lapses again at once, and its new LAPSED removal then needs confirmEligibility: true.Body Parameters
string
The profile, by key. Matched exactly, then in upper and lower case. Send this or
profileId.string
The profile, by
id. Used instead of profileKey when both are sent.string
required
The wallet to admit,
0x followed by 40 hex characters. Stored and returned checksummed.boolean
true to admit a customer onboarded under another profile, or to withdraw a LAPSED, REVOKED or REJECTED removal after you re-verified the customer outside Trusset. Only the boolean true counts.string
A note kept with the admission and in the audit log, up to 300 characters. Longer text is cut.
What comes back
| Situation | HTTP | Response |
|---|---|---|
| Queued, or queued again after a removal or cancellation | 201 | admission with status: PENDING, alreadyAdmitted: false |
| Already waiting | 201 | The same PENDING admission, alreadyAdmitted: false |
| Already on the register | 200 | admission with status: ADMITTED, alreadyAdmitted: true |
| A removal was waiting and the wallet is still on the register | 200 | The removal is cancelled and the admission is ADMITTED again. alreadyAdmitted: true, removalCancelled: true, and renewed: true with confirmEligibility: true |
| A removal was waiting and the wallet is already off the register | 201 | The admission is PENDING again, alreadyAdmitted: false |
| The profile’s register is your instance register | 201 | admission: null, mode: INSTANCE_REGISTER and a message |
Response Fields
object
Show child attributes
Show child attributes
object
boolean
true when the wallet is already on the register. Absent with mode: INSTANCE_REGISTER.boolean
Present and
true when a waiting removal was cancelled.boolean
Present and
true when the re-verification period started again, so dueAt counts from now.string
INSTANCE_REGISTER, only when the profile’s register is your instance register.string
Why nothing was queued, with
mode only.curl -X POST "https://api.trusset.org/customers/api/eligibility/admissions" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"profileKey": "PROFESSIONAL",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"confirmEligibility": true,
"note": "Opt-up to professional client approved by compliance on 2026-10-01"
}'
const response = await fetch('https://api.trusset.org/customers/api/eligibility/admissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
profileKey: 'PROFESSIONAL',
walletAddress: '0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA',
confirmEligibility: true,
note: 'Opt-up to professional client approved by compliance on 2026-10-01'
})
});
const { success, data, error } = await response.json();
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0003l40a2r5w8y1n",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"customerId": "cmgdy2b7r0004l40a9c3e6f2h",
"status": "PENDING",
"source": "API",
"sourceRef": null,
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": null,
"admittedTxHash": null,
"admittedAt": null,
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": null,
"error": null,
"createdAt": "2026-10-05T10:47:09.512Z",
"updatedAt": "2026-10-05T10:47:09.512Z"
},
"alreadyAdmitted": false
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:47:09.530Z"
}
}
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0002l40a8t6x3v9q",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6",
"customerId": "cmgdv8h2c0002l30a4n7q1z5k",
"status": "ADMITTED",
"source": "KYC_LINK",
"sourceRef": "cmgdv7f1b0001l30a9e3m6x2p",
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": "2027-10-05T14:02:11.371Z",
"admittedTxHash": "0xf74c4d459825fd4ed545a14911d0ac951aa378cf40924b9c75036c1e85080f8b",
"admittedAt": "2026-10-05T09:15:24.000Z",
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
"error": null,
"createdAt": "2026-10-05T09:02:51.204Z",
"updatedAt": "2026-10-05T14:02:11.384Z"
},
"alreadyAdmitted": true,
"removalCancelled": true,
"renewed": true
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T14:02:11.402Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "ELIGIBILITY_CONFIRMATION_REQUIRED",
"message": "The customer was onboarded under the RETAIL profile. Admitting the wallet to Professional records your decision that the customer meets its requirements; send confirmEligibility: true to make it."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:46:52.118Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "REVERIFICATION_REQUIRED",
"message": "The admission of 0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6 to the Professional profile is waiting for removal because its re-verification period ran out. Re-verify the customer, or send confirmEligibility: true to record that the customer was re-verified outside Trusset."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T13:58:40.271Z"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
INVALID_ADDRESS | 400 | walletAddress is not a valid address, or is the zero address |
COUNTRY_BLOCKED | 403 | The customer’s country is on the profile’s blocked list |
PROFILE_NOT_FOUND | 404 | Neither profileId nor profileKey names a profile of your instance |
CUSTOMER_NOT_FOUND | 404 | No customer record on your instance holds the wallet, or the one that does is archived |
CUSTOMER_NOT_ELIGIBLE | 409 | The customer behind the wallet is rejected or revoked |
ENTITY_TYPE_MISMATCH | 409 | The customer’s customerType differs from the profile’s entityType |
ELIGIBILITY_CONFIRMATION_REQUIRED | 409 | The customer was onboarded under another profile and confirmEligibility is not true |
REVERIFICATION_REQUIRED | 409 | The wallet’s removal is waiting with reason LAPSED, REVOKED or REJECTED, and confirmEligibility is not true. Re-verify the customer, or confirm that you did |
ADMISSIONS_MANAGED_EXTERNALLY | 409 | The profile’s register is in the EXTERNAL mode, so its owner admits wallets with its own tools |
ELIGIBILITY_REGISTER_NOT_SET | 409 | The profile has no eligibility register |
RATE_LIMIT_EXCEEDED | 429 | Your instance went over its budget of 120 eligibility requests per minute. See Rate limits |
REQUEST_ADMISSION_FAILED | 500 | The admission could not be recorded |
CHAIN_UNAVAILABLE | 503 | A removal was waiting and the register could not be read to tell whether the wallet is still on it. Nothing changed. Retry shortly |
⌘I
curl -X POST "https://api.trusset.org/customers/api/eligibility/admissions" \
-H "Content-Type: application/json" \
-H "X-API-Key: trusset_your_key_here" \
-d '{
"profileKey": "PROFESSIONAL",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"confirmEligibility": true,
"note": "Opt-up to professional client approved by compliance on 2026-10-01"
}'
const response = await fetch('https://api.trusset.org/customers/api/eligibility/admissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'trusset_your_key_here'
},
body: JSON.stringify({
profileKey: 'PROFESSIONAL',
walletAddress: '0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA',
confirmEligibility: true,
note: 'Opt-up to professional client approved by compliance on 2026-10-01'
})
});
const { success, data, error } = await response.json();
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0003l40a2r5w8y1n",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0xfF21b8AC28Bb6A20c1c0160AF42303D2946B99EA",
"customerId": "cmgdy2b7r0004l40a9c3e6f2h",
"status": "PENDING",
"source": "API",
"sourceRef": null,
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": null,
"admittedTxHash": null,
"admittedAt": null,
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": null,
"error": null,
"createdAt": "2026-10-05T10:47:09.512Z",
"updatedAt": "2026-10-05T10:47:09.512Z"
},
"alreadyAdmitted": false
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:47:09.530Z"
}
}
{
"success": true,
"data": {
"admission": {
"id": "cmgdz1k4p0002l40a8t6x3v9q",
"profileKey": "PROFESSIONAL",
"profileName": "Professional",
"registryAddress": "0x4f2A9c81D06e3b75A1C8E24D9B07f56E3a1d8C90",
"walletAddress": "0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6",
"customerId": "cmgdv8h2c0002l30a4n7q1z5k",
"status": "ADMITTED",
"source": "KYC_LINK",
"sourceRef": "cmgdv7f1b0001l30a9e3m6x2p",
"lapsed": false,
"current": true,
"requirementsHash": "0x8919ea37bac1f44ea0e8a37529be970cb49e9779ebd4c4e98490cfd754e9d390",
"dueAt": "2027-10-05T14:02:11.371Z",
"admittedTxHash": "0xf74c4d459825fd4ed545a14911d0ac951aa378cf40924b9c75036c1e85080f8b",
"admittedAt": "2026-10-05T09:15:24.000Z",
"removalReason": null,
"removalTxHash": null,
"removedAt": null,
"signedBy": "0xCD92134767aEC2562be15d2a2062A082dA17dD84",
"error": null,
"createdAt": "2026-10-05T09:02:51.204Z",
"updatedAt": "2026-10-05T14:02:11.384Z"
},
"alreadyAdmitted": true,
"removalCancelled": true,
"renewed": true
},
"error": null,
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T14:02:11.402Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "ELIGIBILITY_CONFIRMATION_REQUIRED",
"message": "The customer was onboarded under the RETAIL profile. Admitting the wallet to Professional records your decision that the customer meets its requirements; send confirmEligibility: true to make it."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T10:46:52.118Z"
}
}
{
"success": false,
"data": null,
"error": {
"code": "REVERIFICATION_REQUIRED",
"message": "The admission of 0x2D27abCA46009EEF7D73eD1B1e913809f2280bE6 to the Professional profile is waiting for removal because its re-verification period ran out. Re-verify the customer, or send confirmEligibility: true to record that the customer was re-verified outside Trusset."
},
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-10-05T13:58:40.271Z"
}
}
