Skip to content

Audit API

The audit log is project-scoped and admin-only. A single endpoint serves both pagination (default) and export (when format is set); there is no separate /export route. Chain verification is a CLI command (z4j audit verify), not an HTTP endpoint.

GET /api/v1/projects/{slug}/audit

Role: admin.

Query params:

Param Type Notes
action_prefix string Prefix match on action, e.g. auth. or task.retry.
outcome string success, failure, etc.
user_id UUID Filter by actor user.
since RFC 3339 Lower bound on occurred_at.
cursor opaque Pagination cursor from prior page.
limit int 1..5000.
format string csv, json, or xlsx. Switches to export mode (see below).
fields string Comma-separated column projection. Only honoured in export mode. Unknown column names are silently ignored.

Response (paginated mode):

{
"items": [
{
"id": "01H...",
"occurred_at": "...",
"user_id": "...",
"project_id": "...",
"action": "task.retry",
"target_type": "task",
"target_id": "01H...",
"outcome": "success",
"details": {"original_task_id": "01H...", "new_task_id": "01H..."},
"row_hmac": "...",
"prev_row_hmac": "..."
}
],
"next_cursor": "..."
}

Set format=csv (or json / xlsx) on the same endpoint to switch to export mode. Pagination is ignored; the full filter result is returned as a file download capped at 50000 rows. If the filter would return more rows than the cap, the request fails with a validation error pointing operators at the filter params – narrow by action_prefix, outcome, or since and re-run.

GET /api/v1/projects/{slug}/audit?format=csv&since=2026-01-01T00:00:00Z&action_prefix=auth.

Exports include row_hmac and prev_row_hmac so external systems can verify the chain independently.

There is no HTTP endpoint for chain verification. Run:

Terminal window
z4j audit verify

The CLI walks the full log and returns (ok, rows_verified, first_broken_id). For a scheduled check, wrap that command in cron or a Kubernetes CronJob. See HMAC audit chain for the chain construction.