Skip to content

Record history and audit

Moltaro keeps an auditable history for record types that enable the audit trail: who changed what, when, and through which surface. This page covers the three developer touchpoints — reading history over the API, configuring audit per record type, and emitting business events from workspace C# code. For the user-facing view see Audit trail and History and audit.

All examples were executed against a real Moltaro installation; response bodies are real, trimmed for length.

GET /api/workspace/entity/{entityIdOrKey}/instances/{instanceId}/changes (operation) returns the change history of one record, newest first, paged with page/pageSize. The caller needs read access to the record and the Read changes history permission — history can expose values the current record state no longer shows:

Terminal window
curl -s "https://ops.example.com/api/workspace/entity/SupportTicket/instances/98520ecb203d4188abf10298a5a638e2/changes?page=1&pageSize=25" \
-H "Authorization: Bearer <token>"
{
"Data": {
"Items": [
{
"Id": "1e0b029f00ad49e7a3f193050414efd6",
"Operation": 1,
"ChangedAt": "2026-07-22T15:51:22.950314+00:00",
"Actor": { "Id": "3aba23d9-ef9b-4df8-a1cb-69a29781d5c4", "Name": "owner" },
"RecordContext": { "EntityDefinitionName": "SupportTicket", "DisplayNameSingular": "Support ticket" },
"FieldChanges": [
{ "Key": "ModifiedAt", "DisplayName": "Modified", "SystemField": 4,
"BeforeValue": null, "AfterValue": "2026-07-22T15:51:22.950314+00:00" },
{ "Key": "Priority", "DisplayName": "Priority", "SystemField": null,
"BeforeValue": "High", "AfterValue": "Medium", "FieldId": "l1eqb13B03NG" }
],
"TableChanges": [],
"AssignmentChanges": [],
"BusinessEvent": null
},
{
"Id": "f2992e9199d94ecb8c1bb6bc00533442",
"Operation": 0,
"ChangedAt": "2026-07-22T15:51:20.332602+00:00",
"Actor": { "Id": "3aba23d9-ef9b-4df8-a1cb-69a29781d5c4", "Name": "owner" },
"FieldChanges": [
{ "Key": "Number", "DisplayName": "Number", "SystemField": 0,
"BeforeValue": null, "AfterValue": "1" },
{ "Key": "Title", "DisplayName": "Title", "SystemField": null,
"BeforeValue": null, "AfterValue": "Printer in hall B is jammed" },
{ "Key": "Priority", "DisplayName": "Priority", "SystemField": null,
"BeforeValue": null, "AfterValue": "High" }
]
}
],
"TotalCount": 2,
"Page": 1,
"PageSize": 25
},
"Success": true
}

Each item carries the operation kind, the actor, the record context, and per-field BeforeValue/AfterValue pairs — for user-facing field kinds the values are display values (the Select field above reads "High", not the option key). System columns (number, created/modified stamps) appear as SystemField-tagged changes next to schema fields. Child-table row changes, assignment changes, and — when the entry was written by code rather than a field edit — a BusinessEvent payload (see below) complete the shape. Deleted and archived records keep their history within the definition’s retention settings.

Two module surfaces have their own history reads with the same philosophy: board items expose history and audit-trail, and Entitlement Operations keeps quantity truth in the append-only ledger.

Audit is a per-definition setting, and new definitions start with it on with unlimited retention. PUT /api/workspace/admin/entity-definitions/{entityDefinitionId}/audit-settings (operation) changes it:

Terminal window
curl -s -X PUT https://ops.example.com/api/workspace/admin/entity-definitions/pYZqCLZWb0K1/audit-settings \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "AuditTrailEnabled": true, "AuditTrailRetentionMode": 1,
"AuditTrailRetentionDays": null,
"RowVersion": "a244a235-1dc6-4e8b-81cf-2db6b972cd55" }'

AuditTrailRetentionMode is 0 disabled, 1 keep forever, 2 keep a rolling window of AuditTrailRetentionDays days. The definition detail exposes the current state as AuditTrailEnabled — the Integration quickstart discovery response shows it per record type, so an agent knows up front whether a record carries history.

Workspace C# logic (the Net Operation Project) has an explicit relationship with the audit trail:

  • Record saves made by function code do not write automatic field-level audit. Automatic save auditing is a host-runtime concern; for project code it is off and cannot be switched on per save. What users change through the product surfaces is audited by the platform; what your code changes is yours to narrate.
  • The supported emit path is a business event. MoltaroDbContext exposes AddBusinessEventAsync, which appends a display-safe event to the record’s audit trail — it requires the definition to have the audit trail enabled:
await Context.AddBusinessEventAsync<SupportTicket>(
ticketId,
new MoltaroBusinessEvent(
Title: "Escalated to on-site service",
Message: "SLA breach predicted; field engineer dispatched.",
Values:
[
new MoltaroBusinessEventValue("engineer", "Engineer", "K. Malek"),
new MoltaroBusinessEventValue("eta", "ETA", "2026-07-23")
]),
cancellationToken);
  • Business events surface in the change feed. The entry arrives with the acting user and shows up in the changes endpoint as a BusinessEvent payload and in the WebApp record history — one narrative for humans and agents.
  • Reading audit from C# goes through the API, not the DbContext. The generated workspace contract does not expose audit rows as queryable DbSets; read history through the changes endpoint above.
  • Boards and Entitlement application automation has fixed attribution. IBoardAutomationCommandService and IEntitlementAutomationCommandService persist as moltaro-system-automation. Their origin metadata retains the original user, FunctionRunId, function identity/version, and FunctionContext.CorrelationId, so operators can join a function run to Boards history/resource events or the Entitlement audit/ledger. Automation request DTOs intentionally cannot replace that actor.
  • Access and governance — roles, entity access models, and the permissions that gate history reads.
  • The workspace activity feed — cross-record activity for dashboards and monitoring.
  • C# business logic — the full programming model around the code shown here.
  • Reliable API automation - the cross-surface table for automatic record audit, explicit business events, Boards history, Entitlement ledger truth, and project publication state.