Skip to content

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.