Dashboard Routes
Dashboard Routes
Aggregation endpoints backing the admin dashboard home screen. All four require the dashboard:read permission. Responses are cached in memory per process with configurable TTLs (see the cache.* options on the plugin page); successful user and tenant writes invalidate the affected cache keys so counts never go stale after a mutation.
Routes
| Method | Path | Permission | Description |
|---|---|---|---|
| GET | /api/admin/dashboard/health | dashboard:read | System health (database, Stripe) |
| GET | /api/admin/dashboard/metrics | dashboard:read | Platform metrics |
| GET | /api/admin/dashboard/active-users | dashboard:read | Active user count |
| GET | /api/admin/dashboard/errors | dashboard:read | Recent errors (requires ErrorLog model) |
GET /api/admin/dashboard/health
System health snapshot: overall status, per-service checks, uptime, and memory usage. Cached for cache.health seconds (default 10). The Stripe service check is included only when a fastify.stripe decorator is registered.
Usage
const response = await fetch("/api/admin/dashboard/health", {
headers: { Authorization: `Bearer ${adminToken}` },
});
const { data } = await response.json();
Response
{
"success": true,
"data": {
"status": "healthy",
"uptime": 3600,
"responseTime": 0,
"services": [
{ "name": "database", "status": "up", "lastCheck": "2026-07-27T12:00:00.000Z" },
{ "name": "stripe", "status": "up", "lastCheck": "2026-07-27T12:00:00.000Z" }
],
"memory": 62,
"nodeVersion": "v22.11.0"
}
}
status is "healthy" when every service is up, "degraded" otherwise.
GET /api/admin/dashboard/metrics
Platform-wide counts. Cached for cache.metrics seconds (default 60); invalidated by user and tenant writes.
Response
{
"success": true,
"data": {
"totalUsers": 1240,
"activeUsers": 312,
"totalRevenue": 0,
"revenueGrowth": 0,
"custom": { "totalTenants": 48, "activeTenants": 45 }
}
}
activeUsers counts users with a lastLoginAt in the last 30 days. totalRevenue/revenueGrowth are placeholders (0) in the current implementation.
GET /api/admin/dashboard/active-users
Users active in the last 15 minutes. Cached for cache.activeUsers seconds (default 30); invalidated by user writes.
Response
{
"success": true,
"data": { "count": 27, "trend": 0, "history": [] }
}
GET /api/admin/dashboard/errors
Recent entries from the optional ErrorLog Prisma model. Returns an empty array when the model does not exist. Cached for cache.metrics seconds, keyed by limit + severity.
Query Parameters
| Name | Type | Default | Description |
|---|---|---|---|
limit | number | 10 | Entries to return (1–100). |
severity | string | — | Filter by severity level. |
Response
{
"success": true,
"data": [
{
"id": "err_001",
"message": "Payment webhook failed",
"severity": "error",
"timestamp": "2026-07-27T11:45:00.000Z",
"stack": "Error: Payment webhook failed\n at ...",
"metadata": {}
}
]
}
Stack traces are truncated to 500 characters.
AI Context
package: "@xenterprises/fastify-xadmin"
routes:
- GET /api/admin/dashboard/health — service health (db, stripe), uptime, memory; cached cache.health s
- GET /api/admin/dashboard/metrics — user/tenant counts; cached cache.metrics s, invalidated on writes
- GET /api/admin/dashboard/active-users — users active in last 15 min; cached cache.activeUsers s
- GET /api/admin/dashboard/errors — recent ErrorLog entries (limit, severity); [] without ErrorLog model
permission: dashboard:read on all four
cache: in-memory per-process, lazy expiry; user/tenant writes invalidate metrics + activeUsers
See Also
- fastify-xadmin —
cache.*options and decorator reference - Audit Log Routes — persistent record of admin actions
Audit Log Routes
Admin audit log endpoints — GET /api/admin/audit-log with filtering and pagination, and POST /api/admin/audit-log/export to request an export.
Impersonation Routes
Admin impersonation sessions — POST /api/admin/impersonation/start, POST /stop, and GET /status, using a session token passed via the x-impersonation-token header.
