Beta documentation. This is an early preview — content is still in active development. Feedback helps shape the final release. Share your thoughts or join the discussion.

api.messages

`api.messages` handles private user-to-user communication. Send messages by user ID or username, read chat threads, track unread counts.

On this page

The messages domain

api.messages handles private user-to-user communication. Send messages by user ID or username, read chat threads, track unread counts.

Function reference

Function Returns Description
api.messages.get(id) table or nil Get a single message
api.messages.send(to, content) table Send a message (by user ID or username)
api.messages.chat(uid, page?, limit?) { items, total } Get conversation with a specific user
api.messages.conversations() table[] List all conversation partners
api.messages.unread() number Unread message count
api.messages.edit(id, content) table Edit a message
api.messages.delete(id) boolean Delete a message

Sending messages

-- By user ID
api.messages.send(42, "Hey, how are you?")

-- By username
api.messages.send("johndoe", "Hello from Lua!")

Reading a conversation

-- Get chat with user 42, page 1, 30 messages per page
local chat = api.messages.chat(42, 1, 30)

for _, msg in ipairs(chat.items) do
    print(msg.sender.username .. ": " .. msg.content)
end

Unread message badge

app:on("before", function(ctx)
    if env.is_user then
        ctx.unread = api.messages.unread()
    end
end)
{% if unread > 0 %}
    <span class="badge">{{ unread }}</span>
{% endif %}

Message inbox page

app:get("/messages", function(ctx)
    if not env.is_user then
        return ctx:redirect("/login")
    end

    local conversations = api.messages.conversations()
    local unread = api.messages.unread()

    return ctx:render("messages", {
        conversations = conversations,
        unread_count = unread
    })
end)

Chat with a specific user

app:get("/messages/:userid", function(ctx)
    if not env.is_user then
        return ctx:redirect("/login")
    end

    local uid = tonumber(ctx.params.userid)
    local chat = api.messages.chat(uid, 1, 50)

    return ctx:render("chat", {
        messages = chat.items,
        other_user = uid
    })
end)

app:post("/messages/:userid", function(ctx)
    if not env.is_user then
        return ctx:error("Login required", 401)
    end

    local uid = tonumber(ctx.params.userid)
    local content = req.post.message

    if not content or str.trim(content) == "" then
        ctx:flash("error", "Message cannot be empty")
        return ctx:redirect("/messages/" .. uid)
    end

    api.messages.send(uid, content)
    return ctx:redirect("/messages/" .. uid)
end, { csrf = true })

Sending via username

-- Let users address messages by typing a username
api.messages.send(req.post.recipient, req.post.content)
-- Works whether recipient is "42" or "johndoe"

Next: api.files & api.folders — manage uploads and organize in folders.

Previous api.posts Next api.files & api.folders