Read the audit trail¶
Your organisation's audit trail records every change to its people, groups, roles, attributes, rules, invitations and settings. This page shows how to read and filter it. What it holds and what it does not is in Roles and access.
org-admin or auditor reads the audit trail. It has no screen in OS yet: you read it through the
API. The examples use $OS, $TOKEN and $ORG as in Manage groups.
Read the trail¶
curl -s "$OS/api/v1/organisations/$ORG/audit-events?limit=100" \
-H "Authorization: Bearer $TOKEN"
OS returns the rows oldest first, in pages of at most 200 (50 by default). Pass next_cursor as
cursor for the next page. A row looks like this:
{"id": 4182, "at": "2026-10-17T09:12:00Z", "request_id": "...",
"actor_membership_id": "mem_...", "actor_organisation_id": "org_...",
"event": "role.assigned", "kind": "role", "thing_id": "ras_...",
"changes": {"role": [null, "people-admin"], "reach": [null, "organisation"],
"member_id": [null, "mem_..."]},
"allowed_actions": ["see"]}
| Field | Meaning |
|---|---|
at, request_id |
when, and the request that made the change |
actor_membership_id |
who: a membership, or system for what OS did itself |
actor_organisation_id |
from which organisation: yours, or one above when a partner or an operator acted |
event |
what happened, as <kind>.<verb> |
kind, thing_id |
what it happened to |
changes |
each recorded field that changed, as [before, after] |
Filter¶
Add one or more filters to the query:
event=membership.deactivated: only this event;kind=group: only changes to one kind of thing;actor=mem_...: only what one person did.
curl -s "$OS/api/v1/organisations/$ORG/audit-events?event=rule.replaced" \
-H "Authorization: Bearer $TOKEN"
Which events there are¶
| Event | What is recorded |
|---|---|
group.created, group.changed, group.deleted |
name and labels; on delete how many members the group had |
group.member_added, group.member_removed |
the group and the member |
role.created, role.changed, role.deleted |
name, labels and rules; on delete how many assignments went with it |
role.assigned, role.unassigned |
the role, the reach, and the member or the group |
attribute.defined, attribute.changed, attribute.deleted |
name, allowed values and multiple; on delete how many values went with it |
attribute.value_assigned, attribute.value_removed |
the attribute, the value, and the member or the group |
rule.replaced |
the rules |
membership.deactivated, membership.reactivated, membership.removed |
the status |
membership.profile_changed |
which of name and phone an administrator changed, never the values |
membership.rows_removed |
how many roles, groups and values went when OS cleaned up a removed member |
invitation.sent, invitation.revoked, invitation.accepted |
the invitation's membership; on accepting, the new person is the actor |
organisation.relabelled, organisation.retention_set |
the labels are on the organisation; the retention period |
An accepted invitation also writes a row for every role, group and value it gave.
What the trail does not hold¶
No passwords, tokens, keys and no e-mail addresses: an invitation is recorded by its id. After a person is erased, their membership ids are still there, but they identify nobody any more.
A change to people or settings is in the trail at once. Changes to memberships and invitations reach it in the background, shortly after. When you read a page again you also see rows recorded later; the trail is for reading, not for following live.
How long the trail is kept¶
Rows are kept for 400 days by default; then OS deletes them. The period is the organisation's
audit_retention_days. Only your operator changes it; ask there if you need another period.
At Artific Core too¶
OS also delivers every row to your organisation's audit trail at Artific Core, within a few
minutes. There it sits among Core's own events, under Calls and product events, with Artific
OS as its origin and os. before the event's name, such as os.role.assigned. So at Core you read
one trail of everything that happened in your organisation.
Core shows a changed field as before and after. A field holding a list, such as an attribute's
allowed values, is shown as two fields: allowed_values_before and allowed_values. A field Core
cannot keep, such as a role's rules or a group's labels, is not there but named under omitted;
OS's trail keeps it whole. Rows from before OS started delivering are in OS's
trail only.
This works once Artific Core's operator has switched it on for OS. Until then the rows wait, and OS's trail is complete on its own.
When OS refuses¶
| Answer | Meaning | What you do |
|---|---|---|
403 |
The organisation, or one above it, is suspended. | Ask your operator what is going on. |
404 |
You may not read the trail, so it does not exist for you; or the organisation does not exist or you do not reach it. | Check $ORG, or ask an administrator for the role auditor. |
422 |
A filter or limit is not valid, for example limit above 200. |
Read errors in the answer. |