Skip to content

Guild emojis

A custom emoji is an image that one guild owns. Members use it in messages as <:name:id> (or <a:name:id> when animated) and in reactions. Get emoji metadata resolves an emoji without membership of its guild.

All routes are relative to https://tebhos.com/api/v1, require authentication and accept both user sessions and bot tokens. A caller who is not a member of the guild, or lacks the required permission, receives 403 FORBIDDEN. Error bodies follow Errors.

Emoji IDs

An emoji id is a snowflake string, unique across all guilds. This is the ID to use in message markup, reactions and every route on this page.

Legacy UUID identifiers

Until 21 September 2026 the API returned a UUID as the emoji id. Emojis still carry that kind of identifier as legacy_id (new emojis get one too), so older clients, stored links and message markup keep working. Every route that takes an emoji_id accepts either the snowflake or the legacy UUID. New code should use id only.

Guild emoji object

Field Type Description
id snowflake The ID of the emoji
legacy_id ?string The legacy UUID identifier (see Emoji IDs)
guild_id snowflake The ID of the guild that owns the emoji
name string The emoji name, 1-32 ASCII letters, digits and underscores
animated boolean Whether the image is animated (GIF, animated PNG or animated WebP)
available boolean Always true
nsfw boolean Always false
image_url string The URL of the stored image
created_at ISO8601 timestamp When the emoji was created
user? partial user object The account that uploaded the emoji. Only List guild emojis includes it
{
  "id": "1501314428688998182",
  "legacy_id": "b4497791-c19c-4b6b-9a2f-df4bc155a9f7",
  "guild_id": "1489002177550843904",
  "name": "party_parrot",
  "animated": true,
  "available": true,
  "nsfw": false,
  "image_url": "https://cdn.tebhos.com/emojis/1489002177550843904/0c8f5a52-7e0b-4f3e-9a41-2d6f3b7c9e10/9f2c1d4e7b.gif",
  "created_at": "2026-09-14T09:12:44+00:00"
}

The Gateway Guild Emojis Update event carries the guild's complete emoji list. Its items have id, legacy_id, guild_id, name, image_url, animated, nsfw, created_by, created_at, creator_name and creator_avatar.

Limits

Limit Value
Emojis per guild 50, or 100 when the uploading member has TEBHOS Pro
Image size 256 KiB (262144 bytes) decoded
Image formats PNG, JPEG, GIF and WebP, detected from the file content. SVG is not accepted
Name 1-32 characters: ASCII letters, digits and _. Unique within the guild

The per-guild limit is checked against the current emoji count each time an emoji is created, so it depends on whether the member creating the emoji has TEBHOS Pro.

Animated emojis need either TEBHOS Pro for the uploading member or a guild at boost level 1 or higher. Otherwise creating or cloning an animated emoji returns 403 FORBIDDEN.

Emoji create object

Field Type Description
name string The emoji name, trimmed
image string The image as raw base64 or a data: URL
{
  "name": "party_parrot",
  "image": "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAI="
}

List guild emojis

GET /guilds/{guild_id}/emojis

Returns every guild emoji object of the guild, each with user. Requires membership; no permission is checked. There is no pagination.

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

curl https://tebhos.com/api/v1/guilds/1489002177550843904/emojis \
  -H "Authorization: Bot $TEBHOS_BOT_TOKEN"

Create guild emoji

POST /guilds/{guild_id}/emojis

Creates an emoji from an emoji create object and returns its guild emoji object (without user) with status 200. Requires CREATE_EXPRESSIONS. The guild receives Guild Emojis Update, and an EMOJI_CREATE audit log entry is recorded. The request body may be at most 2 MiB.

Rate limit: guild:emoji:create, 10 per 30 seconds per account and guild.

Status Code Condition
400 INVALID_FORM_BODY The name is empty, longer than 32 characters or has other characters
400 BAD_REQUEST The image is empty, not valid base64, larger than 256 KiB or not an accepted format, or the guild is at its emoji limit
403 FORBIDDEN CREATE_EXPRESSIONS is missing, or the image is animated and neither Pro nor boost level 1 applies
409 CONFLICT The guild already has an emoji with that name
curl -X POST https://tebhos.com/api/v1/guilds/1489002177550843904/emojis \
  -H "Authorization: Bot $TEBHOS_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "shipit", "image": "data:image/png;base64,iVBORw0KGgo..."}'

Bulk create guild emojis

POST /guilds/{guild_id}/emojis/bulk

Tries to create 1-50 emojis and returns {"success": [...], "failed": [...]}. Requires CREATE_EXPRESSIONS. The request body may be at most 40 MiB.

Rate limit: guild:emoji:bulk_create, 6 per 60 seconds per account and guild.

JSON body

Field Type Description
emojis array[emoji create object] The emojis to create, 1-50 items, attempted in order

Each item is handled independently. success holds the guild emoji objects that were created; failed holds {"name": string, "error": string} for each item that was rejected, where error is a human-readable message. The response is 200 even when every item failed. An empty array or more than 50 items returns 400 INVALID_FORM_BODY.

When at least one emoji was created, the guild receives one Guild Emojis Update.

Clone guild emoji

POST /guilds/{guild_id}/emojis/clone

Copies an emoji from any guild into this guild and returns the new guild emoji object. Requires CREATE_EXPRESSIONS in the target guild; membership of the source guild is not needed. The copy gets a new ID, the caller as uploader, and the source image.

Rate limit: guild:emoji:clone, 10 per 30 seconds per account and guild.

JSON body

Field Type Description
source_emoji_id string The ID (snowflake or legacy UUID) of the emoji to copy
name? string A name for the copy. Defaults to the source name
Status Code Condition
403 FORBIDDEN CREATE_EXPRESSIONS is missing, or the source guild has the CLONE_EMOJI_DISABLED feature
404 NOT_FOUND The source emoji does not exist
409 CONFLICT The target guild already has an emoji with that name

The target guild's emoji limit applies. The copy records an EMOJI_CREATE audit entry and dispatches Guild Emojis Update in the target guild.

Modify guild emoji

PATCH /guilds/{guild_id}/emojis/{emoji_id}

Renames an emoji and returns its guild emoji object. The image cannot be changed. The member who uploaded the emoji needs CREATE_EXPRESSIONS; anyone else needs MANAGE_EXPRESSIONS.

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

Field Type Description
name? string The new name. Same rules as on creation

A rename records an EMOJI_UPDATE audit entry. Every successful request dispatches Guild Emojis Update. An emoji that is not in this guild returns 404 NOT_FOUND, and a name used by another emoji of the guild returns 409 CONFLICT.

Delete guild emoji

DELETE /guilds/{guild_id}/emojis/{emoji_id}

Deletes an emoji and returns 204. The uploader needs CREATE_EXPRESSIONS; anyone else needs MANAGE_EXPRESSIONS.

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

The deletion frees one emoji slot, records an EMOJI_DELETE audit entry and dispatches Guild Emojis Update. Messages that already contain the emoji are not changed. The route takes no purge parameter. An emoji that is not in this guild returns 404 NOT_FOUND.

Upload flow

The TEBHOS web app uploads emoji images directly to storage instead of sending base64. Both steps are user-only (a bot token receives 403 ACCESS_DENIED) and require membership and CREATE_EXPRESSIONS.

  1. POST /servers/{guild_id}/emojis/upload-url with {"filename": string, "content_type": string, "size": integer}. size may be at most 262144 and content_type must be an accepted image type. Returns upload_url (a presigned URL valid for 300 seconds), storage_key, url and expires_in.
  2. PUT the bytes to upload_url, then POST /servers/{guild_id}/emojis/confirm with {"storage_key": string, "name": string, "animated": boolean}.

The confirmation checks the name length (1-32, 400 BAD_REQUEST), name uniqueness (409 CONFLICT) and the animated-emoji rule, records an EMOJI_CREATE audit entry, dispatches Guild Emojis Update and returns {"id", "guild_id", "name", "image_url", "animated"}.