Skip to content

Docs

Team audit log

Enterprise

A per-team record of every view, edit, and access change on the team's folders and notes. Built for enterprise teams in client- and partner-adjacent contexts where "who saw what" actually matters. Opt-in per team, available on request alongside SAML SSO and SCIM.

What gets recorded

When the audit log is on for a team, these categories write a row. Read the limitations alongside this list: a few paths deliberately or currently write nothing, so treat this as what is captured rather than as an exhaustive account of every code path.

  • Views. Opening a team note or folder. Repeat views within five minutes collapse into one row, so a page refresh doesn't bury the signal. Signed-in repeats are keyed on the account; anonymous public-link repeats are keyed on a hashed IP, so several visitors behind one address collapse together.
  • Mutations. Creating, editing, archiving, restoring, deleting, moving, or favoriting team content, and exporting a team folder. Bulk operations on the notes page record one row per affected note.
  • Access changes. Invites, accepted invitations, member removals, ownership transfers, public link toggles, and SCIM provisioning from an external IdP.
  • Account-level. When a team member deletes their Hjarni account. When team-level AI instructions are changed through MCP.

Surfaces covered

The audit log spans every way someone can reach your data, not just the web app. Coverage is per-surface rather than uniform, so check the limitations for the paths that write nothing:

web
Browser sessions, including bulk operations on the notes page.
api
REST API calls with a Bearer token. See the API reference.
mcp
Claude, ChatGPT, Cursor, or any MCP client connected to the team's brain. Rows include the MCP client's user-agent.
public
Anonymous reads via a public folder link. Each visitor is identified by a hashed IP, not a user account.
scim
Membership changes pushed from an external identity provider via SCIM. Actor is the IdP, not a user.

What's in a row

Each entry captures:

  • When. To the second.
  • Who. The actor's email, or "anonymous" for public-link readers, or "system" for SCIM operations.
  • Action. A namespaced label like note.viewed, container.updated, team.member_removed.
  • Target. The affected note or folder, with its full path snapshotted at the time of the event so the row stays readable even if the resource is later deleted.
  • Source. One of the surfaces above.
  • IP hash. A one-way hash of the visitor's IP. Useful for spotting an abusive public-link reader without storing raw addresses.
  • Details. Action-specific metadata. Which attributes changed, where a note was moved from and to, who invited whom.

Who can see the log

Only the team owner. Team members see the disclosure banner that activity is being recorded but cannot read the log itself. This is deliberate. The audit log is a control surface for the data steward, not surveillance data for peers.

If ownership of a team transfers, the historical audit log follows the team to the new owner.

How to enable it

The audit log is an Enterprise feature, available on request alongside SAML SSO and SCIM provisioning. Email evert@hjarni.com and mention the team name to turn it on.

Once enabled:

  • A disclosure banner appears on the team page for every member.
  • The owner sees a View audit log link in that banner.
  • Rows start being written immediately. Filter by action or by folder subtree on the audit log page.

Member disclosure

When the audit log is on, every team page carries a notice telling members that views, edits, and access changes on the team are recorded. This is not optional and not hideable per-member. Audit logging without disclosure would be surveillance; disclosed audit logging is a control.

The exact wording, copied from the live UI:

Audit log on. Activity on this team is recorded across the web, the REST API, MCP (Claude / ChatGPT), and anonymous public links.

Limitations

Worth knowing up front:

  • Personal accounts aren't audited. The audit log is a team-only feature by design. Personal brains stay outside it.
  • MCP search results don't write per-hit view rows. A single search call from an AI assistant can surface a hundred notes; recording a hundred view rows per query would dwarf real reads. Searches are still captured as a single note.searched analytics event, but each surfaced note isn't individually logged. The same applies to notes-list and containers-list. Note that search can return note bodies when the client passes include_body, so content can leave without a view row.
  • Version history reads aren't logged. Fetching a note's revisions returns historical bodies without writing a view row, on the web, the REST API, and MCP notes-history alike. A note.viewed row means someone opened the current note, not that nobody has read its past versions.
  • A few write paths are unlogged. Ticking a checkbox in a note body, reordering folders, editing team AI instructions in the web UI (the MCP path is logged), and exporting the whole team in one go (per-folder exports are logged) all move or change data without writing a row today. These are gaps rather than design decisions, and are on the list to fix; don't read the absence of a row as proof nothing changed.
  • Folder listings on the REST API write a folder view row. Listing a folder's children, notes, or tree records one container.viewed row for the folder itself. That is one row per listing, not one per note surfaced, so it tells you the folder was browsed rather than which notes were seen.
  • No automatic retention pruning yet. Audit log entries persist indefinitely. A retention policy is on the roadmap.
  • No built-in CSV export. Reach out if you need entries dumped for a subject access request or for downstream compliance tooling.
  • PII in metadata. When someone deletes their account, the audit row mirrored to the team owner carries the deleted email. The invitee's email is captured on team.invited rows. Both persist past the original record's deletion. Acceptable for an audit log; worth knowing if you have strict data-minimisation requirements.

Related

Give your AI a memory. Free.

Connect Claude or ChatGPT to notes they can actually read and write.

Get started free

Give your AI a memory. Free.