Skip to content

Audit logs

Every change made in a Tessule workspace leaves a trail, in two complementary logs. The HTTP audit log records every mutating API request — who called what, when, with which (redacted) payload, and what the server answered. The application events log records what those requests meant — a record created, a field updated, a table deleted — with before/after snapshots and structured actor attribution. Together they answer “who changed this, when, and what did it look like before”.

If you only remember one thing: the audit trail records writes, not reads. It can tell you who changed a record and what the old value was; it cannot tell you who looked at anything. Nobody’s viewing activity is logged.


  • Read both audit logs — requires the audit:read action. By default this is granted to all three built-in roles — Admin, Member, and Reader — not just admins.
  • See the Audit page in the app — the page lives in the Build area of the navigation (Build → Audit), which is shown only to holders of builder:access (admins by default, grantable to power users via a custom role). That gate is presentation only: anyone with audit:read can query the audit endpoints directly through the API, whether or not they can see the page.
  • Both logs are strictly workspace-scoped: you see your current workspace’s trail and nothing from any other workspace or organization.

GET /audit/http-logs (the HTTP Audit Logs tab of the Audit page) records one entry for every mutating request to the workspace API — POST, PUT, PATCH, and DELETE. Reads (GET) are never logged. Each entry carries:

Field What it holds
Method & path The HTTP method and the exact API path called
Request body The JSON payload, redacted and truncated (see below)
Response status The HTTP status the server returned — failed and rejected attempts are logged too
User The acting user’s ID, plus their email and name as they were at the time
Timestamp When the request happened

Redaction. The stored body is scrubbed before it is persisted: any field whose name looks credential-like (password, token, secret, apiKey, authorization, credential, …) is replaced with [REDACTED], workspace secret values are always redacted regardless of key name, and inbound webhook URL tokens are stripped from logged paths. Bodies larger than 32 KB are replaced by a marker listing which fields were sent — the audit value is what was attempted, and the first kilobytes answer that.

Unusual actors are recorded honestly rather than dropped:

  • Failed sign-in attempts appear with no user ID, flagged unauthenticated, with the email that was attempted — so a brute-force attempt against an account is traceable.
  • Platform operator writes (actions taken by Tessule’s own administrators through the operator control plane, e.g. provisioning a template workspace) appear with a null user ID and an operator block naming the acting administrator.
  • Impersonated sessions: when a platform administrator signs in as one of your users (a support capability), every write they make is attributed to the assumed user and carries an impersonation block with the real administrator’s identity and session ID. An assumed session can never be mistaken for the user’s own activity — and this is visible to you, in your own audit log.

The API supports filtering by method, path, status, and date range plus pagination (up to 1,000 rows per page); the in-app tab currently exposes the method filter and pagination, with each row expandable to show the stored request body.


GET /audit/events (the Application Events tab) records business-level changes as structured events, independent of which API call produced them:

  • Record eventsItemCreated, ItemUpdated, ItemDeleted
  • Schema eventsTableCreated/Updated/Deleted, FieldCreated/Updated/Deleted, ConstraintCreated/ConstraintDeleted
  • Approval eventsApprovalRequested, ApprovalDecided (see Approvals)

Each event carries the table/record/field it concerns, a timestamp, optional metadata (context such as which fields changed, or approval details), and — for updates and deletes — before and after snapshots of the entity. The snapshot pair on ItemUpdated is what lets you see exactly which values a save overwrote.

Actor attribution. Every event names the user it is attributed to, and the API additionally carries a structured actor: a person acting directly, an API token, or the system applying an approved change on behalf of its requester. An approval being applied shows both the requester (as the author) and the approver (in the event’s metadata).

The in-app tab filters by event type (the record and schema events) and paginates; each row expands to show the metadata and the before/after snapshots. Approval events appear in the unfiltered list. The API adds filtering by table, record, and date range.


  • Audit rows are retained indefinitely today. There is no automatic pruning of either log; long-term archival to cold storage is planned, and nothing will be deleted before it is safely archived. Do not confuse this with notifications, which are working memory and are pruned on a 30/90-day schedule — the audit log is the durable record.
  • Both endpoints page at up to 1,000 rows per request; use the date-range filters to work through long histories.
  • Request bodies are capped at 32 KB per entry (larger bodies keep the field names and a size marker).
  • Approval decisions have their own indefinite record: a decided pending change is never deleted, only marked with its outcome.

Can prove:

  • Who submitted which change, when — every mutating API call, from every surface (UI, REST API, imports, MCP/AI assistants), including failed and rejected attempts with their response status.
  • What a record looked like before a change — the before/after snapshots on update events.
  • Which principal really acted — API token, impersonating administrator, or the platform operator, none of which can masquerade as an ordinary user edit.

Cannot prove:

  • Who read or viewed anything. Reads are not logged, by design.
  • That two near-simultaneous saves didn’t overwrite each other. The trail shows both writes and their order, but preventing lost updates is the job of optimistic concurrency — see Data consistency, which walks through exactly what the audit trail does and does not guarantee here.
  • Court-grade financial history. Tessule’s audit trail is an operational record; if you need evidentiary-grade history, wrap your own process around exports and retention.

Q: I deleted a record — can I recover it from the audit log? The ItemDeleted event’s before-snapshot preserves the record’s last values, so you can read what it contained and re-create it manually. The audit log is not an undo mechanism, though — nothing in it can be “restored” with a click.

Q: A change shows a user who swears they didn’t make it. Expand the entry. If the write came through an API token, the token is the actor; if a platform administrator was assisting via an assumed session, the HTTP log entry carries an impersonation block naming them. The plain user ID is the attribution, not the whole story.

Q: Why can a Reader see the audit log? audit:read is part of the Reader baseline — the audit trail is treated as workspace-visible history, like the member list. If that’s too broad for your data, grant a custom role without audit:read instead of the Reader baseline (see Authorization & Permissions).

Q: Are operator (Tessule staff) actions in my workspace visible to me? Yes. Operator writes go through the same audited customer API — template provisioning appears with an operator attribution, and support access via an assumed identity is flagged per request with the administrator’s identity. There is no unaudited write path into your workspace.

Open the app