Audit log
What every action writes. Retention, export, and integrations.
Every decision your team makes. Auto or human, approve or deny, share or unshare. Writes an immutable row to the audit log. Retention is per-workspace.
What's logged
| Action | Event kind | Subject |
|---|---|---|
| Workspace created / archived | workspace.* | workspace |
| Member invited / accepted / role-changed / removed | member.* | user |
| Team created / member added / removed / archived | team.* | team |
| Machine paired / revoked | machine.* | machine |
| Resource shared / unshared | {resource}.shared / .unshared | resource |
| Workflow run started / step approved / step denied / completed / failed | workflow_run.* | workflow run |
| Plan reviewed / approved / denied / revised | plan.* | plan |
| Approval gate decided | approval_gate.* | inbox item |
| Context candidate proposed / approved / discarded | context.* | vault entry |
| Auth: sign in / sign out / pairing approval | auth.* | user |
| Settings change | settings.* | workspace |
Each row carries:
idULID, timestamp.workspace_id. The tenant.actor_user_idoractor_token_idoractor_kind: 'system'.actor_ip,actor_user_agent(where applicable).subject_type,subject_id.kind,payload(JSON, what changed).result:success/denied/error.correlation_id(group related events from one request).
Retention
| Plan | Default retention |
|---|---|
| Free | 30 days |
| Team | 90 days |
| Enterprise | 365 days, configurable up to 7 years |
Workspace owners + admins can change retention in Settings → Audit. Lowering retention does not delete past rows. It sets the policy going forward. Past rows age out under the policy that was in effect when they were written.
View the audit log
In the web app, Audit is its own page:
- Time-sorted, filterable by actor, kind, subject.
- Each row expandable to show the JSON payload.
- Permalink per row.
Export
POST /api/workspaces/{workspace}/audit/export
Content-Type: application/json
{
"from": "2026-04-01T00:00:00Z",
"to": "2026-05-01T00:00:00Z",
"format": "ndjson" // or "csv"
}Returns a signed URL valid for 24 hours. Files are in the format you requested with one row per event.
Available formats:
ndjson. One JSON object per line, ideal for SIEM ingestion.csv. Flat columns, payload as a JSON string.
For compliance scenarios that require longer retention or bulk export, see Enterprise plans.
Audit log integrity
- Rows are append-only at the DB level.
- Sequence numbers per workspace (
audit_seq) make gap detection easy: if the export has rows 1, 2, 4, 5, you know row 3 was suppressed (it wasn't. But the structure lets you prove it). - Rows do not include resource content (plan text, context body). They reference resource IDs. Audit doesn't double as a content store.
- Soft-deletes of subject rows do not delete their audit history.
Cross-org visibility
The audit log is workspace-scoped. If you belong to multiple orgs, you see each org's audit log independently when you're in that org. There is no global cross-org audit query for non-Viewport-staff.
For multi-org users (consultants, shared engineers), this means: actions in org A do not appear in org B's audit, even if you're the actor. Each org gets only its own view.
Common workflows
Investigation: who approved this plan?
In the audit log, filter by kind: plan.approved and the plan id. The row shows the actor, timestamp, and IP. Plan IDs are in URLs and email links.
Compliance: monthly export to SIEM.
Schedule a cron that POSTs to the export endpoint each month with from / to covering the prior month, ingest the signed URL.
Member departure: what did Alice do?
Filter by actor_user_id. All her actions across the org are listed. Useful for offboarding reviews.
Where to go next
- Reference: API. Audit. Full endpoint reference.
- Webhook delivery. Stream audit events live.