Skip to content

Audit API ​

2 endpoints. Request and response schemas are described on the schemas page; the other tags are listed in the API index.

Endpoints ​

GET /api/v1/admin/audit ​

List audit entries

List audit log entries, newest first (admin only). Two paging modes: offset paging (page/per_page, the default) and keyset paging (cursor). Keyset paging never counts rows or scans past an offset, so it stays fast on large tables; follow next_cursor while has_more is true. In offset mode total is exact when total_exact is true (small tables and the last page); otherwise it is the planner's row estimate (no filter) or a lower bound (with actor/action filters).

Parameters

NameInTypeRequiredDescription
pagequeryintegerno1-based page number (offset paging). Ignored when cursor is present. Minimum: 1.
per_pagequeryintegernoMinimum: 1. Maximum: 100.
cursorquerystringnoOpaque next_cursor of the previous page. Present but empty starts keyset paging at the newest entry. Selects keyset paging: the response carries no page, total or total_exact.
actorquerystringnoCase-insensitive substring of the actor name or actor id.
actionquerystringnoCase-insensitive substring of the action name.

Responses

StatusDescriptionBody
200Paginated list of audit entriesapplication/json: object
400Malformed cursor-
403Admin access required-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
dataarray of AuditEntryno-
has_morebooleannoTrue when entries follow this page.
next_cursorstringnoPass as cursor to fetch the next page. Absent when has_more is false.
pageintegernoOffset paging only.
per_pageintegerno-
totalintegernoOffset paging only. See total_exact.
total_exactbooleannoOffset paging only. False when total is an estimate or a lower bound.

GET /api/v1/admin/audit/export ​

Export audit log

Export the audit log as JSONL or CSV (admin only). Streams the log as a download without counting rows: entries are read in keyset pages (newest first) and flushed after every page, so memory stays bounded however long the log is. The body is chunked (no Content-Length); if the server fails after the response started the connection is aborted rather than ended normally, so a truncated file is detectable. In CSV, cells starting with =, +, -, @, tab or CR are prefixed with ' to defuse spreadsheet formula injection. Fields (stable; new fields may be appended): id, timestamp (RFC 3339, UTC), action, actor, actor_type, actor_id, resource_type, resource_id, repository_id, project_id, ip, details (JSON object; in CSV its JSON text). Unset values are null in JSONL and empty in CSV.

Parameters

NameInTypeRequiredDescription
formatquerystringnojsonl (default): one JSON object per line. csv: header row plus one record per entry. One of: jsonl, csv. Default: jsonl.
sincequerystringnoOnly entries at or after this instant: RFC 3339 timestamp or YYYY-MM-DD (00:00 UTC).
untilquerystringnoOnly entries strictly before this instant (same forms as since); must be after since.
actorquerystringnoCase-insensitive substring of the actor name or actor id.
actionquerystringnoCase-insensitive substring of the action name.

Responses

StatusDescriptionBody
200Audit export stream Headers: Content-Disposition.application/x-ndjson: string; text/csv: string
400Unknown format, malformed since/until, or since not before until-
403Admin access required-

Free software under the AGPL-3.0-or-later.