Audit log CSV export
The workspace audit log can be exported as CSV for archival, external review, or ingestion into a SIEM. The endpoint streams rows directly from Postgres, so an export of millions of rows completes in constant memory on both the server and the client.
Requires the Enterprise plan and workspace admin role.
Endpoint
GET /api/workspaces/{slug}/audit-logs/export.csv
Filters (all optional, all the same as the JSON list endpoint):
| Query parameter | Meaning |
|---|---|
action | Exact match on the dotted action code (e.g. workspace.member.invited) |
entity_type | Exact match on the target entity type (e.g. workspace, project, integration) |
actor_id | UUID of the actor user |
from | Lower bound on created_at, inclusive. RFC 3339, date-only (YYYY-MM-DD), or Unix seconds |
to | Upper bound on created_at, inclusive. Same formats |
Response
Content-Type: text/csv; charset=utf-8 with
Content-Disposition: attachment; filename="audit-<workspace-slug>-<utc-timestamp>.csv".
Columns
| # | Column | Format |
|---|---|---|
| 1 | id | UUID |
| 2 | created_at | RFC 3339 with nanoseconds, UTC |
| 3 | action | Dotted-string action code (e.g. member.role.changed) |
| 4 | entity_type | Target entity type |
| 5 | entity_id | UUID or empty |
| 6 | actor_user_id | UUID or empty (empty for system actions) |
| 7 | actor_token_id | UUID or empty (present when the actor used an API token) |
| 8 | actor_label | Fallback label (e.g. system, <deleted user>) |
| 9 | actor_display_name | Display name at the time of query |
| 10 | actor_email | Email at the time of query |
| 11 | ip_address | Text form of the request IP or empty |
| 12 | user_agent | Raw User-Agent header |
| 13 | metadata_json | The full metadata object as a JSON string |
Rows are ordered newest first (created_at DESC, id DESC) so a
trailing tail of the file is always the oldest data in the export
window. Newlines and quotes inside string columns follow standard CSV
escaping.
Examples
Full workspace export (largest, slowest):
curl -o audit.csv \
-H "Authorization: Bearer $ITHURA_API_TOKEN" \
"https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv"
Last 30 days of role changes only:
FROM=$(date -u -d '30 days ago' +%Y-%m-%d)
curl -o audit-role-changes.csv \
-H "Authorization: Bearer $ITHURA_API_TOKEN" \
"https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv?action=member.role.changed&from=$FROM"
Everything a single admin did last quarter, for an internal review:
curl -o audit-alice-q3.csv \
-H "Authorization: Bearer $ITHURA_API_TOKEN" \
"https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv?actor_id=$ALICE_UUID&from=2026-07-01&to=2026-10-01"
SIEM ingestion
Point your SIEM at the CSV directly, or schedule a job that downloads a
daily incremental export (from=<yesterday>) and ships the file to
your SIEM's bucket. The file is stable-schema and stable-order; a
diff-based ingest is safe.
A native SIEM streaming push (fire-and-forget webhook on every audit event, HMAC-signed) is on the sovereign roadmap as a follow-up to this export. Track it in the Ithura project under the Sovereign module.
Retention
Today Ithura retains every audit row indefinitely (no automated pruning). Configurable per-workspace retention is on the sovereign roadmap; until it ships, the export gives you the primitives you need to archive and then manually purge if your policy requires it.
Permissions
Only workspace admins (role 20) can call the export endpoint. The call
is itself audited under the action workspace.audit.exported with the
requested filters in the metadata column, so a reviewer can always
answer "who pulled the log, when, with what filters."