HTTP API Reference
All API endpoints require an authenticated session unless noted otherwise.
Authentication is performed by the /login route, which sets a signed
session cookie. Subsequent requests include this cookie automatically.
All JSON responses use Content-Type: application/json.
Authentication
- GET /login
Render the login page.
- Response Headers:
Content-Type – text/html
- POST /login
Authenticate a user and establish a session.
- Form Parameters:
username – Account username.
password – Account password.
- Status Codes:
- Response Headers:
Set-Cookie –
session=<signed_value>on success.
Note
Failed login attempts are deliberately delayed by 3 seconds to slow brute-force attacks. Repeated failures additionally trigger account lockout: after
max_login_attemptsconsecutive failures an account is locked forlockout_duration_minutes(both configurable insettings.json).
- GET /logout
Log out the current user, set presence to offline, and clear the session.
Requires authentication.
- Status Codes:
302 Found – Redirect to
/login.
- GET /signup
Render the registration page.
- Response Headers:
Content-Type – text/html
- POST /signup
Register a new account.
- Form Parameters:
username – 1–32 characters; letters, numbers, hyphens, underscores. The reserved names
minimost,everyone, anddeleteduserare rejected (case-insensitively).password – Minimum 8 characters; must include uppercase, digit, and special character.
confirm_password – Must match
password.
- Status Codes:
Chat Interface
- GET /
Serve the main chat SPA.
Requires authentication.
- Response Headers:
Content-Type – text/html
Channels
- GET /channels
Return the list of public channel names.
Requires authentication.
- Response JSON Object:
channels (array) – Ordered list of channel name strings.
Example response:
["general", "software", "firmware", "off-topic"]
- GET /channel_unreads
Return unread message counts for every public channel.
Requires authentication.
- Response JSON Object:
object – Mapping of channel name to unread count.
Example response:
{"general": 3, "software": 0, "off-topic": 1}
Messages
- GET /messages/(channel)
Fetch messages for a channel since a given timestamp.
Requires authentication.
- Parameters:
channel – Public channel name or DM identifier (e.g.
dm:alice:bob).
- Query Parameters:
after (float) – Only return messages modified after this Unix timestamp. Defaults to
0(return all messages). PassNaNto also trigger a full load.
- Response JSON Object:
array – Array of message objects.
Message object fields:
Field
Type
Description
idinteger
Database primary key (in the current user’s database).
channelstring
Channel or DM identifier.
senderstring
Username of the author.
contentstring or null
Message text body.
nullfor image-only messages.filenamestring or null
UUID-named image filename, served from
/files/<filename>.tsfloat
Unix timestamp (seconds).
editedinteger (0/1)
Whether the message has been edited.
edited_tsfloat or null
Timestamp of the most recent edit.
deletedinteger (0/1)
Soft-delete flag.
deleted_tsfloat or null
Timestamp of deletion.
reply_to_idinteger or null
ID of the parent message (in the same user’s database).
reactionsstring (JSON) or null
JSON-encoded object mapping emoji names to lists of reactor usernames, e.g.
"{\"thumbs_up\": [\"alice\", \"bob\"]}"reactions_tsfloat or null
Timestamp of the most recent reaction change.
mentionsstring (JSON) or null
JSON-encoded array of the channel members
@-mentioned in the message, e.g."[\"alice\"]". The sentinel"@everyone"marks a channel-wide mention.nullwhen the message mentions no one. The client highlights the message and notifies the viewer when their username (or@everyone) appears here.
- POST /send/(channel)
Send a message and/or image attachment(s) to a channel.
Requires authentication.
Any
@usernametokens in text that resolve to real channel members are extracted (case-insensitively) and stored in the message’smentionscolumn;@everyoneis stored as the sentinel"@everyone". Tokens inside emails (foo@bar) and URLs are ignored.- Parameters:
channel – Target channel or DM identifier.
- Form Parameters:
text – Message text body (optional if files are provided).
reply_to_id – Integer ID of the parent message (optional).
files – One or more image files (multipart). Accepted extensions:
.jpg,.jpeg,.png,.gif,.webp.
- Status Codes:
200 OK – Returns the string
"ok".400 Bad Request – Empty message (no text and no valid files).
403 Forbidden – User is not permitted to post to the channel.
- GET /message/(msg_id)
Fetch a single message by ID.
Requires authentication.
- Parameters:
msg_id (int) – Message primary key in the current user’s database.
- Response JSON Object:
id (integer) – Message ID.
sender (string) – Author’s username.
content (string) – Message text.
filename (string) – Image filename or null.
deleted (integer) – Soft-delete flag.
- Status Codes:
404 Not Found – Message not found.
- POST /edit/(msg_id)
Edit the text content of a message.
Requires authentication. Only the original sender can edit.
- Parameters:
msg_id (int) – Message ID in the current user’s database.
- Form Parameters:
text – Replacement message text. Mentions are re-extracted from the new text and the
mentionscolumn is updated accordingly.
- Status Codes:
200 OK – Returns
"ok".403 Forbidden – Not the sender, or message not found.
- POST /delete/(msg_id)
Soft-delete a message.
Requires authentication. Only the original sender can delete.
- Parameters:
msg_id (int) – Message ID in the current user’s database.
- Status Codes:
200 OK – Returns
"ok".403 Forbidden – Not the sender, or message not found.
- GET /search_messages
Search message history by keyword.
Requires authentication.
- Query Parameters:
q (string) – Search term (substring match).
- Response JSON Object:
array – Up to 50 matching message objects (fields:
id,channel,sender,content,ts), newest first.
Reactions
- POST /react/(msg_id)
Toggle an emoji reaction on a message.
Requires authentication.
- Parameters:
msg_id (int) – Message ID in the current user’s database.
- Form Parameters:
reaction – Emoji name (e.g.
thumbsup,heart). Must be a valid reaction name from theVALID_REACTIONSset.
- Response JSON Object:
object – Current reactions map after the toggle, e.g.
{"thumbs_up": ["alice", "bob"]}
- Status Codes:
400 Bad Request – Invalid reaction name.
404 Not Found – Message not found.
Users and Presence
- GET /users
Return all registered users except the current user.
Requires authentication.
- Response JSON Object:
array – List of username strings.
- GET /channel_members/(channel)
Return the members of a channel that the current user may
@-mention, excluding the current user. For public channels this is every other registered user; for private channels the other members; for DMs the other participants. Used to populate the@-mention autocomplete dropdown.Requires authentication.
- Parameters:
channel – Channel name, DM identifier, or
private:<id>.
- Response JSON Object:
array – List of mentionable username strings.
- Status Codes:
403 Forbidden – User is not permitted to access the channel.
- GET /user_colors
Return the display name colour for every user that has set one.
Requires authentication.
- Response JSON Object:
object – Mapping of username to CSS hex colour string.
Example response:
{"alice": "#e06c75", "bob": "#61afef"}
- GET /user_avatars
Return the set of usernames that have a custom avatar.
Requires authentication.
- Response JSON Object:
array – List of username strings that have uploaded an avatar.
- GET /online_users
Return presence states for recently active users.
Requires authentication.
- Response JSON Object:
object – Mapping of username to presence state string (
"active","idle","hidden","offline").
Example response:
{"alice": "active", "bob": "idle", "charlie": "offline"}
- POST /presence
Update the current user’s presence state.
Requires authentication.
- Request JSON Object:
state (string) – One of
"active","idle","hidden","offline".
- Status Codes:
204 No Content – State updated.
- GET /typing/(channel)
Return users currently typing in a channel.
Requires authentication.
- Parameters:
channel – Channel or DM identifier.
- Response JSON Object:
array – List of username strings. Excludes the current user.
- POST /typing/(channel)
Report that the current user is typing.
Session is checked silently (not
@login_required).- Parameters:
channel – Channel or DM identifier.
- Status Codes:
204 No Content – Recorded.
Direct Messages
- GET /dms
Return a summary of all visible DM conversations.
Requires authentication.
Hidden conversations (closed by the user) are excluded unless a new message has arrived after the conversation was hidden.
- Response JSON Object:
array –
List of conversation objects, sorted by most recent activity. Each object has:
channel(string): DM channel identifier.users(array): Other participant usernames.unread(integer): Unread message count.
- POST /dms/close
Hide a DM conversation from the sidebar.
Requires authentication.
The conversation is not deleted. It reappears automatically when a new message is received after the hidden timestamp.
- Request JSON Object:
channel (string) – DM channel identifier to hide.
- Status Codes:
204 No Content – Conversation hidden.
400 Bad Request – Missing or invalid channel.
- GET /unread_count
Return the total number of unread DMs.
Requires authentication.
- Response JSON Object:
count (integer) – Total unread DM message count.
Read Receipts
- POST /mark_read/(channel)
Mark all messages in a channel as read.
Requires authentication.
- Parameters:
channel – Channel or DM identifier.
- Status Codes:
204 No Content – Messages marked as read.
- GET /read_receipts/(channel)
Return read receipts for all messages in a channel.
Requires authentication.
- Parameters:
channel – Channel or DM identifier.
- Response JSON Object:
object – Mapping of message timestamp strings to lists of reader usernames.
Example response:
{ "1716000000.123": ["alice", "bob"], "1716000001.456": ["alice"] }
User Settings
- GET /settings
Return the current user’s settings.
Requires authentication.
- Response JSON Object:
name_color (string) – CSS hex colour string, or
nullif not set.avatar_file (string) – Avatar filename, or
nullif not set.
- POST /settings
Update the current user’s settings.
Requires authentication.
- Form Parameters:
name_color – CSS hex colour in
#rrggbbformat (optional). Pass an empty string to clear the colour.
- Status Codes:
204 No Content – Settings saved.
400 Bad Request – Invalid colour format.
Avatars
- GET /avatar/(username)
Serve a user’s profile avatar image.
Requires authentication.
- Parameters:
username – Account username.
- Response Headers:
Content-Type –
image/jpeg
- Status Codes:
404 Not Found – User has no avatar.
- POST /avatar
Upload or replace the current user’s avatar.
Requires authentication.
The image should be pre-resized to 128 × 128 px by the client before upload (the frontend uses the Canvas API for this). The server stores the file as-is.
- Form Parameters:
avatar – Image file (
multipart/form-data). Accepted extensions:.jpg,.jpeg,.png,.gif,.webp.
- Status Codes:
204 No Content – Avatar saved.
400 Bad Request – No file provided or invalid file type.
- DELETE /avatar
Delete the current user’s avatar. The default initials avatar is shown to other users after removal.
Requires authentication.
- Status Codes:
204 No Content – Avatar removed.
Private Channels
- POST /private_channels/(channel_id)/leave
Leave a private channel.
Requires authentication.
A system message is posted to the channel notifying remaining members. If the leaving user is the last member, the channel is not automatically deleted — it becomes an empty room.
- Parameters:
channel_id – Private channel identifier (
private:<name>form).
- Status Codes:
204 No Content – User removed from channel.
403 Forbidden – User is not a member of the channel.
404 Not Found – Channel not found.
Files
- GET /files/(filename)
Serve an uploaded image file.
Requires authentication.
- Parameters:
filename – UUID-based image filename (as stored in the database).
- Response Headers:
Content-Type – Inferred from the file extension.
- Status Codes:
404 Not Found – File not found.
Link Previews
- GET /link_preview
Fetch a link preview card for a URL.
Requires authentication.
- Query Parameters:
url (string) – Fully-qualified URL to preview.
- Response JSON Object:
object – Preview data. Shape depends on the type:
Code preview (Bitbucket):
{ "type": "code", "filename": "chat.py", "filepath": "src/minimost/chat.py", "language": "py", "first_line_num": 1, "highlight_start": 50, "highlight_end": 60, "code": "...", "total_lines": 616, "url": "https://bitbucket.org/..." }
OpenGraph preview:
{ "type": "og", "title": "Page Title", "description": "Page description...", "image": "https://example.com/image.png", "domain": "example.com", "url": "https://example.com/page" }
No preview available:
{}