The user domain
api.users handles everything user-related — accounts, profiles, authentication, and online status.
Function reference
| Function | Returns | Description |
|---|---|---|
api.users.get(id) |
table or nil | Get a single user by ID |
api.users.list(filter?) |
{ items, total } |
Search, filter, and paginate users |
api.users.create(data) |
table | Register a new user |
api.users.update(id, data) |
table | Update user fields |
api.users.login(user, pass) |
table or nil | Authenticate — supports username or email |
api.users.online(filter?) |
{ items, total } |
Currently online visitors |
api.users.me() |
table or nil | Currently logged-in user (from session) |
api.users.delete(id) |
nil | Soft-delete (sets type=4) |
api.users.stats() |
number | Total user count |
List filter
api.users.list({
type = "active", -- "all", "active", "inactive", "blocked", "deleted"
level = 5, -- permission level filter
search = "john", -- search by name or email
page = 1,
limit = 50 -- default 50
})
User registration flow
app:post("/register", function(ctx)
local v = validator(req.post, {
username = "required|string|min:3|max:30",
email = "required|email",
password = "required|string|min:8"
})
if v:fails() then
ctx:flash("error", v:first())
return ctx:redirect("/register")
end
-- Check for duplicate username
local existing = api.users.list({ search = v:valid().username })
if existing.total > 0 then
ctx:flash("error", "Username already taken")
return ctx:redirect("/register")
end
local user = api.users.create(v:valid())
ctx:flash("success", "Welcome, " .. user.username .. "!")
return ctx:redirect("/login")
end)
Login flow
app:post("/login", function(ctx)
local username = req.post.username
local password = req.post.password
local user = api.users.login(username, password)
if not user then
ctx:flash("error", "Invalid credentials")
return ctx:redirect("/login")
end
ctx:flash("success", "Welcome back, " .. user.username .. "!")
return ctx:redirect("/dashboard")
end)
Profile page
app:get("/profile/:username", function(ctx)
local result = api.users.list({ search = ctx.params.username })
if result.total == 0 then
return ctx:error("User not found", 404)
end
local profile = result.items[1]
local is_owner = false
if env.is_user then
local me = api.users.me()
is_owner = me and me.id == profile.id
end
return ctx:render("profile", {
profile = profile,
is_owner = is_owner
})
end)
Online users badge
-- Show "12 users online" in your footer
app:get("/", function(ctx)
local online = api.users.online()
local stats = api.users.stats()
return ctx:render("home", {
online_count = online.total,
total_users = stats
})
end)
Warning:
api.users.delete(id)soft-deletes — it setstype=4. The content stays, the user can't log in. There is no hard-delete from Lua.
Next: api.sites — site information.