User settings
User settings are the stored preferences of one account. Fluxer keeps them in two records: the account-wide user settings object, and a user guild settings object for each guild and for private channels.
Every route here is user-only and rejects a bot or OAuth2 bearer credential with 403 ACCESS_DENIED. Every route except Get current user settings also rejects an account with an outstanding required action, with 403 ACCOUNT_SUSPICIOUS_ACTIVITY.
Presence status values
Section titled “Presence status values”| Value | Description |
|---|---|
| online | User is presented as online |
| dnd | User is presented as do not disturb |
| idle | User is presented as idle |
| invisible1 | User is presented as offline to everyone else |
1 The account stays connected and keeps receiving Gateway traffic while this value is stored
Theme values
Section titled “Theme values”| Value | Description |
|---|---|
| dark | Dark theme |
| dark_legacy | Previous generation of the dark theme |
| coal | Coal theme |
| light | Light theme |
| system | Theme follows the operating system |
Notification levels
Section titled “Notification levels”| Value | Name | Description |
|---|---|---|
| 0 | ALL_MESSAGES | Notify for every message |
| 1 | ONLY_MENTIONS | Notify only for mentions |
| 2 | NO_MESSAGES | Do not notify for messages |
| 3 | INHERIT | Inherit the parent setting |
Guild mute configuration object
Section titled “Guild mute configuration object”Mute expiry for a guild, a private channel group, or a channel override.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| end_time1 | ?ISO8601 timestamp | The time at which the temporary mute stops applying, or null for no expiry |
| selected_time_window2 | integer | The opaque mute duration the client selected |
1 An end_time in the past no longer mutes notifications but can remain present in the response
2 The value is returned unchanged and takes no part in notification delivery. An absent value is returned as 0
Guild mute configuration input object
Section titled “Guild mute configuration input object”The input form of the guild mute configuration object.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| end_time?1 | ?ISO8601 timestamp | integer | The time at which the temporary mute stops applying, or null for no expiry |
| selected_time_window | integer | The opaque mute duration the client selected, stored verbatim |
1 The value is an ISO 8601 timestamp string or Unix milliseconds. A string that is not a valid timestamp is rejected with INVALID_ISO_TIMESTAMP
Channel notification override object
Section titled “Channel notification override object”Notification settings stored for one channel.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| collapsed1 | boolean | Whether the channel category is collapsed |
| message_notifications | integer | Notification level |
| muted | boolean | Whether channel notifications are muted |
| mute_config | ?guild mute configuration object | The mute configuration of the channel, or null when none is stored |
| unread_badges1 2 | ?integer | Notification level for unread badges, or null to inherit |
1 The value controls client presentation and does not affect notification delivery
2 Every response has the member, with null standing in for an unset level
Channel notification override input object
Section titled “Channel notification override input object”The input form of the channel notification override object.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| collapsed | boolean | Whether the channel category is collapsed |
| message_notifications | integer | Notification level |
| muted | boolean | Whether channel notifications are muted |
| mute_config? | ?guild mute configuration input object | The mute configuration of the channel, or null to clear it |
| unread_badges? | ?integer | Notification level for unread badges, or null to inherit |
User guild settings object
Section titled “User guild settings object”Notification settings for one guild, or for every private channel when guild_id is null.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| guild_id1 | ?snowflake | The ID of the guild, or null for direct message and group DM settings |
| message_notifications | integer | The default notification level |
| muted | boolean | Whether the guild or private channel group is muted |
| mute_config | ?guild mute configuration object | The mute configuration, or null when none is stored |
| mobile_push | boolean | Whether notification delivery is enabled for the guild |
| suppress_everyone | boolean | Whether @everyone mentions are suppressed |
| suppress_roles | boolean | Whether role mentions are suppressed |
| hide_muted_channels3 | boolean | Whether muted channels are hidden |
| channel_overrides2 | ?map[snowflake, channel notification override object] | The per-channel overrides, or null when none are set |
| unread_badges3 5 | ?integer | The default notification level for unread badges, or null to follow message_notifications |
| version4 | integer | The monotonic revision of this settings object |
1 The private channel settings are always serialised with guild_id null
2 An override map holding no entry is serialised as null
3 The value controls client presentation and does not affect notification delivery
4 The value increases on every stored write, including one that changes no other member, so a client can discard a stale User Guild Settings Update
5 Every response has the member, with null standing in for an unset level
Example
Section titled “Example”{ "guild_id": null, "message_notifications": 1, "muted": false, "mute_config": null, "mobile_push": true, "suppress_everyone": false, "suppress_roles": false, "hide_muted_channels": false, "channel_overrides": null, "unread_badges": null, "version": 4}Guild settings update fields
Section titled “Guild settings update fields”Both notification settings operations accept exactly these fields. Every field is optional, and an omitted field leaves the stored value unchanged.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| message_notifications? | integer | The default notification level, INHERIT for new settings |
| muted? | boolean | Whether the guild is muted, default false for new settings |
| mute_config? | ?guild mute configuration input object | The mute configuration, or null to clear it |
| mobile_push? | boolean | Whether notification delivery is enabled, default true for new settings |
| suppress_everyone? | boolean | Whether @everyone mentions are suppressed, default false for new settings |
| suppress_roles? | boolean | Whether role mentions are suppressed, default false for new settings |
| hide_muted_channels? | boolean | Whether muted channels are hidden, default false for new settings |
| channel_overrides?1 | ?map[snowflake, channel notification override input object] | The complete per-channel override map, or null to clear it |
| unread_badges? | ?integer | The default notification level for unread badges, or null to follow message_notifications |
1 The supplied map becomes the complete override set, and an empty map clears every override
A direct mention of the account always counts. An @everyone or @here mention counts only while suppress_everyone is false, and a role mention only while suppress_roles is false. A mention that counts increments mention_count on the channel’s read state and adds an entry to the recent mention history. A guild message whose every mention is suppressed records nothing.
Neither field is read outside a guild. A direct message and a group DM collect only direct mentions, and every one of them counts whatever the private channel settings hold.
User settings update object
Section titled “User settings update object”The input form of the user settings object. Every field is optional, and an omitted field leaves the stored value unchanged. A field present with a value overwrites the stored value in full, including an array or object member.
The three staff-only fields are the exception. Every update resets suppress_unprivileged_self_mentions, suppress_unprivileged_self_mentions_bypass_user_ids, and staff_dm_access_user_ids to false, empty, and empty for an ordinary account, including an update that names none of them.
Two further members are accepted and ignored. guild_positions is an array of at most 200 guild snowflakes, and nothing reads it. default_share_voice_activity belongs to Modify voice activity sharing.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| status? | string | Presence status |
| status_resets_at?1 | ?ISO8601 timestamp | integer | The moment at which the scheduled reset applies, or null to clear it |
| status_resets_to? | ?string | Presence status applied by the scheduled reset, or null to clear it |
| theme? | string | Theme value |
| locale?2 | string | Interface locale |
| restricted_guilds?3 | array[snowflake] | The guilds where member direct messages are restricted (max 200) |
| bot_restricted_guilds?3 | array[snowflake] | The guilds where bot direct messages are restricted (max 200) |
| default_guilds_restricted? | boolean | Whether newly joined guilds restrict member direct messages |
| bot_default_guilds_restricted? | boolean | Whether newly joined guilds restrict bot direct messages |
| inline_attachment_media? | boolean | Whether attachment media is rendered inline |
| inline_embed_media? | boolean | Whether embed media is rendered inline |
| gif_auto_play? | boolean | Whether GIF media plays automatically |
| render_embeds? | boolean | Whether message embeds are rendered |
| render_reactions? | boolean | Whether message reactions are rendered |
| animate_emoji? | boolean | Whether custom emoji animate |
| animate_stickers? | integer | Sticker animation setting |
| render_spoilers? | integer | Spoiler rendering setting |
| message_display_compact? | boolean | Whether messages use compact presentation |
| flags?4 | integer | Friend source flags |
| friend_source_flags?4 | integer | Friend source flags |
| incoming_call_flags?5 | integer | Incoming call flags |
| group_dm_add_permission_flags?6 | integer | Group DM add permission flags |
| guild_folders?7 | array[guild folder input object] | The complete guild folder layout (max 100) |
| custom_status?8 | ?custom status input object | The custom status, or null to clear it |
| afk_timeout? | integer | The idle seconds before the account is presented as away (60-600) |
| time_format? | integer | Time format setting |
| developer_mode? | boolean | Whether developer mode is enabled |
| trusted_domains?9 | array[string] | The trusted external link domains (max 1000, each 1-253 characters) |
| default_hide_muted_channels? | boolean | Whether newly joined guilds hide muted channels |
| sensitive_content_friend_dm_filter?10 | integer | Sensitive media filter for friend direct messages |
| sensitive_content_non_friend_dm_filter?11 | integer | Sensitive media filter for non-friend direct messages |
| sensitive_content_guild_filter?11 | integer | Guild sensitive media filter |
| suppress_unprivileged_self_mentions?12 | boolean | Whether direct and reply mentions from unprivileged users are suppressed |
| suppress_unprivileged_self_mentions_bypass_user_ids?12 | ?array[snowflake] | The users exempt from mention suppression |
| staff_dm_access_user_ids?12 | ?array[snowflake] | The users granted staff direct message access |
| profile_privacy? | integer | Profile privacy level |
| synced_preferences?13 | ?string | The base64-encoded fluxer.user.preferences.v1.SyncedPreferences snapshot, or null to clear it |
1 A string matches ISO 8601 and an integer is Unix milliseconds between 0 and 8640000000000000. Anything else is rejected with INVALID_ISO_TIMESTAMP
2 The value is an exact entry of the supported locale registry, never a negotiated nearest match. A change also applies to email localisation
3 Duplicate identifiers are removed before the bound is applied, and an empty array clears the stored set
4 flags is a legacy alias for friend_source_flags, which wins when both are supplied. friend_source_flags is bounded to 0 through 2147483647 while flags accepts any integer
5 The stored value is collapsed before it is written. FRIENDS_ONLY wins over NOBODY, and either collapse preserves SILENT_EVERYONE
6 FRIENDS_ONLY, then NOBODY, then EVERYONE are tested in that order against the already collapsed value, so EVERYONE applies only when neither of the other two is supplied
7 The array replaces the layout in full
8 The object replaces the stored custom status in full, so an omitted member is cleared. Input normalisation turns an all-empty object into null, which clears the status
9 The single entry * trusts every domain and cannot be combined with a concrete domain, which fails against trusted_domains with INVALID_TRUSTED_DOMAINS. An empty array clears the set
10 An account that is not a verified adult can set only blur or block. Any other value fails against that field with AGE_RESTRICTED
11 An account that is not a verified adult cannot modify this field, and supplying it fails against that field with AGE_RESTRICTED
12 The field is staff-only
13 The value runs to at most 349528 characters of base64 and decodes to at most 262144 bytes, the 256 KiB ceiling. A longer string fails at the boundary, an oversized decode fails with TOO_LARGE, and an undecodable value fails with INVALID_FORMAT
Fluxer decodes an accepted synced_preferences value, re-encodes it canonically, and stores the result, so a snapshot with only zero values is stored as cleared and read back as the empty string.
Fluxer prepends an empty uncategorised folder to a submitted layout that omits one. A guild ID listed in more than one folder is kept only in the highest-ranked folder. A name is the primary key, so a named folder outranks an unnamed one whatever its identity, and an ordinary folder outranks the uncategorised folder only when both are named or both unnamed. The earliest folder in the submitted order wins a tie.
Guild folder input object
Section titled “Guild folder input object”One folder of a submitted guild folder layout.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id1 | integer | The identifier of the folder |
| name? | ?string | The name of the folder (0-100 characters) |
| color?2 | ?integer | The packed 24-bit RGB colour of the folder (0-16777215) |
| flags?2 | integer | Guild folder flags |
| icon?2 | string | Guild folder icon |
| guild_ids3 | array[snowflake] | The guild IDs in display order (max 200) |
1 The value is at least -1, and -1 identifies the uncategorised folder
2 An omitted color is stored as 0, an omitted flags as 0, and an omitted icon as folder. A color below 0 fails with COLOR_VALUE_TOO_LOW and one above 16777215 with COLOR_VALUE_TOO_HIGH
3 Duplicate identifiers within one folder are removed before the bound is applied
Custom status input object
Section titled “Custom status input object”A custom status as submitted with a settings update.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| text?1 | ?string | The status text (1-128 characters) |
| expires_at?2 | ?ISO8601 timestamp | integer | The expiry as a timestamp string or Unix milliseconds, or null for no expiry |
| emoji_id?3 | ?snowflake | The custom emoji to display |
| emoji_name?3 | ?string | The Unicode emoji to display (1-32 characters) |
1 Fluxer measures the length after input normalisation, which turns an empty string into null. Blocklisted text or a blocklisted link is rejected with 403 CONTENT_BLOCKED
2 The value is in the future, and a value at or before the current time is rejected
3 emoji_name is ignored, and not validated, when emoji_id has a value. An emoji_id of null leaves emoji_name in place, and it is then exactly one Unicode emoji
A custom emoji ID that does not resolve fails with CUSTOM_EMOJI_NOT_FOUND against custom_status.emoji_id. Fluxer drops the resolved emoji for an account without the global expression entitlement, so the request succeeds with text alone.
Initial settings
Section titled “Initial settings”A new account starts with these values. Every field not listed starts empty, so there is no custom status and synced_preferences is the empty string.
| Setting | Initial value |
|---|---|
| Theme | The theme chosen at registration, or system |
| Status | online |
| Rendering | Animated custom emoji, always-animated stickers, GIF autoplay, embeds and reactions rendered, spoilers on click, inline attachment and embed media |
| Incoming calls and group DM additions | Friends only |
| Guild DM restrictions | Unrestricted for both members and bots |
| Guild folders | One empty uncategorised folder |
| AFK timeout | 600 seconds |
| Time format | Automatic |
| Trusted domains | None |
| Profile privacy | Visible to all guild members |
| Voice activity sharing | Enabled |
| Friend sources | Mutual friends and mutual guilds, plus no relation for a verified adult |
| Sensitive media filters | Show for a verified adult and blur otherwise on friend DMs, block on non-friend DMs, blur in guilds |
| Developer mode | Enabled in development, disabled elsewhere |
Get current user settings
Section titled “Get current user settings”GET/v1/users/@me/settingsReturns the user settings object.
An account with an outstanding required action can still call this route. An account with no stored settings record returns 404 UNKNOWN_USER.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | user settings object | Settings were returned |
| 404 | error response | Settings do not exist and the request returns UNKNOWN_USER |
Rate limit
Section titled “Rate limit”40 requests per 10 seconds for each authenticated user, on the user:settings:get bucket shared with Get current user.
Modify current user settings
Section titled “Modify current user settings”PATCH/v1/users/@me/settingsModifies the account-wide settings and returns the complete user settings object. Emits a User Settings Update Gateway event.
An account with no stored settings record returns 404 UNKNOWN_USER. A locale change additionally emits a User Update Gateway event.
An unresolvable custom status emoji returns 400 INVALID_FORM_BODY with CUSTOM_EMOJI_NOT_FOUND against custom_status.emoji_id. The trusted domain, age restriction, and synced preferences decisions return 400 VALIDATION_ERROR with their own codes in errors.
JSON body
Section titled “JSON body”The body uses the user settings update object.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | user settings object | Settings were applied and returned |
| 400 | error response | A field value, the custom status emoji, the trusted domain combination, an age-restricted filter, or the synced preferences snapshot is invalid |
| 403 | error response | Custom status text is blocked and the request returns CONTENT_BLOCKED |
| 404 | error response | Settings do not exist and the request returns UNKNOWN_USER |
Side effects
Section titled “Side effects”Fluxer emits User Settings Update to the caller’s own sessions. A value-identical patch still performs the write and produces the Dispatch. A locale change also applies to email and notification localisation and emits User Update. The user object has no locale member.
Every User Settings Update republishes the caller’s current Presence Update to eligible sessions, so a custom status change becomes visible without a further request.
A status of invisible forces every one of the caller’s sessions to invisible. A later status of online, idle, or dnd releases them, and it does so only when at least one session is currently invisible.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user, on the user:settings:update bucket shared with Modify voice activity sharing.
Modify voice activity sharing
Section titled “Modify voice activity sharing”PUT/v1/users/@me/settings/voice-activity-sharingChanges the default voice activity sharing value, applies it to the caller’s side of every existing friendship, and returns the caller’s user object. Emits Relationship Update and User Update Gateway events, and a User Settings Update Gateway event only when the stored default changes.
A missing account or settings record returns 404 UNKNOWN_USER.
This operation owns default_share_voice_activity, which is read-only in the user settings object.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| share_voice_activity | boolean | Whether voice activity is shared, stored as the new default and applied to the caller’s side of every friendship |
Outside the window the cooldown restarts on every accepted request, including one that sets the value it already holds. The user object has that moment as last_voice_activity_sharing_change_at.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | user object | Sharing state was returned after applying the request |
| 400 | error response | The 24-hour cooldown remains active and the request returns INVALID_FORM_BODY |
| 404 | error response | The account or its settings do not exist and the request returns UNKNOWN_USER |
Side effects
Section titled “Side effects”An accepted request writes default_share_voice_activity and then walks every friendship. A friendship whose caller-side value already equals the submitted value is skipped, and its stored version does not advance. Every friendship, skipped or rewritten, produces one Relationship Update to the caller and one to the friend, so re-sending the current value still fans the full set out. The friend’s Dispatch is emitted only when the reciprocal friendship exists.
It then records the change time in last_voice_activity_sharing_change_at and emits User Update to the caller.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user, on the user:settings:update bucket shared with Modify current user settings.
Modify DM notification settings
Section titled “Modify DM notification settings”PATCH/v1/users/@me/guilds/@me/settingsModifies and returns the user guild settings object that governs direct messages and group DMs. Emits a User Guild Settings Update Gateway event on every success.
Fluxer creates the settings with the documented defaults when they are absent.
JSON body
Section titled “JSON body”The body uses the guild settings update fields.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | user guild settings object | DM settings were returned after applying the request |
Side effects
Section titled “Side effects”The private channel settings are returned with guild_id null. Fluxer performs the write and emits the Dispatch to the caller’s own sessions even when the request changes nothing, and version advances on that write. No other account receives a Dispatch.
Rate limit
Section titled “Rate limit”30 requests per 10 seconds for each authenticated user, on the user:guild_settings:update bucket shared with Modify guild notification settings.
Modify guild notification settings
Section titled “Modify guild notification settings”PATCH/v1/users/@me/guilds/{guild_id}/settingsModifies and returns the user guild settings object for the supplied guild ID. Emits a User Guild Settings Update Gateway event on every success.
Fluxer creates the settings with the documented defaults when they are absent.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The guild settings key |
JSON body
Section titled “JSON body”The body uses the guild settings update fields.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | user guild settings object | Guild settings were returned after applying the request |
Side effects
Section titled “Side effects”Fluxer performs the write and emits the Dispatch to the caller’s own sessions even when the request changes nothing, and version advances on that write. No guild member other than the caller receives a Dispatch.
Rate limit
Section titled “Rate limit”30 requests per 10 seconds for each authenticated user, on the user:guild_settings:update bucket shared with Modify DM notification settings.