API reference
The public API: what apps and bots can call. Everything goes to https://the-hub.coffee/app/api.php?action=<name>.
Answers and errors
Answers are JSON: {"ok": true, …}, or {"ok": false, "error": "a readable reason"} with an HTTP status: 400 something in the request is wrong, 401 the token is missing, wrong or expired, 403 a missing permission (or an action this kind of token can't use), 404 not found, 429 too fast: wait a little and try again.
The OAuth token endpoint answers in OAuth's own format instead: {"error": "invalid_grant", "error_description": "…"}.
IDs: people have a public uid (26 characters, it never changes). Spaces, channels and messages have numbers.
OAuth (apps)
| Action | Method | Auth | What it does |
|---|---|---|---|
oauth_token | POST | client ID + secret, or PKCE | Trade a code (grant_type=authorization_code) or a refresh token (grant_type=refresh_token) for tokens. Form-encoded or JSON. |
oauth_me | GET | Bearer vlo_…, scope identify | The person: id, username, display_name, avatar, color, created_at. |
oauth_spaces | GET | Bearer vlo_…, scope spaces | Their spaces: id, name, icon, owner. |
The sign-in page is https://the-hub.coffee/app/oauth.html. See Apps for the whole flow.
Bots
With Authorization: Bot vlb_…. Anything not in this list answers "Bots can't use this part of the API".
| Action | Method | What to send |
|---|---|---|
me | GET | The bot's own profile, under user. |
bot_events | GET | after (a message id): new messages since then. See Bots. |
sync | GET | The bot's spaces, channels, members and roles. Add server_id for one space's details. |
messages | GET | channel_id, optional before (a message id): the 50 messages before it, newest last. |
message_send | POST | channel_id, content (up to 4000 characters, Markdown), optional reply_to and attachments (from upload). |
message_edit | POST | id, content. Its own messages only. |
message_delete | POST | id. Its own, or anyone's with Manage messages. |
react | POST | message_id, emoji (an emoji, or a custom one as <:name:id>). Adds it, or takes it away. |
typing | POST | channel_id. Shows "… is typing" for a few seconds. |
pins / message_pin | GET / POST | channel_id / id: list pins, or pin and unpin (Manage messages). |
upload | POST | A file as multipart form data. Send the file it returns in attachments. |
user_profile | GET | user_id or user_uid, optional server_id. |
dm_open | POST | user_id: the direct-message channel with that person (their message settings apply). |
stickers_list | GET | The stickers it can send. |
mod_command | POST | channel_id, text: a moderation command, like /timeout @user 10m spam. The answer is under result. |
mod_action | POST | server_id, op (ban, unban, kick, mute, unmute, timeout, untimeout, warn, clearwarnings, nick), user (@username or a user ID), optional reason, duration (milliseconds), nick. |
Moderation by a bot follows the same rules as by a person: it needs the permission, and can only act on members whose highest role is below its own. The commands are listed in Moderation.
Messages
A message has id, channel_id, author, content, attachments, reply, reactions, sticker, pinned, created_at, edited_at, and:
system: truefor replies to moderation commands. Their author is{"id": 0, "display_name": "[System] <space>"}.emojis: for custom emojis in its text or reactions,{"<id>": "<picture>"}. A custom emoji is written<:name:id>(<a:name:id>when animated).
Limits
- Bots: 5 messages every 5 seconds. People: 10 every 10 seconds.
- Channels can have slowmode; moderators and bots with Manage messages aren't slowed down.
- Uploads: up to 25 MB.