Cosmetics
A cosmetic is an image an account wears next to its avatar, over its profile, or behind its name. The catalog lists the items on offer; the Admin API adds and changes them. An account wears at most one item of each type, and at most one of an avatar decoration and an ultra decoration: wearing one takes the other off, and a request that puts both on keeps the ultra decoration.
Every route on this page is user-only, requires no permission, and acts on the caller’s own account.
Cosmetic item types
Section titled “Cosmetic item types”| Value | Description |
|---|---|
| avatar_decoration | A frame drawn around the avatar |
| avatar_ultra | A large decoration drawn behind or in front of the avatar on supported surfaces |
| profile_effect | An effect played over the profile card |
| nameplate | A background behind the name in member and direct message lists |
| room_character | A 3D character that shows the account inside 3D voice rooms |
| room_face | The face and expression of the modular room character |
| room_hair | The hair of the modular room character |
| room_top | The shirt or jacket of the modular room character |
| room_bottom | The trousers or shorts of the modular room character |
| room_shoes | The shoes or socks of the modular room character |
| room_costume | A costume of the modular room character, worn instead of the top and the bottom |
| room_hat | The hat of the modular room character |
| room_glasses | The glasses of the modular room character |
| room_accessory | An accessory of the modular room character, such as headphones |
The nine room_<slot> types are the parts of the modular room character, one slot each. An account dresses it with Dress my room character.
Cosmetic availability
Section titled “Cosmetic availability”| Value | Description |
|---|---|
| free | Every account can wear it |
| premium | Accounts with premium can wear it, and so can an account that owns it |
| owned | Only accounts that own it can wear it |
Cosmetic item object
Section titled “Cosmetic item object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the item |
| type | string | The cosmetic item type |
| name | string | The display name of the item (1-64 characters) |
| description | ?string | A short description of the item (1-256 characters) |
| asset1 | ?string | The hash of the item image |
| availability | string | The cosmetic availability |
| ultra_layout2 | ?ultra layout object | The sizes of an ultra decoration on each surface |
| ultra_front3 | ?ultra front object | The images of an ultra decoration drawn in front of the avatar |
| effect_layers?4 | ?effect layers object | The HD intro and loop of a profile effect |
| model_key5 | ?string | The character model or preset of a room character, or the part of a room character part |
1 Eight hexadecimal characters, prefixed with a_ when the image is animated. The media proxy serves the image at /branding/cosmetic-{type}-{id}/{asset}.webp on the instance’s media endpoint, with size between 128 and 480 and animated=true for the moving image. Null for a room character part without its own image: the client shows the preview its part manifest names
2 Null for every other type, and for an ultra decoration the admin gave no sizes, which then uses the fixed sizes
3 Null for every other type, and for an ultra decoration drawn behind the avatar
4 Null or absent when no layers are available, and null for every other type. An incomplete stored set or an invalid intro duration is returned as null
5 Present on a room_character item and on the room_<slot> items, absent on every other type. The client draws the character and its parts from its own copy of the models, so a key this client does not know shows the default outfit, or leaves that slot to the default outfit
Example
Section titled “Example”{ "id": "1501314428688998182", "type": "avatar_decoration", "name": "Gold ring", "description": null, "asset": "a_1a2b3c4d", "availability": "premium", "ultra_layout": null, "ultra_front": null, "effect_layers": null}Ultra layout object
Section titled “Ultra layout object”The sizes an admin gave an ultra decoration, one entry for each surface. A client that does not read it draws the fixed sizes, and so does a client whose request for it fails.
| Field | Type | Description |
|---|---|---|
| compact | ?ultra layout surface object | The size in chat and in the member list, null for the fixed size |
| voice | ?ultra layout surface object | The size on voice tiles, null for the fixed size |
| profile | ?ultra layout surface object | The size on the profile card, null for the fixed size |
Ultra layout surface object
Section titled “Ultra layout surface object”Every value is a multiple of the avatar diameter, on the scale of the fixed sizes 2.30, 3.20 and 3.40. Micup keeps three decimal places.
| Field | Type | Description |
|---|---|---|
| width | number | The width of the decoration (0.5-6) |
| height | number | The height of the decoration (0.5-6) |
| offset_x | number | The horizontal shift from the centre of the avatar (-3 to 3) |
| offset_y | number | The vertical shift from the centre of the avatar (-3 to 3) |
Ultra front object
Section titled “Ultra front object”The images an admin gave an ultra decoration to draw it in front of the avatar. Each one is the left half of the decoration, twice as tall as it is wide, and a client draws the right half as its mirror image.
| Field | Type | Description |
|---|---|---|
| closed | string | The hash of the still image shown while the decoration is closed |
| open | array[string] | The hashes of the still opening frames in order, 2 to 30 of them |
| idle | string | The hash of the animated loop played while the decoration is open, prefixed with a_ |
The media proxy serves each image like asset, under the same item path. A client asks for them with size up to 600, since an image can be 576 pixels tall.
A client that reads it draws the decoration over the avatar in a square 3.468 times the avatar diameter on every surface, and ultra_layout applies only to drawing behind. The decoration rests on closed. When the avatar is interacted with, such as on hover, on keyboard focus, or when a profile opens, the opening frames play forward at 30 frames per second and idle loops. Letting go plays the frames back from the one showing. With reduced motion or data saving on, the decoration stays closed.
A client loads the frames and the loop on the first open and replays every later open from what it loaded. It draws no ultra decoration before it has read the item through List cosmetic items by ID, so a decoration never jumps from behind the avatar to the front. A client that does not read it, or whose request for the item fails, draws asset behind the avatar.
Effect layers object
Section titled “Effect layers object”The high-resolution layers an admin gave a profile effect. They belong to the cosmetic item, including items in owned, and are not copied into cosmetic asset data, partial users, profiles or Gateway events. A client reads them through List cosmetic items by ID.
| Field | Type | Description |
|---|---|---|
| intro | string | The hash of the animated intro, prefixed with a_ |
| loop | string | The hash of the animated loop, prefixed with a_ |
| intro_ms | integer | The intro duration in milliseconds (250-30000) |
The media proxy serves both WebP images under /branding/cosmetic-profile_effect-{id}/{hash}.webp, using size=1024&animated=true. Each side is 128 through 1024 pixels. Each layer is at most 3000000 bytes, and the pair is at most 4500000 bytes.
A supported client uses the layers only on open profiles: the profile modal, mobile sheet, profile page and popouts. It loads both layers before playing the intro, then starts the loop after intro_ms. Each profile opening restarts the intro. Shop, settings and previews use the main image in asset. When animation is disabled or reduced motion is enabled, the client uses a still main image. A client without layer support, with no layers, or whose layer download fails uses the main image.
Cosmetic asset data object
Section titled “Cosmetic asset data object”The item an account wears, as it appears on the partial user and the profile. A field that carries it is always present and is null when the account wears nothing of that type.
| Field | Type | Description |
|---|---|---|
| asset1 | string | The hash of the image the account put on |
| item_id | snowflake | The ID of the worn item |
1 Copied when the item is put on, so an account keeps the image it put on after the item’s image changes. The ultra front images and effect layers are not copied: a client reads them from the item, so a new set reaches every account that wears it
The partial user carries avatar_decoration_data, avatar_ultra_data and nameplate_data. The profile carries profile_effect_data.
List cosmetic catalog
Section titled “List cosmetic catalog”GET/v1/cosmetics/catalogReturns the items on offer. An item taken off sale is not listed.
Query parameters
Section titled “Query parameters”| Field | Type | Description |
|---|---|---|
| type? | string | Only return items of this cosmetic item type |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | array[cosmetic item object] | Catalog was returned |
Each API process keeps the catalog for up to 60 seconds, so a catalog change can take that long to appear.
Rate limit
Section titled “Rate limit”30 requests per minute for each authenticated user, on the cosmetics:catalog bucket.
List cosmetic items by ID
Section titled “List cosmetic items by ID”GET/v1/cosmetics/itemsReturns up to 50 items by ID, including items taken off sale, as an array of cosmetic item objects. A client uses it to draw what other accounts wear, such as the sizes and in-front images of an ultra decoration, with one request for every batch of new items it sees. An unknown ID is left out, and a repeated ID is returned once.
Query parameters
Section titled “Query parameters”| Field | Type | Description |
|---|---|---|
| ids | string | Comma separated item IDs, 1 to 50 of them |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | array[cosmetic item object] | The known items were returned |
| 400 | error response | More than 50 IDs, or an ID that is not a positive 64-bit integer, returned as INVALID_FORM_BODY |
Each API process keeps an item for up to 60 seconds, and at most 5,000 items, so a change an admin makes can take that long to appear.
Rate limit
Section titled “Rate limit”30 requests per minute for each authenticated user, on the cosmetics:items bucket.
List my cosmetics
Section titled “List my cosmetics”GET/v1/users/@me/cosmeticsReturns the items the current account owns and the items it wears.
Response body
Section titled “Response body”| Field | Type | Description |
|---|---|---|
| owned | array[cosmetic item object] | The items the account owns, including items taken off sale |
| equipped | equipped cosmetics object | The items the account wears |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | response body | Items were returned |
Rate limit
Section titled “Rate limit”30 requests per minute for each authenticated user, on the cosmetics:list_own bucket.
Equipped cosmetics object
Section titled “Equipped cosmetics object”| Field | Type | Description |
|---|---|---|
| avatar_decoration_id | ?snowflake | The avatar decoration being worn |
| avatar_ultra_id | ?snowflake | The ultra decoration being worn |
| profile_effect_id | ?snowflake | The profile effect being worn |
| nameplate_id | ?snowflake | The nameplate being worn |
| room_face_id1 | ?snowflake | The room character face being worn |
| room_hair_id1 | ?snowflake | The room character hair being worn |
| room_top_id1 | ?snowflake | The room character top being worn |
| room_bottom_id1 | ?snowflake | The room character bottom being worn |
| room_shoes_id1 | ?snowflake | The room character shoes being worn |
| room_costume_id1 | ?snowflake | The room character costume being worn |
| room_hat_id1 | ?snowflake | The room character hat being worn |
| room_glasses_id1 | ?snowflake | The room character glasses being worn |
| room_accessory_id1 | ?snowflake | The room character accessory being worn |
| room_character_id1 | ?snowflake | The room character being worn, null for the default character or the worn parts |
| room_character_shirt1 | ?integer | The shirt colour of the default character and its parts as 0xRRGGBB, null when the server derives it from the account ID |
1 Returned by List my cosmetics only. Wear or take off cosmetics neither reads nor changes them; Choose a room character and Dress my room character do
Wear or take off cosmetics
Section titled “Wear or take off cosmetics”PUT/v1/users/@me/cosmetics/equippedPuts items on and takes them off. Returns the equipped cosmetics object.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| avatar_decoration_id? | ?snowflake | The avatar decoration to wear, or null to take it off |
| avatar_ultra_id? | ?snowflake | The ultra decoration to wear, or null to take it off |
| profile_effect_id? | ?snowflake | The profile effect to wear, or null to take it off |
| nameplate_id? | ?snowflake | The nameplate to wear, or null to take it off |
An omitted field leaves that type as it is.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | equipped cosmetics object | Items were put on or taken off |
| 403 | error response | COSMETIC_NOT_OWNED: an item is unknown, is not of the field’s type, or the account may not wear it |
Side effects
Section titled “Side effects”When a worn item changes, the account’s sessions receive User Update with the current user object. A changed avatar decoration, ultra decoration or nameplate also reaches every guild the account is in as Guild Member Update. A request that changes nothing writes nothing and emits nothing.
Rate limit
Section titled “Rate limit”5 requests per 10 minutes for each authenticated user, on the cosmetics:equip bucket.
Choose a room character
Section titled “Choose a room character”PUT/v1/users/@me/cosmetics/room-characterSets the character the account shows as inside 3D voice rooms. Returns the worn character and shirt.
The default character is worn when item_id is null. Its shirt colour comes from a fixed palette of 16 colours: shirt picks one, and null lets the server derive one from the account ID. Every other character wears its own colours, and the server keeps shirt with the account, so going back to the default character brings the colour back.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| item_id | ?snowflake | The ID of the room character item to wear, or null to wear the default character |
| shirt | ?integer | A colour of the shirt palette as 0xRRGGBB, or null to derive it from the account ID; default character only |
Both fields are required. A shirt outside the palette returns 400 INVALID_FORM_BODY.
Response body
Section titled “Response body”| Field | Type | Description |
|---|---|---|
| room_character_id | ?snowflake | The room character being worn, null for the default character |
| room_character_shirt | ?integer | The shirt colour the account chose, null when it derives from the account ID |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | response body | The character was put on |
| 400 | error response | shirt is not in the palette, returned as INVALID_FORM_BODY |
| 403 | error response | The item is unknown, is not a room character, or the account may not wear it, returned as COSMETIC_NOT_OWNED |
| 403 | error response | Room characters are switched off, returned as FEATURE_TEMPORARILY_DISABLED |
Side effects
Section titled “Side effects”When the character or the shirt changes, the account’s own sessions receive User Update. Nothing reaches the guilds the account is in. A request that changes nothing writes nothing and emits nothing. A voice room shows the new character once the client sends Refresh my voice room character.
Rate limit
Section titled “Rate limit”10 requests per minute for each authenticated user, on the cosmetics:room_character bucket.
Dress my room character
Section titled “Dress my room character”PUT/v1/users/@me/cosmetics/room-outfitPuts room character parts on and takes them off inside 3D voice rooms, all in one write, and sets their shirt colour. Returns the room outfit the account wears.
A slot the account leaves empty shows the part of the default outfit. A part goes on together with the parts it fits with: a part takes off the worn parts it excludes and the worn parts that exclude it, so a costume takes off the top and the bottom and a top takes off the costume. Wearing a part takes the room character off.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| face_id? | ?snowflake | The room_face item to wear, or null to take it off |
| hair_id? | ?snowflake | The room_hair item to wear, or null to take it off |
| top_id? | ?snowflake | The room_top item to wear, or null to take it off |
| bottom_id? | ?snowflake | The room_bottom item to wear, or null to take it off |
| shoes_id? | ?snowflake | The room_shoes item to wear, or null to take it off |
| costume_id? | ?snowflake | The room_costume item to wear, or null to take it off |
| hat_id? | ?snowflake | The room_hat item to wear, or null to take it off |
| glasses_id? | ?snowflake | The room_glasses item to wear, or null to take it off |
| accessory_id? | ?snowflake | The room_accessory item to wear, or null to take it off |
| shirt? | ?integer | A colour of the shirt palette as 0xRRGGBB, or null to derive it from the account ID |
An omitted field stays as it is. The shirt colour paints the parts that take the wearer’s colour. A shirt outside the palette returns 400 INVALID_FORM_BODY.
Room outfit object
Section titled “Room outfit object”| Field | Type | Description |
|---|---|---|
| room_face_id | ?snowflake | The room character face being worn |
| room_hair_id | ?snowflake | The room character hair being worn |
| room_top_id | ?snowflake | The room character top being worn |
| room_bottom_id | ?snowflake | The room character bottom being worn |
| room_shoes_id | ?snowflake | The room character shoes being worn |
| room_costume_id | ?snowflake | The room character costume being worn |
| room_hat_id | ?snowflake | The room character hat being worn |
| room_glasses_id | ?snowflake | The room character glasses being worn |
| room_accessory_id | ?snowflake | The room character accessory being worn |
| room_character_id | ?snowflake | The room character being worn, null once a part is worn |
| room_character_shirt | ?integer | The shirt colour the account chose, null when it derives from the account ID |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | room outfit object | The parts were put on or taken off |
| 400 | error response | INVALID_FORM_BODY: two parts of the request exclude each other, or shirt is not in the palette |
| 403 | error response | COSMETIC_NOT_OWNED: a part is unknown, of another slot or family, or the account may not wear it |
| 403 | error response | Room characters are switched off, returned as FEATURE_TEMPORARILY_DISABLED |
A part is also refused with COSMETIC_NOT_OWNED when its key is not a part of its slot in the part manifest this server version ships. Of two parts that exclude each other, the error names the later slot.
Side effects
Section titled “Side effects”When a part, the room character or the shirt changes, the account’s own sessions receive User Update. Nothing reaches the guilds the account is in. A request that changes nothing writes nothing and emits nothing. A voice room shows the new outfit once the client sends Refresh my voice room character.
Rate limit
Section titled “Rate limit”10 requests per minute for each authenticated user, on the cosmetics:room_character bucket shared with Choose a room character.