curl -s \
"https://engine.example.com/v1/holders/alpha/attributes" \
-H "Authorization: Bearer $TOKEN"// A client from OpenAPI Generator: see Build a client.
import {
Configuration,
HoldersApi,
ProblemFromJSON,
ResponseError,
} from "./nodeasset-client";
const api = new HoldersApi(new Configuration({
basePath: "https://engine.example.com",
accessToken: process.env.TOKEN,
}));
try {
const answer = await api.getHolderAttributes({ holderId: "alpha" });
console.log(answer.value);
} catch (e) {
if (!(e instanceof ResponseError)) throw e;
// A refusal is a problem; its type ends in the slug.
const problem = ProblemFromJSON(await e.response.json());
const slug = problem.type.split(":").pop();
console.error(e.response.status, slug, problem.detail);
}
# A client from OpenAPI Generator: see Build a client.
import os
import sys
import nodeasset_client
config = nodeasset_client.Configuration(
host="https://engine.example.com",
access_token=os.environ["TOKEN"],
)
with nodeasset_client.ApiClient(config) as client:
api = nodeasset_client.HoldersApi(client)
try:
answer = api.get_holder_attributes(holder_id="alpha")
print(answer.value)
except nodeasset_client.ApiException as e:
# A refusal is a problem; its type ends in the slug.
problem = nodeasset_client.Problem.from_json(e.body)
slug = problem.type.rsplit(":", 1)[-1]
print(e.status, slug, problem.detail, file=sys.stderr)
// A client from OpenAPI Generator: see Build a client.
import nodeasset.client.ApiClient;
import nodeasset.client.ApiException;
import nodeasset.client.api.HoldersApi;
import nodeasset.client.model.Problem;
public class GetHolderAttributes {
public static void main(String[] args) throws Exception {
ApiClient client = new ApiClient();
client.updateBaseUri("https://engine.example.com");
client.setRequestInterceptor(builder ->
builder.header("Authorization", "Bearer " + System.getenv("TOKEN")));
HoldersApi api = new HoldersApi(client);
try {
var request = HoldersApi.APIGetHolderAttributesRequest.newBuilder()
.holderId("alpha")
.build();
var answer = api.getHolderAttributes(request);
System.out.println(answer.getValue());
} catch (ApiException e) {
// A refusal is a problem; its type ends in the slug.
Problem problem = client.getObjectMapper()
.readValue(e.getResponseBody(), Problem.class);
String type = problem.getType();
String slug = type.substring(type.lastIndexOf(':') + 1);
System.err.println(e.getCode() + " " + slug + " " + problem.getDetail());
}
}
}
{
"offset": 0,
"ledgerTime": null,
"now": "2026-10-03T13:26:06.148629453Z",
"value": {
"holderId": "alpha",
"attributes": {
"residency": {
"value": "SG",
"state": "verified",
"expiresAt": "2027-10-01T00:00:00Z",
"proofHash": "sha256:71bb0d85eaa3ef967532c1362a20fed032d5889aa1cdd659e18a61485aefde94",
"evidence": "kyc/alpha/residency"
},
"investorType": {
"value": "professional",
"state": "verified",
"expiresAt": null,
"proofHash": "sha256:99104191dccbd729f5ee8dd91329ceb2be83da5eec4358e7e33c410e2882ad96",
"evidence": "kyc/alpha/investor-type"
},
"accreditation": null
},
"kyc": null,
"claims": [
{
"property": "residency",
"value": "SG"
},
{
"property": "residencyValidUntil",
"value": "2027-10-01T00:00:00Z"
},
{
"property": "investorType",
"value": "professional"
}
],
"version": 2,
"updatedAt": "2026-10-03T13:22:41.508812Z",
"updatedBy": "operator-1",
"operationId": "op-2b8e1c5d-4f3a-4d6e-9a7b-1c2d3e4f5a6b"
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}Get a holder's attributes
Returns the holder’s eligibility attributes, its outside KYC, and the claims they support, now or as they stood at at or asOf.
An investor reads its own holder only.
curl -s \
"https://engine.example.com/v1/holders/alpha/attributes" \
-H "Authorization: Bearer $TOKEN"// A client from OpenAPI Generator: see Build a client.
import {
Configuration,
HoldersApi,
ProblemFromJSON,
ResponseError,
} from "./nodeasset-client";
const api = new HoldersApi(new Configuration({
basePath: "https://engine.example.com",
accessToken: process.env.TOKEN,
}));
try {
const answer = await api.getHolderAttributes({ holderId: "alpha" });
console.log(answer.value);
} catch (e) {
if (!(e instanceof ResponseError)) throw e;
// A refusal is a problem; its type ends in the slug.
const problem = ProblemFromJSON(await e.response.json());
const slug = problem.type.split(":").pop();
console.error(e.response.status, slug, problem.detail);
}
# A client from OpenAPI Generator: see Build a client.
import os
import sys
import nodeasset_client
config = nodeasset_client.Configuration(
host="https://engine.example.com",
access_token=os.environ["TOKEN"],
)
with nodeasset_client.ApiClient(config) as client:
api = nodeasset_client.HoldersApi(client)
try:
answer = api.get_holder_attributes(holder_id="alpha")
print(answer.value)
except nodeasset_client.ApiException as e:
# A refusal is a problem; its type ends in the slug.
problem = nodeasset_client.Problem.from_json(e.body)
slug = problem.type.rsplit(":", 1)[-1]
print(e.status, slug, problem.detail, file=sys.stderr)
// A client from OpenAPI Generator: see Build a client.
import nodeasset.client.ApiClient;
import nodeasset.client.ApiException;
import nodeasset.client.api.HoldersApi;
import nodeasset.client.model.Problem;
public class GetHolderAttributes {
public static void main(String[] args) throws Exception {
ApiClient client = new ApiClient();
client.updateBaseUri("https://engine.example.com");
client.setRequestInterceptor(builder ->
builder.header("Authorization", "Bearer " + System.getenv("TOKEN")));
HoldersApi api = new HoldersApi(client);
try {
var request = HoldersApi.APIGetHolderAttributesRequest.newBuilder()
.holderId("alpha")
.build();
var answer = api.getHolderAttributes(request);
System.out.println(answer.getValue());
} catch (ApiException e) {
// A refusal is a problem; its type ends in the slug.
Problem problem = client.getObjectMapper()
.readValue(e.getResponseBody(), Problem.class);
String type = problem.getType();
String slug = type.substring(type.lastIndexOf(':') + 1);
System.err.println(e.getCode() + " " + slug + " " + problem.getDetail());
}
}
}
{
"offset": 0,
"ledgerTime": null,
"now": "2026-10-03T13:26:06.148629453Z",
"value": {
"holderId": "alpha",
"attributes": {
"residency": {
"value": "SG",
"state": "verified",
"expiresAt": "2027-10-01T00:00:00Z",
"proofHash": "sha256:71bb0d85eaa3ef967532c1362a20fed032d5889aa1cdd659e18a61485aefde94",
"evidence": "kyc/alpha/residency"
},
"investorType": {
"value": "professional",
"state": "verified",
"expiresAt": null,
"proofHash": "sha256:99104191dccbd729f5ee8dd91329ceb2be83da5eec4358e7e33c410e2882ad96",
"evidence": "kyc/alpha/investor-type"
},
"accreditation": null
},
"kyc": null,
"claims": [
{
"property": "residency",
"value": "SG"
},
{
"property": "residencyValidUntil",
"value": "2027-10-01T00:00:00Z"
},
{
"property": "investorType",
"value": "professional"
}
],
"version": 2,
"updatedAt": "2026-10-03T13:22:41.508812Z",
"updatedBy": "operator-1",
"operationId": "op-2b8e1c5d-4f3a-4d6e-9a7b-1c2d3e4f5a6b"
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"gate": "<string>",
"check": "<string>",
"recovery": "<string>",
"retryAfter": 123,
"retryable": true,
"packageName": "<string>",
"party": "<string>",
"contractId": "<string>",
"projectionOffset": 123,
"ledgerEnd": 123,
"code": 123,
"reason": "<string>",
"policyVersion": 123,
"errors": [
{
"pointer": "<string>",
"detail": "<string>"
}
]
}app, approver, auditor, investor, operator, risk. An investor reaches only its own holder’s records.Authorizations
A JWT from the deployment's identity provider, whose roles claim names the caller's roles and whose holder claim names an investor's holder.
Headers
A signed request's key id, as venue.api.signing.clients configures it for the bearer's subject.
Seconds since the epoch, within venue.api.signing.window of the engine's clock, 5 minutes by default.
^[0-9]+$At least 16 random bytes in base64url, never reused within twice the window.
22 - 128^[A-Za-z0-9_-]+={0,2}$The base64 HMAC-SHA256, under the key's secret, of the method, the path and query, the timestamp, the nonce and the body's SHA-256.
Your id for this request, 1 to 128 printable characters, repeated in the answer; absent, the engine makes one.
128^[\x21-\x7E]+$A W3C trace context, which the engine joins and passes on.
^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$Path Parameters
The holder's id.
Query Parameters
The ledger offset to read at, instead of the latest; not with asOf. What depends on time is judged at the offset's ledger time.
An instant to read the ledger as it stood then; not with at. What depends on time is judged at that instant.
Response
The holder's attributes.
The ledger offset the answer was read at; 0 for an answer from the engine's own records.
The ledger time of offset: the effective time of the latest transaction at or before it; null where the projection records none.
The engine's clock when it answered, an ISO-8601 instant.
What the read answers; for a list, the page's records in the list's order.
Show child attributes
Show child attributes

