Audit Log Routes
Audit Log Routes
Read and export the audit trail. Entries are written automatically by every admin mutation (users, roles, tenants, impersonation, Stripe actions) and can also be written from your own routes via fastify.xAdmin.audit.log(request, entry) — see the plugin page. Audit-log write failures are caught and logged (message only) so they never break the operation being audited.
Routes
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /api/admin/audit-log | audit:read | List entries (paginated, filterable) |
| POST | /api/admin/audit-log/export | audit:export | Request an export |
GET /api/admin/audit-log
Paginated audit entries, newest first.
Usage
const response = await fetch(
"/api/admin/audit-log?page=1&limit=20&resource=users",
{ headers: { Authorization: `Bearer ${adminToken}` } }
);
const { data, meta } = await response.json();
Query Parameters
| Name | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (1-indexed). |
limit | number | — | Entries per page (1–100). |
action | string | — | Filter by action (e.g. create, update, delete). |
userId | string | — | Filter by the admin who performed the action. |
resource | string | — | Filter by resource (e.g. users, roles, tenants). |
resourceId | string | — | Filter by the affected resource ID. |
startDate | string | — | ISO start date (inclusive), e.g. "2026-01-01". |
endDate | string | — | ISO end date (inclusive), e.g. "2026-03-31". |
Date parameters must start with an ISO YYYY-MM-DD pattern or validation rejects the request with a 400.
Response
{
"success": true,
"data": [
{
"id": "log_001",
"action": "update",
"resource": "users",
"resourceId": "usr_123",
"userId": "usr_admin",
"description": "Changed role for user: alice@example.com",
"metadata": { "previousRole": "member", "newRole": "admin" },
"createdAt": "2026-07-19T11:30:00.000Z"
}
],
"meta": { "page": 1, "limit": 20, "total": 342, "totalPages": 18 }
}
POST /api/admin/audit-log/export
Request an export of audit entries. Records the export itself in the audit log.
Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
format | string | No | csv (default) or json. |
filters | object | No | Optional action, startDate, endDate filters. |
Response
{
"success": true,
"data": {
"downloadUrl": null,
"expiresAt": "2026-07-28T12:00:00.000Z",
"recordCount": 342,
"format": "csv",
"status": "pending"
}
}
The export is asynchronous: status is "pending" and downloadUrl is null until the file is ready (expiresAt is 24 hours out).
AI Context
package: "@xenterprises/fastify-xadmin"
routes:
- GET /api/admin/audit-log — paginated, newest first; query: page, limit (1-100), action, userId, resource, resourceId, startDate, endDate (ISO)
- POST /api/admin/audit-log/export — body: format (csv|json), filters { action, startDate, endDate }; returns pending status + recordCount
permissions: audit:read, audit:export
decorator: fastify.xAdmin.audit.log(request, { action, resource, resourceId?, description?, metadata? }) — failures swallowed after logging
auto-recorded: user/role/tenant/impersonation/stripe admin mutations
See Also
- Users Routes — actions recorded when users are modified
- Impersonation Routes — impersonation start/stop events appear here
fastify-xadmin
Admin dashboard API plugin for Fastify v5 — tenants, RBAC roles/permissions, user administration, audit logging, impersonation, and Stripe billing management.
Dashboard Routes
Admin dashboard aggregation endpoints — GET /api/admin/dashboard/health, /metrics, /active-users, /errors, with in-memory TTL caching.
