Audit events
The tenant's audit trail in one list: every change (who changed what, when, the row before and after, and why) and every logged read.
Needs audit:read. An admin reads it, Aleta does, and so does a user whose groups give the audit module (see groups); an API key reads as its owner. Anyone else gets 403 forbidden. A reader who does not see every client (anyone but an admin or Aleta) gets only the changes on custody accounts, cash accounts, lenses and clients they can see, and no reads. The trail is kept for 7 years, in whole calendar months.
The event
idstringStable identifier. A UUID.
kindstringchange(a write) oraccess(a read). The reads are the ones the Aleta apps log and, through this API, every successfulGETof your data, as aread.resource_typeis the route's resource in its v1 name (custody_account,client,lens, ...) andresource_idis the first id in the path. A report file download (GET /v1/reports/{id}/download) is logged as areadofreports; itsresource_idis the report's id. Reading this list is not logged, and the query string is never kept.occurred_atstringISO 8601 timestamp, UTC.
actionstringFor a change
create,update,delete,archive,unarchive,lock,unlock,publish, ...; for an accessread,export,download, ...resource_type, resource_idstring or nullWhat it was about, in the v1 name (
cash_account,custody_account,entity,asset,custodian_authority, ...). A resource with no v1 name is shown as stored. An access names the resource, and its id when the read had one.actorobject{kind, user_id, credential_id, owner_user_id, role}; the fields a kind does not have arenull.kindispersonwith theuser_id;machinefor an API key, with itscredential_idand the user it acts as inowner_user_id(a machine user acting as itself has itsuser_id);aletawhen Aleta acted (its fleet key or a staff seat), with the staffroleand never who (no ids, and the person's id, e-mail and name are taken out ofbeforeandafter); orsystem(sync, calculation, migration). An asset's history shows the same actor.before, afterobject or nullThe row as it was and became.
nullon an access, on a create (before) or delete (after), and on a redacted change.changesobject[]{field, before, after}per top-level field that changed.reasonstring or nullWhy, when the write was given one.
request_idstring or nullThe request's
x-request-id.outcomestringsuccess,failureordenied.redactedbooleantruewhen personal data was erased (GDPR):beforeandafterare thennull.
List audit events
Newest first, one page at a time: pass limit (default 100; a larger value is capped at 1000) and the previous page's next_cursor as cursor. An unknown parameter, a cursor that does not decode, or a value below in the wrong format is 400 bad_request. Without audit:read, or without the right to read the trail, the answer is 403 forbidden.
Optional attributes
kindstringchangeoraccess; another value is a400.actor_user_idstringA user's UUID: only what this user did, directly or through one of their API keys (the actor's
user_idorowner_user_id). An API key'scredential_iddoes not match.resource_typestringOnly this resource, by its v1 name.
resource_idstringOnly this row.
occurred_from, occurred_tostringRFC 3339; from (inclusive) and to (exclusive).
curl -G https://api.aleta.ai/v1/audit-events \
-H "Authorization: Bearer {access_token}" \
-d resource_type=custodian_authority
{
"data": [
{
"id": "0199f2a1-0d4e-7b10-8c2d-4e5f6a7b8c9d",
"kind": "change",
"occurred_at": "2026-10-18T08:05:00.000000Z",
"action": "update",
"resource_type": "custodian_authority",
"resource_id": "0199f2a0-7c1e-7a40-9d1b-3c5e8f0a2b11",
"actor": { "kind": "aleta", "user_id": null, "credential_id": null, "owner_user_id": null, "role": "aleta_internal" },
"before": { "status": "awaiting_aleta" },
"after": { "status": "active" },
"changes": [{ "field": "status", "before": "awaiting_aleta", "after": "active" }],
"reason": "the first file ran",
"request_id": "6f1c2d3e-4a5b-4c6d-8e7f-90a1b2c3d4e5",
"outcome": "success",
"redacted": false
}
],
"next_cursor": null,
"limit": 100
}