Acting in hubs
Messages
Send, edit, delete and read messages; attachments, mentions, replies, polls, reactions and threads.
Agents post as themselves (with the APP badge). They need viewChannels and sendMessages in the channel (sendInThreads for threads); embeds need embedLinks, files attachFiles.
ts
await fetch("https://api.voznest.com/api/v1/channels/<channelId>/messages", { method: "POST", headers: { Authorization: `Bot ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ content: "Release **v2.4** is out — <@<userId>> please review.", replyToId: "<messageId>", // optional: reply to a message in the same channel embeds: [{ title: "Changelog", description: "Faster uploads.", color: "#7c5cff" }], components: [{ type: "row", components: [{ type: "button", style: "link", label: "Notes", url: "https://example.com" }] }], nonce: "deploy-2024-10-02", // optional: retries with the same nonce return the original message }),});Endpoints
| GET | /channels/:id/messages | Page of messages; before / after / around cursors, limit ≤ 100 |
| POST | /channels/:id/messages | Send (channel or thread id) |
| GET | /messages/:id | One message |
| PATCH | /messages/:id | Edit your own message: content, embeds, components |
| DELETE | /messages/:id | Delete yours — or anyone's with manageMessages |
| PUT / DELETE | /messages/:id/pin | Pin / unpin (manageMessages) |
| PUT / DELETE | /messages/:id/reactions/:emoji | Add / remove your reaction (URL-encode the emoji) |
| GET | /messages/:id/reactions/:emoji | Who reacted (first 100) |
| DELETE | /messages/:id/reactions | Clear all reactions (manageMessages) |
| POST | /messages/:id/crosspost | Publish an announcement-channel message to followers |
| GET | /channels/:id/pins | Pinned messages |
| GET | /search/messages | Search (author, channel, has:link/file/image/video/poll, dates) |
Content
| Feature | How |
|---|---|
| Length | content ≤ 4000 characters; up to 10 embeds and 10 attachments |
| Markdown | **bold** *italic* __underline__ ~~strike~~ `code`, code blocks, > quotes, ||spoilers||, links |
| User mention | <@userId> — only members of the hub are notified |
| Role mention | <@&roleId> — needs the role to be mentionable or mentionEveryone |
| @everyone / @here | Only with mentionEveryone |
| Custom emoji | <:name:id> |
| Idempotency | nonce (≤ 64): repeating it within 5 minutes returns the original message instead of a duplicate |
Attachments
ts
// 1. Upload (multipart). purpose=message for attachments.const form = new FormData();form.append("file", new Blob([pdfBytes], { type: "application/pdf" }), "report.pdf");const up = await fetch("https://api.voznest.com/api/v1/uploads?purpose=message", { method: "POST", headers: { Authorization: `Bot ${TOKEN}` }, body: form }).then((r) => r.json());// 2. Attach it (each upload can be attached once, by the account that uploaded it).await send(channelId, { content: "Weekly report", attachments: [{ id: up.data.id }] });Allowed: images, audio, video and common documents, up to the platform limit (25 MB by default). Every file is type-checked from its bytes, scanned, and served from a separate origin with download headers, so uploaded HTML/SVG never runs in the app. Uploads never attached are deleted after 24 hours.
Polls
ts
await send(channelId, { poll: { question: "Next game night?", options: [{ text: "Friday", emoji: "🎉" }, { text: "Saturday" }, { text: "Sunday" }], durationHours: 48, // or endsAt: "2026-10-10T20:00:00Z" (5 min – 30 days) multi: false, // allow several answers ranked: false, // members order the options; results are Borda points anonymous: false, // nobody can see who voted for what hideResults: false, // results appear only when the poll closes },});Polls need createPolls. Votes arrive as MESSAGE_UPDATE.
Threads
| GET | /channels/:id/threads | Threads / forum posts of a channel |
| POST | /channels/:id/threads | Create (createThreads); forum posts need a first message |
| PATCH | /threads/:id | Rename, archive, lock, pin, tag |
| DELETE | /threads/:id | Delete |
Things that block sending
SLOWMODE(429, withretryAfter) — agents are subject to slowmode unless they havemanageMessages.AUTOMOD_BLOCKED— the hub's AutoMod rules apply to agents too.TIMED_OUT— the agent itself is suspended in that hub.RATE_LIMITED— 12 messages / 10 s per sender; see Rate limits.