Admin
All admin endpoints require an authenticated user with the isAdmin flag. Every action mentioned here writes a row to the admin audit log; the affected user can read those entries via GET /auth/admin-activity.
GET /admin/stats
Aggregate dashboard stats.
200 OK
{
"users": number,
"maps": number,
"storage": number, // bytes
"recentSignups": number, // last 7 days
"monthlySignups": number, // last 30 days
"tierBreakdown": { tier: count, ... }
}GET /admin/users
List users with pagination, search, and sort.
Query
page number (default 1)
limit number (default 20, max 100)
search string (matches username or email)
tier string (filter to one tier)
sort "created" | "updated" | "username" | "email" (default "created")
order "asc" | "desc" (default "desc")
200 OK
{
"users": [ user profile ],
"pagination": { page, limit, total, totalPages }
}GET /admin/users/:id
Single user info, plus map count and storage usage.
200 OK
{
"user": { ... },
"stats": { "maps": number, "storage": number }
}
Errors
404 USER_NOT_FOUNDPATCH /admin/users/:id/tier
Adjust a user's tier, optionally with a duration (in days).
Body
{
"tier": string,
"duration"?: number // days, max 36500
}
200 OK
{ "user": { ... } }
Audit
Logs action "update_tier" with { fromTier, toTier, durationDays }.
Errors
400 VALIDATION_ERROR
404 USER_NOT_FOUNDPATCH /admin/users/:id/admin
Toggle a user's admin flag. You can't demote yourself.
Body
{ "isAdmin": boolean }
200 OK
{ "user": { ... } }
Audit
Logs action "update_admin" with { isAdmin }.
Errors
400 SELF_DEMOTE
400 VALIDATION_ERROR
404 USER_NOT_FOUNDGET /admin/users/:id/maps
Read-only list of a user's maps (metadata only). The call itself is logged.
200 OK
{ "maps": [ { id, name, format, sizeBytes, createdAt, updatedAt } ] }
Audit
Logs action "list_maps" with { count }.
Errors
404 USER_NOT_FOUNDGET /admin/users/:id/maps/:mapId
Read-only single map (content included). Every open is logged.
200 OK
{ "map": { id, name, format, content, sizeBytes, createdAt, updatedAt } }
Audit
Logs action "view_map" with { resourceId, name, sizeBytes }.
Errors
404 MAP_NOT_FOUNDGET /admin/audit
Recent audit entries across all users.
Query
limit number (default 50, max 200)
targetUserId string (filter to one user)
200 OK
{
"entries": [
{ id, adminId, adminUsername, targetUserId, targetUsername, action, resourceId, note, metadata, createdAt },
...
]
}DELETE /admin/users/:id
Delete an account. Cascades to the user's maps. You can't delete your own.
200 OK
{ "deleted": true }
Audit
Logs action "delete_user" before the row is removed.
Errors
400 SELF_DELETE
404 USER_NOT_FOUND