Skip to content

Guilds

A guild (shown as a "server" in the TEBHOS apps) is a community with its own channels, roles, members, expressions and settings. This page covers the guild object and the guild-level operations. Related resources live on their own pages:

All routes are relative to https://tebhos.com/api/v1 and require authentication. Routes marked user-only accept only a user session; a valid Bot <token> credential is refused with 403 ACCESS_DENIED. Every other route on this page also accepts a bot token. List current user guilds and Get guild also accept an OAuth2 access token with the guilds scope; every other route answers a valid access token with 403 ACCESS_DENIED. Error bodies follow Errors.

A caller who is not a member of the guild receives 403 FORBIDDEN. Because membership is checked first, a guild ID that does not exist also returns 403 on the member-scoped routes.

Two route families

TEBHOS serves the guild API under /guilds/{guild_id}/.... The web app also uses a few older /servers/{guild_id}/... routes that return TEBHOS-specific shapes. This documentation describes the /guilds routes and mentions a /servers route only where it is the sole way to reach a feature.

Guild object

The guild object is returned by Get guild, Modify guild, Create guild and List current user guilds, and it is the payload of the Gateway Guild Update event. The Ready payload carries the same fields for every guild.

Structure

Field Type Description
id snowflake The ID of the guild
name string The name of the guild (1-100 characters)
icon ?string The icon hash. An animated icon hash starts with a_
banner ?string The banner hash, or a CSS gradient string when the guild uses a banner colour preset (see below)
banner_width ?integer Banner width in pixels
banner_height ?integer Banner height in pixels
splash ?string The invite background hash
splash_width ?integer Invite background width in pixels
splash_height ?integer Invite background height in pixels
embed_splash ?string The resolved invite card image URL: the embed background if one is set, otherwise the banner URL
embed_splash_width ?integer Embed background width in pixels
embed_splash_height ?integer Embed background height in pixels
splash_card_alignment integer Splash card alignment
vanity_url_code ?string The custom invite code, or null
owner_id snowflake The ID of the guild owner
system_channel_id ?snowflake The text channel that receives member join messages
system_channel_flags integer System channel flags
rules_channel_id ?snowflake The rules channel. No HTTP route sets it
afk_channel_id ?snowflake The AFK voice channel
afk_timeout integer The AFK timeout in seconds (0 when never set)
features array[string] The effective guild features, sorted alphabetically
verification_level integer Verification level
mfa_level integer MFA level
explicit_content_filter integer Stored for compatibility (0-2). TEBHOS applies no content filter based on it
default_message_notifications integer Default message notification level
disabled_operations integer Reserved bit field, 0 unless set by an instance administrator
message_history_cutoff ?ISO8601 timestamp Earliest message a member without READ_MESSAGE_HISTORY can read; null means such a member reads no history
nsfw boolean Always false; TEBHOS has no age-restricted guilds
nsfw_level integer Always 0
content_warning_level integer Always 0
content_warning_text null Always null
member_count ?integer The number of members. See the note below
image_url ?string TEBHOS addition: the resolved icon URL
banner_url ?string TEBHOS addition: the resolved banner URL, or the gradient string
splash_url ?string TEBHOS addition: the resolved invite background URL
embed_splash_url ?string TEBHOS addition: the resolved embed background URL
tebhos TEBHOS guild extras object TEBHOS addition: settings that have no standard field
permissions? string The caller's guild-level permission mask as a decimal string. Only List current user guilds sets it
roles? array[guild role object] Only Get guild sets it
emojis? array[object] Only Get guild sets it. Each item has id, name, animated and nsfw (always false)
stickers? array[object] Only Get guild sets it. Each item has id, name, description, tags, animated and nsfw (always false)
channels? array[channel object] Only Get guild sets it

member_count is a live count on Get guild (null if the count could not be read). On Modify guild and in Gateway events it may be up to 30 seconds old. List current user guilds omits it and returns approximate_member_count instead when asked.

Banner colour presets

Besides an uploaded image, a guild banner can be a CSS gradient chosen from the app's colour presets. In that case banner and banner_url hold the gradient string itself (starting with linear-gradient(, radial-gradient( or conic-gradient(), and banner_width and banner_height are null.

Image hashes resolve to URLs of the form https://tebhos.com/api/v1/server-icons/{guild_id}/{hash}.webp (and server-banners, server-invite-bg, server-embed-bg for the other images). The resolved *_url fields already contain the full URL. See Media proxy routes.

TEBHOS guild extras object

Field Type Description
boost_count integer Boosts on the guild, active and pending
boost_goal integer The boost goal shown on the guild's boost bar (default 25)
boost_bar_enabled boolean Whether the boost progress bar is shown in the channel list (default true)
banner_separated boolean Whether the banner is shown separately from the invite background (same as the DETACHED_BANNER feature)
description ?string The guild description
region ?string The guild's region label
max_members integer Member cap set by an administrator, 0 when unset
is_public boolean Whether the guild is listed in discovery (same as the DISCOVERABLE feature)
invites_disabled boolean Whether invites are paused (same as the INVITES_DISABLED feature)

In the Ready payload this object is found at properties.tebhos; everywhere else it is the top-level tebhos field.

Example

{
  "id": "1489002177550843904",
  "name": "Ada's Workshop",
  "icon": "a_9f2c1d4e7b",
  "banner": null,
  "banner_width": null,
  "banner_height": null,
  "splash": null,
  "splash_width": null,
  "splash_height": null,
  "embed_splash": null,
  "embed_splash_width": null,
  "embed_splash_height": null,
  "splash_card_alignment": 0,
  "vanity_url_code": "workshop",
  "owner_id": "1489002177550843905",
  "system_channel_id": "1489002177550843907",
  "system_channel_flags": 0,
  "rules_channel_id": null,
  "afk_channel_id": null,
  "afk_timeout": 300,
  "features": ["ANIMATED_BANNER", "ANIMATED_ICON", "BANNER", "INVITE_SPLASH", "VANITY_URL"],
  "verification_level": 1,
  "mfa_level": 0,
  "explicit_content_filter": 0,
  "default_message_notifications": 1,
  "disabled_operations": 0,
  "message_history_cutoff": null,
  "nsfw": false,
  "nsfw_level": 0,
  "content_warning_level": 0,
  "content_warning_text": null,
  "member_count": 128,
  "image_url": "https://tebhos.com/api/v1/server-icons/1489002177550843904/a_9f2c1d4e7b.webp",
  "banner_url": null,
  "splash_url": null,
  "embed_splash_url": null,
  "tebhos": {
    "boost_count": 27,
    "boost_goal": 25,
    "boost_bar_enabled": true,
    "banner_separated": false,
    "description": "A place to build things",
    "region": "europe",
    "max_members": 0,
    "is_public": false,
    "invites_disabled": false
  }
}

Guild features

features is the effective feature set. TEBHOS builds it from three sources.

Derived from the guild's boost level. These are never stored; they appear while the guild's boost level is high enough. A guild with an active Business Class subscription counts as level 2.

Feature Level Unlocks
INVITE_SPLASH 1 An invite background (splash)
BANNER 2 A guild banner
VANITY_URL 2 A custom invite code
ANIMATED_ICON 2 An animated icon
ANIMATED_BANNER 2 An animated banner

Toggleable by the guild. A member with MANAGE_GUILD adds or removes these through Modify guild or the feature toggle routes.

Feature Effect
INVITES_DISABLED Invites are paused: accepting an invite or joining from discovery is refused
TEXT_CHANNEL_FLEXIBLE_NAMES Stored for clients; the API does not rewrite channel names either way
DETACHED_BANNER The banner is shown separately from the invite background
CLONE_EMOJI_DISABLED Other guilds cannot clone this guild's emojis
CLONE_STICKER_DISABLED Other guilds cannot clone this guild's stickers
HIDE_OWNER_CROWN Clients hide the owner crown in the member list

Set by the instance. DISCOVERABLE appears while the guild's discovery application is approved. Instance administrators can also set other features. The Gateway acts on UNAVAILABLE_FOR_EVERYONE, UNAVAILABLE_FOR_EVERYONE_BUT_STAFF and UNAVAILABLE_HIDDEN (the guild is reported as unavailable), LARGE_GUILD_OVERRIDE (large-guild handling for notifications) and VOICE_E2EE.

Cloning is allowed by default

TEBHOS uses the opt-out features CLONE_EMOJI_DISABLED and CLONE_STICKER_DISABLED. A guild that holds neither allows its expressions to be cloned.

Verification levels

Value Name
0 NONE
1 LOW
2 MEDIUM
3 HIGH

TEBHOS has no phone verification, so the phone-based level 4 does not exist. For older clients a request with 4 is accepted and stored as 3 (HIGH), and a guild that still holds 4 is always returned as 3.

TEBHOS stores the level and returns it, and the apps show it in guild settings, but the API does not currently gate messages or joins on it. A guild listed in discovery cannot lower the level below LOW; such a request fails with 400 INVALID_FORM_BODY.

MFA levels

TEBHOS has no guild-level multi-factor requirement. mfa_level stays on the guild object for compatibility and is always 0 (NONE); it never removes permissions from anyone. Account-level multi-factor authentication is unaffected.

Default message notification levels

Value Name Description
0 ALL_MESSAGES Members are notified for every message by default
1 ONLY_MENTIONS Members are notified only for mentions by default

System channel flags

Value Name Description
1 << 0 SUPPRESS_JOIN_NOTIFICATIONS Do not post a join message in the system channel when a member joins

When the flag is not set and system_channel_id is set, TEBHOS posts a join message (message type 7) in the system channel for each member who joins through an invite.

Splash card alignments

Value Name
0 CENTER
1 LEFT
2 RIGHT

Create guild

POST /guilds

Creates a guild owned by the caller and returns its guild object with status 200. The owner's other sessions receive the new guild over the Gateway.

A bot credential is authenticated but refused with 400 BOTS_CANNOT_CREATE_GUILDS.

Rate limit: guild:create, 10 per 60 seconds per account.

JSON body

Field Type Description
name string The guild name, 1-100 characters after trimming
icon? ?string The icon as base64 or a data: URL. PNG, JPEG, GIF or WebP, at most 10 MiB decoded
empty_features? boolean Accepted and ignored
template? null Creating a guild from a template is not supported; any non-null value returns 400 BAD_REQUEST

An animated icon needs boost level 2, which a new guild never has, so an animated icon returns 403 FORBIDDEN. Upload it later through Modify guild.

A new guild gets a category named Genel holding a text channel genel and a voice channel Genel, and an @everyone role with the default permission set. The voice channel's bitrate is 64000 (64 kbps). No system channel is set.

Status Code Condition
400 INVALID_FORM_BODY name is empty or longer than 100 characters
400 BAD_REQUEST The icon cannot be decoded, is too large or is not an accepted format, a template was supplied, or the caller is already a member of 100 guilds (the message is MAX_GUILDS)
400 BOTS_CANNOT_CREATE_GUILDS The caller is a bot
403 FORBIDDEN The icon is animated
curl -X POST https://tebhos.com/api/v1/guilds \
  -H "Authorization: Bearer $TEBHOS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Ada'\''s Workshop"}'

List current user guilds

GET /users/@me/guilds

Returns an array of guild objects, one per guild the caller is a member of, ordered by ascending guild ID. Each object includes permissions, the caller's guild-level mask. roles, emojis, stickers and channels are not included.

Also accepts an OAuth2 access token with the guilds scope; a token without it receives 403 MISSING_OAUTH_SCOPE.

Rate limit: guild:list, 40 per 10 seconds per account.

Query parameters

Field Type Description
before? snowflake Return guilds with an ID lower than this guild ID
after? snowflake Return guilds with an ID higher than this guild ID. Takes precedence over before
limit? integer Maximum number of guilds to return (1-200, default 200)
with_counts? boolean When true (or 1), include approximate_member_count. Default false

A cursor that names a guild the caller is not in is ignored. A guild whose data cannot be read is skipped rather than failing the request, and permissions is omitted for a guild whose permissions cannot be computed. limit outside 1-200 returns 400 INVALID_FORM_BODY.

curl "https://tebhos.com/api/v1/users/@me/guilds?with_counts=true" \
  -H "Authorization: Bot $TEBHOS_BOT_TOKEN"

Get guild

GET /guilds/{guild_id}

Returns the guild object with roles (sorted by descending position), emojis, stickers, channels and a live member_count. Requires membership.

Also accepts an OAuth2 access token with the guilds scope; a token without it receives 403 MISSING_OAUTH_SCOPE.

Rate limit: guild:read, 100 per 10 seconds per account and guild.

channels is not filtered by visibility

The channels array on this route contains every channel in the guild. Use List guild channels to get only the channels the caller can view.

Modify guild

PATCH /guilds/{guild_id}

Updates guild settings and returns the updated guild object. Requires MANAGE_GUILD. Every successful request dispatches Guild Update to the guild and records a GUILD_UPDATE audit log entry.

Rate limit: guild:update, 20 per 10 seconds per account and guild.

JSON body

Every field is optional. An omitted field keeps its value. For the fields typed ?, an explicit null clears the value.

Field Type Description
name? string The guild name, 1-100 characters after trimming
icon? ?string New icon as base64 or a data: URL, or null to remove it
banner? ?string New banner image as base64 or a data: URL, a CSS gradient string, or null to remove it
splash? ?string New invite background (static image only), or null to remove it
embed_splash? ?string New embed background (static image only), or null to remove it
splash_card_alignment? integer Splash card alignment, 0-2
system_channel_id? ?snowflake The system channel, or null to clear it
system_channel_flags? integer System channel flags, not negative
afk_channel_id? ?snowflake The AFK voice channel, or null to clear it
afk_timeout? integer AFK timeout in seconds, 60-3600
default_message_notifications? integer Default message notification level, 0-1
verification_level? integer Verification level, 0-3 (4 is accepted and stored as 3)
mfa_level? integer Accepted for compatibility and ignored; see MFA levels
explicit_content_filter? integer 0-2. Stored for compatibility only
features? array[string] The complete desired feature set, at most 100 entries
message_history_cutoff? ?ISO8601 timestamp See message_history_cutoff on the guild object

nsfw, nsfw_level, content_warning_level and content_warning_text are accepted for compatibility and ignored. Sudo fields (password, mfa_code and so on) are also accepted and ignored.

Images accept PNG, JPEG, GIF and WebP up to 10 MiB decoded, sent as raw base64 or as a data: URL. The asset rules follow the guild's boost level:

Field Requirement
icon Any level; an animated icon needs level 2
banner An image needs level 2 (an animated one too); a gradient string needs no level
splash Level 1; animated images are refused with 400
embed_splash Any level; animated images are refused with 400

A missing level returns 403 FORBIDDEN. Replacing the icon schedules the old icon file for deletion.

features is the full set you want the guild to have, not a difference. Send back the array from the guild object with your changes applied:

  • A toggleable feature that is in the array and not in the guild is added; one that is in the guild but not in the array is removed.
  • A feature the guild already has in its effective set (including derived features such as BANNER) is accepted and left alone.
  • Adding any other feature returns 400 BAD_REQUEST.

system_channel_id and afk_channel_id are stored as given; the route does not check that the channel exists or has the right type.

In a guild listed in discovery, verification_level 0 returns 400 INVALID_FORM_BODY.

Status Code Condition
400 INVALID_FORM_BODY A value is out of range, message_history_cutoff is not an RFC 3339 timestamp, or the verification level is too low for a discoverable guild
400 BAD_REQUEST An ID is not a snowflake, an image is invalid or animated where that is not allowed, or a non-toggleable feature was added
403 FORBIDDEN MANAGE_GUILD is missing or a boost level requirement is not met
curl -X PATCH https://tebhos.com/api/v1/guilds/1489002177550843904 \
  -H "Authorization: Bot $TEBHOS_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Ada'\''s Lab", "afk_timeout": 600, "system_channel_flags": 1}'

TEBHOS-only settings

description, region, boost_goal and boost_bar_enabled (the TEBHOS guild extras) have no field on this route. They are set with PATCH /servers/{guild_id}, which requires MANAGE_GUILD, shares the guild:update bucket, and returns {"message": "..."}:

Field Type Description
description? string Up to 1000 characters
region? string Up to 50 characters
boost_goal? integer 1-100000
boost_bar_enabled? boolean Whether the boost bar is shown

The change is dispatched as Guild Update.

Toggle guild feature

Each of these routes adds or removes one toggleable feature and returns the updated guild object. They require MANAGE_GUILD and are user-only. Each dispatches Guild Update.

Route Body Feature
PATCH /guilds/{guild_id}/text-channel-flexible-names {"enabled": boolean} TEXT_CHANNEL_FLEXIBLE_NAMES
PATCH /guilds/{guild_id}/detached-banner {"enabled": boolean} DETACHED_BANNER
PATCH /guilds/{guild_id}/hide-owner-crown {"enabled": boolean} HIDE_OWNER_CROWN
PATCH /guilds/{guild_id}/invites-disabled {"disabled": boolean} INVITES_DISABLED
PATCH /guilds/{guild_id}/clone-emoji-disabled {"disabled": boolean} CLONE_EMOJI_DISABLED
PATCH /guilds/{guild_id}/clone-sticker-disabled {"disabled": boolean} CLONE_STICKER_DISABLED

A missing or non-boolean body field returns 400 BAD_REQUEST.

Delete guild

POST /guilds/{guild_id}/delete

Permanently deletes the guild and returns 204. User-only. Only the guild owner can delete a guild; anyone else receives 403 FORBIDDEN.

Rate limit: guild:delete, 10 per 60 seconds per account and guild.

The request body is ignored; you can send {}. No password or sudo proof is required.

Deletion cannot be undone

Deleting a guild removes its channels, messages, roles, memberships, invites, discovery listing and member guild settings. An active Business Class subscription on the guild is cancelled without a refund. There is no way to restore a deleted guild.

Every member receives Guild Delete, members in the guild's voice channels are disconnected, and the guild is removed from search.

Leave guild

DELETE /users/@me/guilds/{guild_id}

Removes the caller from the guild and returns 204. The caller's other sessions receive Guild Delete and the remaining members receive Guild Member Remove. The guild is removed from the caller's guild folders.

Rate limit: guild:leave, 10 per 10 seconds per account and guild.

Query parameters

Field Type Description
delete_messages? boolean When true, delete every message the caller wrote in the guild before leaving (default false)

Message deletion is best-effort: if it fails, the caller still leaves the guild.

Status Code Condition
400 BAD_REQUEST The caller is the guild owner. Transfer ownership or delete the guild instead
404 NOT_FOUND The caller is not a member

Bulk delete current user's guild messages

POST /users/@me/guilds/{guild_id}/messages/bulk-delete-mine

Deletes every message the caller wrote in the guild's channels and returns 202 with no body. The caller stays a member. Requires membership and sudo mode; a bot token satisfies sudo mode for its own account. Each affected channel receives a Message Delete Bulk event.

Rate limit: guild:leave, 10 per 10 seconds per account and guild (shared with Leave guild).

A non-member receives 404 NOT_FOUND; a user session without a sudo grant receives 403 SUDO_MODE_REQUIRED.

Custom invite URL

A guild at boost level 2 can claim a custom invite code (its vanity code). https://tebhos.com/vanity/{code} and Get invite resolve it; see Custom invite URLs.

Custom invite URL object

Field Type Description
code ?string The current custom invite code, or null
uses integer How many times the code has been resolved

Get guild custom invite URL

GET /guilds/{guild_id}/vanity-url

Returns the custom invite URL object. Requires MANAGE_GUILD. User-only.

Rate limit: guild:vanity_url:get, 100 per 10 seconds per account and guild.

Modify guild custom invite URL

PATCH /guilds/{guild_id}/vanity-url

Sets or removes the custom invite code and returns {"code": "..."} with the code now held (null after removal). Requires MANAGE_GUILD. User-only. Dispatches Guild Update.

Rate limit: guild:vanity_url:patch, 10 per 60 seconds per client and guild.

Field Type Description
code? ?string The code to claim. Null, an empty string or an omitted field removes the current code

A code is trimmed and must be 2-32 characters of ASCII letters, digits, - and _. Codes are unique regardless of letter case, and a list of reserved words (such as admin, api, login, invite, settings) cannot be claimed. Removing the code resets uses to 0.

Status Code Condition
400 INVALID_FORM_BODY The code has the wrong length or characters, or is reserved
403 FORBIDDEN MANAGE_GUILD is missing, or the guild is below boost level 2 (setting only; removal works at any level)
409 CONFLICT Another guild holds the code
curl -X PATCH https://tebhos.com/api/v1/guilds/1489002177550843904/vanity-url \
  -H "Authorization: Bearer $TEBHOS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"code": "workshop"}'

Resolve custom invite code

GET /vanity/{code}/resolve

Resolves a custom invite code without authentication. Letter case is ignored. Each call increases the code's uses. Returns a camelCase object:

Field Type Description
serverId snowflake The guild ID
serverName string The guild name
serverImage string The guild icon URL, or an empty string
memberCount integer The stored member count
vanityUses integer The use count after this call
inviteCode string The guild's own invite code, which can be passed to Accept invite

An unknown code returns 404 NOT_FOUND.

Guild images

Modify guild accepts images inline as base64. The web app instead uploads them straight to storage in two steps, which avoids large JSON bodies. Both steps are user-only and require MANAGE_GUILD (the owner always passes).

  1. POST /servers/{guild_id}/{kind}/upload-url with {"filename": string, "content_type": string, "size": integer}. Returns upload_url (a presigned URL valid for 300 seconds), storage_key, url and expires_in. PNG, JPEG, GIF and WebP up to 8 MiB are accepted.
  2. Upload the bytes with PUT to upload_url, then POST /servers/{guild_id}/{kind}/confirm with {"storage_key": string}.

{kind} is icon, banner, invite-bg (the invite background, splash) or embed-bg (embed_splash). The banner needs boost level 2 and the invite background level 1, and an animated icon or banner needs level 2, as on Modify guild. Confirming dispatches Guild Update. The icon confirmation returns {"icon_hash": string, "image_url": string}.

Guild boosts

A guild's boost level (0, 1 or 2) comes from the number of active boosts and controls the derived guild features, voice bitrate ceilings, upload limits and animated emoji. Boosting, the boost list and pricing are documented under Guild boosts. tebhos.boost_count on the guild object holds the current number of boosts.

Roles

Role routes are documented on Roles and permissions:

Operation Route
List guild roles GET /guilds/{guild_id}/roles
Create guild role POST /guilds/{guild_id}/roles
Modify guild role positions PATCH /guilds/{guild_id}/roles
Modify guild role PATCH /guilds/{guild_id}/roles/{role_id}
Delete guild role DELETE /guilds/{guild_id}/roles/{role_id}
Modify role hoist positions PATCH /guilds/{guild_id}/roles/hoist-positions
Reset role hoist positions DELETE /guilds/{guild_id}/roles/hoist-positions

Adding and removing a single role on a member is covered in Guild members.