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:

ParamTypeNotes
action_prefixstringPrefix match on action, e.g. auth. or task.retry.
outcomestringsuccess, failure, etc.
user_idUUIDFilter by actor user.
sinceRFC 3339Lower bound on occurred_at.
cursoropaquePagination cursor from prior page.
limitint1..5000.
formatstringcsv, json, or xlsx. Switches to export mode (see below).
fieldsstringComma-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.