curl -s \
"https://engine.example.com/v1/approvals?limit=100" \
-H "Authorization: Bearer $TOKEN"
# Send each page's next back as after, until null.// A client from OpenAPI Generator: see Build a client.
import {
ApprovalsAndOperationsApi,
Configuration,
ProblemFromJSON,
ResponseError,
} from "./nodeasset-client";
const api = new ApprovalsAndOperationsApi(new Configuration({
basePath: "https://engine.example.com",
accessToken: process.env.TOKEN,
}));
try {
// Send each page's next back as after, until null.
let after: string | undefined;
do {
const page = await api.listApprovals({ limit: 100, after });
for (const approval of page.value ?? []) {
console.log(approval);
}
after = page.next ?? undefined;
} while (after);
} 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.ApprovalsAndOperationsApi(client)
try:
# Send each page's next back as after, until null.
after = None
while True:
page = api.list_approvals(limit=100, after=after)
for approval in page.value or []:
print(approval)
after = page.next
if after is None:
break
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.ApprovalsAndOperationsApi;
import nodeasset.client.model.Problem;
public class ListApprovals {
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")));
ApprovalsAndOperationsApi api = new ApprovalsAndOperationsApi(client);
try {
// Send each page's next back as after, until null.
String after = null;
do {
var request = ApprovalsAndOperationsApi.APIListApprovalsRequest.newBuilder()
.limit(100)
.after(after)
.build();
var page = api.listApprovals(request);
for (var approval : page.getValue()) {
System.out.println(approval);
}
after = page.getNext();
} while (after != null);
} 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,
"now": "2026-10-03T13:26:37.654270303Z",
"value": [
{
"actionKey": "policy.set-6b02b476021d124cec20af24",
"kind": "policy.set",
"resource": {
"kind": "instrument",
"id": "FUND",
"href": "/v1/instruments/FUND"
},
"maker": "operator-1",
"makerName": "Olive Park",
"makerEmail": "olive.park@venue.example",
"makerRole": "operator",
"madeAt": "2026-10-03T13:24:38.436690Z",
"state": "approved",
"checker": "approver-1",
"checkerName": "Ann Kim",
"checkerEmail": "ann.kim@venue.example",
"checkedAt": "2026-10-03T13:24:38.449164Z",
"operationId": "op-e4aa8a51-8330-47b5-87b0-1d31ece49972",
"reason": null,
"method": "PUT",
"path": "/v1/instruments/FUND/policy",
"body": {
"policy": {
"limits": null,
"lockup": null,
"holding": {
"max": 50000000,
"min": null
},
"windows": null,
"denyList": [],
"admission": {
"requires": [],
"maxHolders": 100,
"trustedIssuers": []
},
"countries": null,
"supplyCap": null,
"investorTypes": null,
"liquidateOnly": false
},
"summary": "Cap the fund at 100 holders",
"effectiveAt": null,
"expectedVersion": 0
},
"required": 1,
"signedBy": [
"approver-1"
],
"signers": [
{
"sub": "approver-1",
"name": "Ann Kim",
"email": "ann.kim@venue.example",
"signedAt": "2026-10-03T13:24:38.449164Z"
}
]
}
],
"next": null
}{
"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>"
}
]
}List approvals
Lists four-eyes actions, newest first.
curl -s \
"https://engine.example.com/v1/approvals?limit=100" \
-H "Authorization: Bearer $TOKEN"
# Send each page's next back as after, until null.// A client from OpenAPI Generator: see Build a client.
import {
ApprovalsAndOperationsApi,
Configuration,
ProblemFromJSON,
ResponseError,
} from "./nodeasset-client";
const api = new ApprovalsAndOperationsApi(new Configuration({
basePath: "https://engine.example.com",
accessToken: process.env.TOKEN,
}));
try {
// Send each page's next back as after, until null.
let after: string | undefined;
do {
const page = await api.listApprovals({ limit: 100, after });
for (const approval of page.value ?? []) {
console.log(approval);
}
after = page.next ?? undefined;
} while (after);
} 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.ApprovalsAndOperationsApi(client)
try:
# Send each page's next back as after, until null.
after = None
while True:
page = api.list_approvals(limit=100, after=after)
for approval in page.value or []:
print(approval)
after = page.next
if after is None:
break
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.ApprovalsAndOperationsApi;
import nodeasset.client.model.Problem;
public class ListApprovals {
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")));
ApprovalsAndOperationsApi api = new ApprovalsAndOperationsApi(client);
try {
// Send each page's next back as after, until null.
String after = null;
do {
var request = ApprovalsAndOperationsApi.APIListApprovalsRequest.newBuilder()
.limit(100)
.after(after)
.build();
var page = api.listApprovals(request);
for (var approval : page.getValue()) {
System.out.println(approval);
}
after = page.getNext();
} while (after != null);
} 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,
"now": "2026-10-03T13:26:37.654270303Z",
"value": [
{
"actionKey": "policy.set-6b02b476021d124cec20af24",
"kind": "policy.set",
"resource": {
"kind": "instrument",
"id": "FUND",
"href": "/v1/instruments/FUND"
},
"maker": "operator-1",
"makerName": "Olive Park",
"makerEmail": "olive.park@venue.example",
"makerRole": "operator",
"madeAt": "2026-10-03T13:24:38.436690Z",
"state": "approved",
"checker": "approver-1",
"checkerName": "Ann Kim",
"checkerEmail": "ann.kim@venue.example",
"checkedAt": "2026-10-03T13:24:38.449164Z",
"operationId": "op-e4aa8a51-8330-47b5-87b0-1d31ece49972",
"reason": null,
"method": "PUT",
"path": "/v1/instruments/FUND/policy",
"body": {
"policy": {
"limits": null,
"lockup": null,
"holding": {
"max": 50000000,
"min": null
},
"windows": null,
"denyList": [],
"admission": {
"requires": [],
"maxHolders": 100,
"trustedIssuers": []
},
"countries": null,
"supplyCap": null,
"investorTypes": null,
"liquidateOnly": false
},
"summary": "Cap the fund at 100 holders",
"effectiveAt": null,
"expectedVersion": 0
},
"required": 1,
"signedBy": [
"approver-1"
],
"signers": [
{
"sub": "approver-1",
"name": "Ann Kim",
"email": "ann.kim@venue.example",
"signedAt": "2026-10-03T13:24:38.449164Z"
}
]
}
],
"next": null
}{
"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>"
}
]
}approver, auditor, compliance, operator, risk.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}$Query Parameters
Only actions in these states; repeat it for several. Absent, every state.
Where a four-eyes action stands.
awaiting, approved, rejected Only actions of these operation kinds; repeat it for several. Absent, every kind.
What an operation does: the record it acts on and the act, <record>.<verb>.
instrument.record, policy.set, admission-consent.propose, instrument.pause, holder.register, holder.onboard, holder.close, holder.register-successor, holder.set-attributes, admission.offer, admission.withdraw, accepted-terms.accept, subscription.claim, subscription.withdraw, subscription.deliver, subscription.settle, subscription.release, primary-market.propose, redemption.claim, redemption.withdraw, redemption.release, redemption.settle, dealing-cycle.open, dealing-cycle.settle, dealing-cycle.release, standing-settlement.open, standing-settlement.settle, standing-settlement.pause, standing-settlement.resume, standing-settlement.close, reserve.propose, reserve.close, lock-agreement.propose, lock-agreement.release, mint.start, mint.cancel, reserve-redemption.start, reserve-redemption.cancel, reserve-report.create, amendment.propose, amendment.withdraw, provision-settlement.propose, distribution.execute, distribution.roll, standing-approval.grant, standing-approval.revoke, holder.restrict, holder.restrict-batch, restriction.lift, issuer-powers-agreement.propose, issuer-powers-consent.offer, holder.force-transfer, holder.recover, instrument.force-transfer, instrument.recover, hold.release, external-account.map, webhook.register, webhook.remove, webhook.test Only the action that ran as this operation.
Only actions on these kinds of record; repeat it for several. Absent, every kind.
A kind of record an operation, an action or an event concerns.
instrument, holder, subscription, redemption, dealing-cycle, standing-settlement, reserve, lock-agreement, mint, reserve-redemption, amendment, distribution, standing-approval, reconciliation-run, external-statement, primary-market, restriction, hold, webhook, external-account, external-source, issuer-powers-agreement, scheduled-distribution, contract, exercise Only actions on this record.
Only actions made at this instant or later, by madeAt.
Only actions made before this instant, by madeAt.
The most records a page holds, 1 to 1000; 50 by default.
1 <= x <= 1000The previous page's next; absent, the first page.
Response
The actions.
The ledger offset the answer was read at; 0 for an answer from the engine's own records.
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
The cursor for the next page, sent back as after; null on a list's last page, never on a feed.

