Zrzur Developers

Channels

Every server channel has channel_type: "TextChannel": text, voice (with voice), announcement, forum (with forum) and thread (with parent and thread). A bot also sees the direct messages it is part of (DirectMessage). Groups are for people only. The Event reference lists the fields and shows how to tell a direct message from a server channel.

The examples use plain HTTP. The SDK lines after them need the SDK, which is not published yet; see SDKs.

Create and change channels

POST /servers/{server}/channels creates a channel (needs Manage Channel). A staff-only ticket channel in a category:

curl -X POST "https://api.zrzur.com/servers/SERVER_ID/channels" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '{ "type": "Text", "name": "ticket-0001", "description": "Support ticket", "category": "CATEGORY_ID", "private": true }'
FieldMeaning
typeText (the default), Voice or Forum
name1 to 32 characters
descriptionUp to 1024 characters
nsfwOnly for adults
announcementText channels: only members with Manage Messages post
categoryId of a category of this server. The channel follows the category's permissions. A category the server does not have answers 404 NotFound, and nothing is made
privatetrue denies View Channel to @everyone in this channel, and it does not follow its category's permissions. Roles that have View Channel, in the server or in this channel, still see it

The answer is the new channel. Check that a role of your bot has View Channel, or your bot cannot use a private channel it made. To let the staff in, give their role View Channel on the channel with PUT /channels/{target}/permissions/{role_id}.

Announcement channels only accept messages from members with Manage Messages.

Threads

A thread is a channel inside a text channel and uses that channel's permissions. Start one with a name and a first message:

curl -X POST "https://api.zrzur.com/channels/CHANNEL_ID/threads" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '{ "name": "Release", "content": "First message" }'

The answer is the thread: a channel with parent set. So POST /channels/{target}/messages writes into it. GET /channels/{target}/threads lists them, and PATCH /channels/{target}/thread archives or locks one.

POST /channels/{target}/threads starts one from a message (message), with a first message (content), or empty (only name). A new message reopens an archived thread. Locking needs Manage Messages.

The first message follows the rules of every message your bot sends:

A card with buttons can be the first message of a thread:

curl -X POST "https://api.zrzur.com/channels/CHANNEL_ID/threads" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '{ "name": "ticket-0001", "embeds": [{ "title": "Ticket 0001", "description": "Opened by <@USER_ID>" }], "components": [{ "type": "ActionRow", "components": [{ "type": "Button", "style": "Danger", "label": "Close ticket", "custom_id": "ticket:close" }] }] }'
# answer: { "_id": "THREAD_ID", "channel_type": "TextChannel", "parent": "CHANNEL_ID", ... }

With the SDK:

const thread = await bot.threads.create(channelId, { name: "Release", content: "First message" });
await bot.messages.send(thread._id, "In the thread");
await bot.threads.list(channelId);
await bot.threads.archive(thread._id);

Three permissions decide who starts and writes. Each is read on the parent channel with its overrides, and Send Messages is needed as well: CreateThreads starts a thread in a text channel, CreateForumPosts starts a post in a forum, and SendMessageInThreads writes in threads and forum posts. Without one, the call answers MissingPermission. Using a bot command in a thread counts as writing there.

A server can switch threads or forums off: threads_disabled and forums_disabled in PATCH /servers/{target}. Then nobody can add anything, the owner included: messages, edits, reactions and pins answer ThreadsDisabled or ForumsDisabled. Everything stays readable, and people can still delete their messages and remove reactions.

Forums

A forum holds posts only. Each post is a thread with a title, a first message and up to five tags. Make a forum with "type": "Forum" in POST /servers/{server}/channels, and post into it:

curl -X POST "https://api.zrzur.com/channels/FORUM_ID/threads" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '{ "name": "How do I start?", "content": "Read the guide.", "tags": ["help"] }'

A post needs content, and its tags must be tags of that forum. With the SDK:

const forum = await bot.forums.create(serverId, { name: "questions" });
await bot.forums.setTags(forum._id, [{ id: "help", name: "Help" }], { required: true });
await bot.forums.post(forum._id, { title: "How do I start?", content: "Read the guide.", tags: ["help"] });

Invites

Bots create and manage invites like people do, with the same permissions: Invite Others to create one, Manage Server to list and remove them. They never join through one: that answers IsBot.

curl -X POST "https://api.zrzur.com/channels/CHANNEL_ID/invites" \
  -H "x-bot-token: YOUR_BOT_TOKEN" \
  -H "content-type: application/json" \
  -d '{ "max_uses": 3 }'

The answer has the invite code in _id. GET /servers/{target}/invites lists them and DELETE /invites/{target} removes one. With the SDK:

const invite = await bot.invites.create(channelId, { max_uses: 3 });
await bot.invites.list(serverId);
await bot.invites.delete(invite._id);

Typing

POST /channels/{target}/typing shows "is typing…" for a few seconds, limited to 5 per 10 seconds per channel. The SDK's bot.typing(channelId) uses the gateway when connected, and this route without one.

Webhooks

A webhook posts into one channel without a gateway connection. Create one with a bot token or in server settings (needs Manage Webhooks). The answer has token and url. They are shown once: the server keeps only a hash, so save them now. A lost token can only be replaced.

curl -X POST "https://api.zrzur.com/webhooks/$WEBHOOK_ID/$WEBHOOK_TOKEN?wait=true" \
  -H "content-type: application/json" \
  -d '{"content": "Build finished", "username": "CI"}'

Anyone with the address can post, so treat it like a password. Tokens start with zrzur_wh_, so secret scanners can find a leaked one. POST /webhooks/{webhook_id}/token makes a new token; the old one stops at once.

Sending

POST /webhooks/{webhook_id}/{token} answers 204. With ?wait=true it returns the message.

FieldMeaning
contentUp to 2000 characters. A message needs at least one of content, embeds, attachments, components
usernameName on this message, 1 to 80 characters. The webhook mark stays
avatar_urlAvatar on this message, a public web address. Clients load it through the media proxy, which checks it
embedsUp to 10, 6000 characters in total. type is ignored: embeds are always rich
allowed_mentionsWhich mentions may notify anyone. { "parse": [] } turns them all off
flags4 hides link previews, 4096 sends without a notification
thread_idQuery parameter: post into this thread of the webhook's channel
thread_nameForum: start a thread with this name. applied_tags sets its tags. A forum without either answers ForumThreadRequired

Embeds take title (256), description (4096), url, color (a number) or colour (CSS text), timestamp, author (name 256), footer (text 2048), up to 25 fields (name 256, value 1024), image.url, thumbnail.url.

To send files, use multipart/form-data with files[0], files[1], ... and the JSON body in payload_json. Each file passes the same checks as a member's upload. Up to 5 files of 20 MB; refer to one from an embed with attachment://name.png. A webhook without Upload Files gets 403, never a message without its files.

@everyone, @online and role mentions notify people only if the webhook has the matching permission and allowed_mentions allows them. New webhooks have neither permission, and the text is still posted. Edits never notify anyone.

Interactive components work only on webhooks a bot created, and clicks go to that bot. Other webhooks can post links, text and media.

Editing a webhook

PATCH /webhooks/{webhook_id} with Manage Webhooks changes the name, avatar, permissions and channel, and takes X-Audit-Log-Reason. With the token, PATCH /webhooks/{webhook_id}/{token} changes only the name and avatar; permissions or channel_id there answer 403. GET with the token leaves out who made it. Names have 1 to 80 characters and cannot contain hidden characters or pass for Zrzur, its staff or a verified bot.

Its own messages

GET, PATCH and DELETE /webhooks/{webhook_id}/{token}/messages/{message_id} work on messages this webhook sent, and no others.

In a thread a webhook needs SendMessageInThreads, and CreateForumPosts to start a forum post. What the roles of its creator deny is denied to it too. Where threads or forums are switched off it can't send or edit, but it can delete its own messages.

Limits

Each channel has up to 15 webhooks (TooManyChannelWebhooks) and each server up to 1000 (TooManyServerWebhooks).

One webhook sends 5 messages in 2 seconds, and all webhooks of a channel 30 a minute. Over that, the answer is 429 with { "type": "RateLimited", "retry_after": 1200, "global": false } (milliseconds) and the X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset-After and Retry-After headers. After 20 wrong tokens in a minute an address waits, even with a right token.

AutoMod reads webhook messages and their embeds, on edits too. Moderators can delete and report them like any message.

Other formats

Nothing from these two formats notifies anyone.

Reference

GET /channels/{channel_id}/webhooks

Gets all webhooks. Gets all webhooks inside the channel. Their tokens are not included.

Permissions: Channel:ManageWebhooks · Rate limit: channels, 15 / 10 s

POST /channels/{channel_id}/webhooks

Creates a webhook. Creates a webhook which 3rd party platforms can use to send messages

Permissions: Channel:ManageWebhooks · Rate limit: channels, 15 / 10 s

DELETE /channels/{group_id}/recipients/{member_id}

Remove Member from Group. Removes a user from the group.

Not available to bots.

Permissions: Channel:ManageChannel · Rate limit: channels, 15 / 10 s

PUT /channels/{group_id}/recipients/{member_id}

Add Member to Group. Adds another user to the group.

Not available to bots.

Permissions: Channel:InviteOthers · Rate limit: channels, 15 / 10 s

DELETE /channels/{target}

Close Channel. Deletes a server channel, leaves a group or closes a group.

Permissions: Channel:ViewChannel, Channel:ManageChannel · Rate limit: channels, 15 / 10 s

GET /channels/{target}

Fetch Channel. Fetch channel by its id.

Permissions: Channel:ViewChannel · Rate limit: channels, 15 / 10 s

PATCH /channels/{target}

Edit Channel. Edit a channel object by its id.

Permissions: Channel:ManageChannel · Rate limit: channels, 15 / 10 s

POST /channels/{target}/invites

Create Invite. Creates an invite to this channel. Channel must be a TextChannel.

Permissions: Channel:InviteOthers · Rate limit: channels, 15 / 10 s

GET /channels/{target}/members

Fetch Group Members. Retrieves all users who are part of this group. This may not return full user information if users are not friends but have mutual connections.

Permissions: Channel:ViewChannel · Rate limit: channels, 15 / 10 s

PATCH /channels/{target}/thread

Edit Thread. Rename, archive, reopen or tag a thread: its owner or anyone who can manage messages. Locking (only moderators write) needs Manage Messages.

Permissions: Channel:ViewChannel, Channel:ManageMessages · Rate limit: channels, 15 / 10 s

GET /channels/{target}/threads

Threads Of A Channel. Active threads (or archived ones with archived=true), newest first, 50 per page (limit up to 100); before is a thread id.

Permissions: Channel:ViewChannel · Rate limit: channels, 15 / 10 s

POST /channels/{target}/threads

Start Thread. Start a thread in a text channel, from a message or with a first message, or a post in a forum (a title, a first message and its tags). Needs Send Messages in the channel, and Create Threads (Create Forum Posts in a forum). Refused with ThreadsDisabled or ForumsDisabled when the server has them switched off.

Permissions: Channel:SendMessage, Channel:CreateForumPosts, Channel:CreateThreads, Channel:ReadMessageHistory · Rate limit: channels, 15 / 10 s

POST /channels/create

Create Group. Create a new group channel.

Not available to bots.

Rate limit: channels, 15 / 10 s

GET /servers/{target}/webhooks

Gets a server's webhooks. Webhooks of every channel of the server where you have Manage Webhooks, newest first. Their tokens are not included.

Permissions: Channel:ManageWebhooks · Rate limit: servers, 5 / 10 s

DELETE /webhooks/{webhook_id}

Deletes a webhook. Deletes a webhook

Permissions: Channel:ManageWebhooks · Rate limit: any_dlta, 20 / 10 s

GET /webhooks/{webhook_id}

Gets a webhook. Gets a webhook, for those who may manage it. Its token is never included.

Permissions: Channel:ManageWebhooks · Rate limit: any_dlta, 20 / 10 s

PATCH /webhooks/{webhook_id}

Edits a webhook. Edits a webhook: name, avatar, permissions, channel. Moving it needs Manage Webhooks in both channels, within the same server.

Permissions: Channel:ManageWebhooks · Rate limit: any_dlta, 20 / 10 s

DELETE /webhooks/{webhook_id}/{token}

Deletes a webhook. Deletes a webhook with a token

Rate limit: any_dlta, 20 / 10 s

GET /webhooks/{webhook_id}/{token}

Gets a webhook. Gets a webhook with its token. Who made it is not included.

Rate limit: any_dlta, 20 / 10 s

PATCH /webhooks/{webhook_id}/{token}

Edits a webhook. Edits a webhook's name and avatar with its token. Its permissions and channel can only be changed by a manager.

Rate limit: any_dlta, 20 / 10 s

POST /webhooks/{webhook_id}/{token}

Executes a webhook. Sends a message. Answers 204 unless wait=true, which returns the message. thread_id posts into a thread of the webhook's channel.

Rate limit: any_dlta, 20 / 10 s

DELETE /webhooks/{webhook_id}/{token}/{message_id}

Deletes a webhook message (short path). As /messages/{message_id}

Rate limit: any_dlta, 20 / 10 s

PATCH /webhooks/{webhook_id}/{token}/{message_id}

Edits a webhook message (short path). As /messages/{message_id}

Rate limit: any_dlta, 20 / 10 s

POST /webhooks/{webhook_id}/{token}/github

Executes a webhook specific to github. Takes a GitHub webhook delivery and posts what happened. Events and actions that show nothing answer 204 too, so GitHub keeps the hook healthy.

Rate limit: any_dlta, 20 / 10 s

DELETE /webhooks/{webhook_id}/{token}/messages/{message_id}

Deletes a webhook message. Deletes a message this webhook sent

Rate limit: any_dlta, 20 / 10 s

GET /webhooks/{webhook_id}/{token}/messages/{message_id}

Fetches a webhook message. Fetches a message this webhook sent

Rate limit: any_dlta, 20 / 10 s

PATCH /webhooks/{webhook_id}/{token}/messages/{message_id}

Edits a webhook message. Edits a message this webhook sent

Rate limit: any_dlta, 20 / 10 s

POST /webhooks/{webhook_id}/{token}/slack

Executes a webhook in Slack's format. Takes what a Slack incoming webhook takes (text, attachments, blocks, username, icon_url), as JSON or as payload=<json>. Returns the message unless wait=false, which answers 204.

Rate limit: any_dlta, 20 / 10 s

POST /webhooks/{webhook_id}/test

Sends a test message. Posts a short message through a webhook, for those who manage it: they have no token to do it with, since it is only shown when made.

Permissions: Channel:ManageWebhooks · Rate limit: any_dlta, 20 / 10 s

POST /webhooks/{webhook_id}/token

Regenerates a webhook's token. Makes a new token. The old one stops working at once. The answer is the only time the new token is shown.

Permissions: Channel:ManageWebhooks · Rate limit: any_dlta, 20 / 10 s