API reference
Messages
Read, send, edit and delete messages, with replies, mentions, files, reactions and pins.
All paths below start with https://bafflux.com/api and need Authorization: Bot <token>. Your bot needs View Channel to read a channel and Send Messages to post in it.
The message object
{
"id": "103745999999999999",
"channelId": "103700000000000001",
"author": { "id": "103600000000000000", "username": "andre", "displayName": "Andre", "avatarUrl": null },
"content": "Hey <@103712345678901248>, **nice** work",
"createdAt": "2026-10-14T03:12:45.120Z",
"editedAt": null,
"attachments": [],
"embeds": [],
"reactions": [{ "emoji": "🎉", "count": 2, "me": false }],
"mentions": ["103712345678901248"],
"mentionRoles": [],
"mentionEveryone": false,
"replyDeleted": false,
"pinned": false,
"crossposted": false
}| Field | Notes |
|---|---|
author.tag | "bot", "verified_bot", "official" or "system" when the author has one |
attachments | { id, filename, contentType, size, width, height, url }. Images are converted to WebP (GIFs stay GIFs) |
embeds | Rich embeds from bots and webhooks, then link previews. See Embeds |
reply | When it replies to another message: { id, author, content, hasAttachments } (first 200 characters) |
replyDeleted | It was a reply, but the original is gone |
interaction | A bot's answer to a slash command: { user, name } |
serverId | Only on MESSAGE_CREATE events, so you know which server it's from |
nonce | Echoed back if you sent one |
Text
Messages are 1-2000 characters (or empty, with files or embeds). They're shown with Markdown-like formatting:
| Write | Shows |
|---|---|
**bold**, *italic*, __underline__, ~~strike~~ | Formatting |
`code` and ```blocks``` | Code |
||spoiler|| | Hidden until clicked |
<https://example.com> | A link without a preview |
<@userId> | Mentions (pings) a person |
<@&roleId> | Mentions everyone with a role |
@everyone, @here | Pings everyone who can see the channel (needs Mention Everyone) |
<:name:id>, <a:name:id> | A custom emoji (still or animated) |
Put a backslash before a character to show it as-is: \*not italic\*.
Reading
GET /api/channels/{channelId}/messages?limit=50&before={messageId}Returns up to limit messages (1-100, default 50), oldest first. Without before you get the newest page; pass the oldest ID you have to go further back. IDs grow over time, so they also sort messages.
Pinned messages: GET /api/channels/{channelId}/pins (newest pin first).
Sending
POST /api/channels/{channelId}/messages
Content-Type: application/json
{ "content": "Hello!", "replyTo": "103745999999999999", "mentionReply": false }| Field | Notes |
|---|---|
content | The text (may be empty when you send files or embeds) |
embeds | Up to 10 embeds (bots only) |
replyTo | Message ID in the same channel to reply to |
mentionReply | Whether the reply pings its author. Defaults to true |
nonce | Up to 64 characters; returned in the response and the MESSAGE_CREATE event |
Answers 201 with the message.
Files
Send multipart/form-data with a payload_json part (the JSON above) and up to 10 files parts of up to 10 MB each. Needs Attach Files.
curl https://bafflux.com/api/channels/$CHANNEL_ID/messages \
-H "Authorization: Bot $BOT_TOKEN" \
-F 'payload_json={"content": "Weekly chart"}' \
-F 'files=@chart.png'Editing and deleting
PATCH /api/channels/{channelId}/messages/{messageId} { "content": "Fixed typo" }
DELETE /api/channels/{channelId}/messages/{messageId}Bots can edit only their own messages. An edit can also carry embeds (replaces them, [] removes them); leave content out to change only the embeds. Bots can delete their own, or anyone's with Manage Messages. Deleting a message deletes its files.
Reactions
PUT /api/channels/{channelId}/messages/{messageId}/reactions/{emoji}
DELETE /api/channels/{channelId}/messages/{messageId}/reactions/{emoji}
GET /api/channels/{channelId}/messages/{messageId}/reactions/{emoji}{emoji} is the URL-encoded emoji (%F0%9F%8E%89 for 🎉) or a custom one as name:id. GET lists who reacted (first 100). Adding a new emoji needs Add Reactions; joining one that's already there doesn't. Messages take up to 20 different reactions.
Pins and typing
PUT /api/channels/{channelId}/pins/{messageId}
DELETE /api/channels/{channelId}/pins/{messageId}
POST /api/channels/{channelId}/typingPinning needs Manage Messages (up to 50 pins per channel). The typing call shows "Bot is typing..." for about 9 seconds; repeat it every few seconds while you work.
Threads
POST /api/channels/{channelId}/threads
{ "name": "Patch notes discussion", "messageId": "103745999999999999", "autoArchiveMinutes": 1440 }Starts a thread in a text or announcement channel, optionally from one of its messages (one thread per message). autoArchiveMinutes is when it hides after the last message: 60, 1440, 4320 or 10080. A thread is a channel with kind: "thread"; send messages to it like any channel. GET /api/channels/{channelId}/threads lists a channel's threads, newest activity first.
Publishing announcements
In an announcement channel, POST /api/channels/{channelId}/messages/{messageId}/crosspost copies a message to every channel that follows it (once per message). Your own messages need Send Messages; anyone's need Manage Messages.