Guild emojis
An emoji is a custom image that one guild owns. Members use it in messages and reactions. Its ID is a snowflake that is unique across every guild. List guild emojis is the only guild-scoped read, and Get emoji metadata resolves a single emoji without membership of its guild.
Every route names a guild in its path. A guild that has UNAVAILABLE_FOR_EVERYONE rejects the request with 403 MISSING_ACCESS before the operation runs, and UNAVAILABLE_FOR_EVERYONE_BUT_STAFF does the same for an account without the instance staff flag.
A guild that does not exist returns 404 UNKNOWN_GUILD. A caller who is not a current member of an existing guild returns 403 MISSING_PERMISSIONS, so guild existence is distinguishable from guild membership. On Modify guild emoji a non-member receives the same 403 MISSING_PERMISSIONS, and a guild that does not exist returns 404 UNKNOWN_EMOJI.
The instance phrase and URL blocklists screen a submitted emoji name before the operation runs, and a match returns 403 CONTENT_BLOCKED. A name of fewer than three characters is not scanned. Neither blocklist reads image. Fluxer checks its decoded bytes against the banned asset hash list when it stores them.
Guild emoji object
Section titled “Guild emoji object”The stored image is written once at creation and is never replaced, so name is the only mutable field.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the emoji |
| name | string | The name of the emoji (2-32 characters) |
| animated1 | boolean | Whether the stored image is animated |
| user?2 | partial user object | The account that uploaded the emoji |
1 Detected from the submitted image at creation, and copied unchanged by Clone guild emoji
2 Present only on List guild emojis, where it is populated for every caller and requires no permission
Example
Section titled “Example”{ "id": "1501314428688998182", "name": "party_parrot", "animated": true}Emoji create object
Section titled “Emoji create object”The image and name submitted for one new emoji.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| name1 | string | The name of the emoji (2-32 characters, ASCII letters, digits, and underscore) |
| image2 3 | base64 string | The image to store (at most the resolved emoji_max_size limit in decoded bytes, 524288 by default) |
1 The value is trimmed, and both bounds apply to the trimmed value
2 A data URL prefix is accepted and everything up to the first comma is removed before any bound applies
3 The decoded ceiling is the resolved emoji_max_size limit key in guild scope, 524288 bytes by default
The remaining encoded portion is bounded to 699052 characters, the base64 expansion of the 524288 byte default, and a longer value returns the validation code BASE64_LENGTH_INVALID at the image path. A value that is not canonical base64 with correct padding returns INVALID_BASE64_FORMAT. An image over the resolved ceiling returns IMAGE_SIZE_EXCEEDS_LIMIT at the same path, and maxSize is the ceiling that applied.
The 699052 character bound does not move with the limit key, so a resolved ceiling above 524288 bytes admits no more than 524289 decoded bytes.
Accepted upload formats are PNG, JPEG, WebP, GIF, APNG, AVIF, HEIC, HEIF, JXL, and SVG. Fluxer takes the format and the animation state from the decoded image. An animated AVIF is rejected.
Pixel dimensions are not enforced. An accepted image is stored at its original dimensions and the Media Proxy image asset contract selects the delivered size.
Example
Section titled “Example”{ "name": "party_parrot", "image": "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAI="}Emoji bulk create response object
Section titled “Emoji bulk create response object”The outcome of one bulk creation, holding one entry for every submitted item.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| success | array[guild emoji object] | The emojis this request created |
| failed | array[expression creation failure object] | The items rejected after top-level request validation |
Both arrays are present on every success response, and either can be empty. An item appears in exactly one of them, so the combined length equals the submitted item count.
Example
Section titled “Example”{ "success": [{"id": "1501314428688998182", "name": "party_parrot", "animated": true}], "failed": [{"name": "too_big", "error": "The image is too large."}]}Expression creation failure object
Section titled “Expression creation failure object”One item a bulk creation rejected, identified only by the name the caller submitted.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| name1 | string | The name echoed from the submitted item |
| error2 | string | The failure message rendered for the item |
1 The object has no index, so two submitted items sharing a name cannot be told apart
2 Rendered in the locale of the authenticated account, so its value changes with the caller’s locale
There is no machine-readable code, so a client that needs to branch on the reason retries the item on its own. An item that fails because the guild is full renders the emoji limit message with the resolved limit. Every other failure with a registered error code renders that code’s own message. An undecodable or unaccepted image renders the generic INVALID_FORM_BODY message with no per-field validation code. A banned image hash renders the CONTENT_BLOCKED message. A failure with no registered code, such as an object storage fault, renders a fixed unknown-error message.
List guild emojis
Section titled “List guild emojis”GET/v1/guilds/{guild_id}/emojisReturns every guild emoji object of the guild, each with user. Requires membership of the guild and no permission.
Fluxer returns the complete collection in one response, and the operation has no pagination parameters. An emoji whose uploader cannot be resolved is omitted, so the array can be shorter than the number of stored emojis.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | array[guild emoji object] | Emojis were returned |
| 4031 | error response | Guild is unavailable, or the caller is not a member |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
1 The error code is MISSING_ACCESS for an unavailable guild and MISSING_PERMISSIONS for a non-member
Rate limit
Section titled “Rate limit”60 requests per 10 seconds for each authenticated user and guild ID, on the guild:emojis:list::guild_id bucket.
Create guild emoji
Section titled “Create guild emoji”POST/v1/guilds/{guild_id}/emojisCreates one emoji from submitted image data and returns its guild emoji object without user. Requires membership of the guild and CREATE_EXPRESSIONS. Emits a Guild Emojis Update Gateway event.
The admission checks run in a fixed order: the body schema, then guild existence and membership, then CREATE_EXPRESSIONS, then the slot limit, and only then the image. A guild at its slot limit therefore returns MAX_EMOJIS even when the image would also have been rejected.
The slot limit is the operator-configured max_guild_emojis value resolved against the guild’s complete feature set, defaulting to 500. A guild with UNLIMITED_EMOJI bypasses that configuration and receives a fixed ceiling of 999999.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
JSON body
Section titled “JSON body”The body is one emoji create object.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | guild emoji object | Emoji was created |
| 4001 | error response | Guild is at its emoji slot limit, or the image is undecodable, oversized, or in an unaccepted format |
| 4032 | error response | Name is blocked, the guild is unavailable, the caller is not a member or lacks CREATE_EXPRESSIONS, or the image hash is banned |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
1 The error code is MAX_EMOJIS for the slot limit, with the resolved limit in its message variables, and INVALID_FORM_BODY for an image failure, with BASE64_LENGTH_INVALID for an oversized encoding, IMAGE_SIZE_EXCEEDS_LIMIT for decoded bytes over the resolved ceiling, or INVALID_IMAGE_FORMAT for an undecodable or unaccepted image at the image path
2 The error code is CONTENT_BLOCKED for a blocked name and for a banned image hash, MISSING_ACCESS for an unavailable guild, and MISSING_PERMISSIONS for a membership or permission failure
An image the decoder cannot read returns INVALID_IMAGE_FORMAT. The name scan runs before the route is reached, so it precedes the rate limit bucket and the credential check. The image hash check runs at upload time, after every other admission step has passed.
Side effects
Section titled “Side effects”The operation consumes one guild emoji slot, stores the metadata-stripped image, emits Guild Emojis Update with the guild’s complete emoji collection to every session connected to the guild, and then writes an EMOJI_CREATE audit entry with the supplied reason. A failed creation leaves no emoji, audit entry, or Dispatch and consumes no slot. Fluxer logs a failure to write the audit entry and still returns 200, so the emoji exists and the Dispatch is emitted.
Rate limit
Section titled “Rate limit”10 requests per 30 seconds for each authenticated user and guild ID, on the guild:emoji:create::guild_id bucket.
Bulk create guild emojis
Section titled “Bulk create guild emojis”POST/v1/guilds/{guild_id}/emojis/bulkAttempts to create between 1 and 50 emojis in one request and returns an emoji bulk create response object. Requires membership of the guild and CREATE_EXPRESSIONS. Emits one Guild Emojis Update Gateway event for the whole batch.
Fluxer processes the items strictly in the submitted order and treats each one independently. Once the guild is full, every remaining item fails with the limit. A later item can still succeed after an earlier item failed for any other reason.
An undecodable image, an unaccepted format, and a banned hash each fail one item and leave the rest of the batch to run.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| emojis | array[emoji create object] | The items to create, attempted in the order supplied (1-50) |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | emoji bulk create response object | Every validated item was attempted |
| 4001 | error response | Top-level body, item count, item shape, item name, or encoded image bound is invalid |
| 4032 | error response | An item name is blocked, the guild is unavailable, or the caller is not a member or lacks CREATE_EXPRESSIONS |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
1 Boundary validation rejects the whole request, so an oversized encoded image in one item fails before any item is created
2 The error code is CONTENT_BLOCKED for a blocked item name, MISSING_ACCESS for an unavailable guild, and MISSING_PERMISSIONS for a membership or permission failure
Every item name is scanned together before the route is reached, so one blocked name rejects the whole request and no item is created.
Side effects
Section titled “Side effects”Each successful item consumes one guild emoji slot, stores its image, and writes an EMOJI_CREATE audit entry with the supplied reason. One Guild Emojis Update with the guild’s complete emoji collection is emitted after the batch when at least one item succeeded, and it is emitted before the audit entries are written. A failed item leaves no emoji, audit entry, or slot consumption.
Rate limit
Section titled “Rate limit”6 requests per minute for each authenticated user and guild ID, on the guild:emoji:bulk_create::guild_id bucket.
Clone guild emoji
Section titled “Clone guild emoji”POST/v1/guilds/{guild_id}/emojis/cloneCopies an existing emoji into the target guild and returns the new guild emoji object without user. Requires membership of the target guild and CREATE_EXPRESSIONS there. Emits a Guild Emojis Update Gateway event in the target guild.
The name, animation state, and stored image bytes are copied server-side, so the caller does not re-upload the image and cannot override any copied value. Membership of the source guild is not required. The source guild must not have CLONE_EMOJI_DISABLED.
An unknown source emoji is reported first, then a source guild that is missing or that disables cloning, then target membership and permission, and only then the target slot limit. Get emoji metadata reports whether a source permits cloning without attempting the operation.
The copied bytes are not re-scanned against the banned asset hash list.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the target guild |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| source_emoji_id | snowflake | The ID of the emoji to copy, which can belong to any guild |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | guild emoji object | Emoji was cloned |
| 4001 | error response | Target guild is at its emoji slot limit |
| 4032 | error response | Source guild is missing or disables cloning, the target guild is unavailable, or the caller is not a member of the target guild or lacks CREATE_EXPRESSIONS there |
| 4043 | error response | Source emoji or target guild does not exist |
1 The error code is MAX_EMOJIS
2 The error code is MISSING_ACCESS when the source guild is missing or has CLONE_EMOJI_DISABLED and when the target guild is unavailable, and MISSING_PERMISSIONS for a target membership or permission failure
3 The error code is UNKNOWN_EMOJI for the source emoji and UNKNOWN_GUILD for the target guild
A source guild that no longer exists returns 403 MISSING_ACCESS, so a caller cannot tell it apart from a source guild that disables cloning.
Side effects
Section titled “Side effects”The operation consumes one target guild emoji slot and creates a copy whose uploader is the caller. It emits Guild Emojis Update with the target guild’s complete emoji collection and then writes an EMOJI_CREATE audit entry. The source emoji and source guild are unchanged and receive no Dispatch.
Rate limit
Section titled “Rate limit”10 requests per 30 seconds for each authenticated user and target guild ID, on the guild:emoji:clone::guild_id bucket.
Modify guild emoji
Section titled “Modify guild emoji”PATCH/v1/guilds/{guild_id}/emojis/{emoji_id}Renames an emoji and returns its guild emoji object without user. Emits a Guild Emojis Update Gateway event.
Limitations
Section titled “Limitations”- The uploader can rename their own emoji with CREATE_EXPRESSIONS.
- Any other caller requires MANAGE_EXPRESSIONS.
Neither permission is subject to the guild MFA level.
The emoji is resolved within the guild named in the path before any permission is evaluated. An emoji that belongs to another guild and an emoji in a guild that does not exist both return 404 UNKNOWN_EMOJI.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
| emoji_id | snowflake | The ID of the emoji |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| name | string | The new name of the emoji (2-32 characters, ASCII letters, digits, and underscore) |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | guild emoji object | Name was processed |
| 4001 | error response | Path parameter or name is invalid |
| 4032 | error response | Name is blocked, the guild is unavailable, or the caller is neither the uploader with CREATE_EXPRESSIONS nor a member holding MANAGE_EXPRESSIONS |
| 404 | error response | Emoji does not exist in that guild and the request returns UNKNOWN_EMOJI |
1 The error code is INVALID_FORM_BODY with INVALID_SNOWFLAKE_FORMAT or SNOWFLAKE_OUT_OF_RANGE for a path parameter, STRING_LENGTH_INVALID for a name outside 2 to 32 characters after normalisation, and INVALID_FORMAT for a disallowed character
2 The error code is CONTENT_BLOCKED for a blocked name, MISSING_ACCESS for an unavailable guild, and MISSING_PERMISSIONS for a permission failure
Side effects
Section titled “Side effects”The operation sets the requested name, emits Guild Emojis Update with the guild’s complete emoji collection, and then writes an EMOJI_UPDATE audit entry. Both are produced even when the submitted name equals the current name, and the audit entry then records an empty change list.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user and guild ID, on the guild:emoji:update::guild_id bucket.
Delete guild emoji
Section titled “Delete guild emoji”DELETE/v1/guilds/{guild_id}/emojis/{emoji_id}Deletes the emoji record and returns 204 with an empty body. Emits a Guild Emojis Update Gateway event.
Limitations
Section titled “Limitations”- The uploader can delete their own emoji with CREATE_EXPRESSIONS.
- Any other caller requires MANAGE_EXPRESSIONS.
Neither permission is subject to the guild MFA level. Fluxer resolves the guild, then the purge eligibility, then the emoji, and only then the permission, so a purging request in a guild without the required feature is refused before the emoji is looked up.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
| emoji_id | snowflake | The ID of the emoji |
Query parameters
Section titled “Query parameters”| Field | Type | Description |
|---|---|---|
| purge?1 | boolean | Whether to permanently delete the stored image (default false) |
1 Read as true only when it is exactly true, True, or 1 after trimming. Every other value, including TRUE and yes, reads as false
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | Emoji record was deleted |
| 4031 | error response | Guild is unavailable or cannot purge expression assets, or the caller is neither the uploader with CREATE_EXPRESSIONS nor a member holding MANAGE_EXPRESSIONS |
| 4042 | error response | Guild or emoji does not exist |
1 The error code is MISSING_ACCESS for an unavailable guild and when purge is true and the guild lacks EXPRESSION_PURGE_ALLOWED, and MISSING_PERMISSIONS for a membership or permission failure
2 The error code is UNKNOWN_GUILD for the guild and UNKNOWN_EMOJI for the emoji
Side effects
Section titled “Side effects”The operation removes the emoji from the guild, returns its slot, emits Guild Emojis Update with the guild’s remaining emoji collection, and then writes an EMOJI_DELETE audit entry. When purge is true, the stored object and its cached representations are queued for permanent deletion after the Dispatch and before the audit entry. Existing messages that reference the emoji are not rewritten, and no message Dispatch is produced.
Rate limit
Section titled “Rate limit”10 requests per 30 seconds for each authenticated user and guild ID, on the guild:emoji:delete::guild_id bucket. The route also draws on the guild:emoji:delete:daily::guild_id bucket of 300 requests per day for each authenticated user and guild ID.