The synced_preferences field of the user settings object is a base64-encoded fluxer.user.preferences.v1.SyncedPreferences message with the client preferences an account shares between its devices. The API stores the snapshot and doesn't act on any field in it. The schema is in packages/schema/proto/fluxer/user/preferences/v1.
Modify current user settings replaces the whole snapshot. To change one preference, decode the stored snapshot, change it and send all of it back. Sending null or the empty string clears it, and the API returns the empty string when nothing is stored. Each change goes to every session of the account in User Settings Update.
The API accepts standard or URL-safe base64, with or without padding, and returns standard base64 with padding. The API re-encodes what you send and keeps unknown fields. A snapshot with only default values comes back as the empty string.
An invalid snapshot returns 400 with errors at the path synced_preferences.
| Condition | Status and code | Element codes |
|---|
| Encoded string longer than 699052 characters | 400 INVALID_FORM_BODY | CONTENT_EXCEEDS_MAX_LENGTH and INVALID_FORMAT |
| Encoded string outside the base64 alphabet | 400 INVALID_FORM_BODY | INVALID_FORMAT |
| Decoded message above 524288 bytes (512 KiB) | 400 VALIDATION_ERROR | TOO_LARGE |
Bytes that don't decode as SyncedPreferences | 400 VALIDATION_ERROR | INVALID_FORMAT |
A field marked ? is absent until a client sets it. Every other scalar field is 0, false or empty when unset. An enumeration field has the type int32 and links to its values.
SyncedPreferences is the root message.
Display, motion, message, media, voice and interaction preferences.
| Field | Type | Description |
|---|
| saturation_factor? | double | Color saturation multiplier, where 1 is unchanged |
| always_underline_links | bool | Whether links are always underlined |
| enable_text_selection? | bool | Whether message text can be selected |
| show_message_send_button? | bool | Whether the composer shows a send button |
| show_textarea_focus_ring? | bool | Whether the composer shows a focus ring |
| hide_keyboard_hints | bool | Whether keyboard shortcut hints are hidden |
| escape_exits_keyboard_mode? | bool | Whether Escape exits keyboard navigation mode |
| sync_reduced_motion_with_system? | bool | Whether reduced motion follows the operating system |
| reduced_motion_override? | bool | Reduced motion setting, used when it doesn't follow the operating system |
| message_group_spacing? | double | Spacing between message groups in CSS pixels |
| message_gutter? | double | Message gutter width in CSS pixels |
| font_size? | double | Message font size in CSS pixels |
| show_user_avatars_in_compact_mode? | bool | Whether compact mode shows avatars |
| mobile_sticker_animation_overridden | bool | Whether the mobile sticker animation value is used |
| mobile_gif_autoplay_overridden | bool | Whether the mobile GIF autoplay value is used |
| mobile_animate_emoji_overridden | bool | Whether the mobile emoji animation value is used |
| mobile_sticker_animation_value? | int32 | Mobile sticker animation setting |
| mobile_gif_autoplay_value? | bool | Mobile GIF autoplay |
| mobile_animate_emoji_value? | bool | Mobile emoji animation |
| auto_send_klipy_gifs | bool | Whether picking a GIF sends it immediately |
| show_gif_button? | bool | Whether the composer shows the GIF button |
| show_memes_button? | bool | Whether the composer shows the memes button |
| show_stickers_button? | bool | Whether the composer shows the sticker button |
| show_emoji_button? | bool | Whether the composer shows the emoji button |
| show_media_favorite_button? | bool | Whether media shows the favorite button |
| show_media_download_button? | bool | Whether media shows the download button |
| show_media_delete_button? | bool | Whether media shows the delete button |
| show_suppress_embeds_button? | bool | Whether messages show the suppress embeds button |
| show_gif_indicator? | bool | Whether GIFs show a GIF indicator |
| show_attachment_expiry_indicator? | bool | Whether attachments show their expiry indicator |
| use_browser_locale_for_time_format? | bool | Whether times use the browser locale |
| channel_typing_indicator_mode | int32 | Channel typing indicator mode |
| show_selected_channel_typing_indicator? | bool | Whether the selected channel shows its typing indicator |
| show_message_action_bar? | bool | Whether messages show the action bar |
| show_message_action_bar_quick_reactions? | bool | Whether the action bar shows quick reactions |
| show_message_action_bar_shift_expand? | bool | Whether holding Shift expands the action bar |
| show_message_action_bar_only_more_button? | bool | Whether the action bar shows only the more button |
| show_default_emojis_in_autocomplete? | bool | Whether autocomplete includes standard emoji |
| show_custom_emojis_in_autocomplete? | bool | Whether autocomplete includes custom emoji |
| show_stickers_in_autocomplete? | bool | Whether autocomplete includes stickers |
| show_memes_in_autocomplete? | bool | Whether autocomplete includes memes |
| voice_channel_join_requires_double_click? | bool | Whether joining a voice channel needs a double click |
| custom_theme_css? | string | CSS of the synced custom theme |
| show_favorites? | bool | Whether the favorites section is shown |
| zoom_level? | double | App zoom multiplier, where 1 is unscaled |
| dm_message_preview_mode | int32 | Direct message preview mode |
| enable_tts_command? | bool | Whether the text-to-speech command is on |
| tts_rate? | double | Text-to-speech rate multiplier, where 1 is normal |
| show_faded_unread_on_muted_channels? | bool | Whether muted channels show a faded unread indicator |
| show_context_menu_shortcuts? | bool | Whether context menus show keyboard shortcuts |
| confirm_before_starting_calls? | bool | Whether starting a call asks for confirmation |
| hdr_display_mode | int32 | HDR display mode |
| preserve_edit_draft? | bool | Whether canceling an edit keeps its draft |
| stay_interactive_when_unfocused? | bool | Whether animation and interaction continue while the app is unfocused |
| confirm_before_joining_voice_channels? | bool | Whether joining a voice channel asks for confirmation |
| screen_reader_announce_new_messages? | bool | Whether a screen reader announces new messages |
| first_click_pass_through_when_unfocused? | bool | Whether the first click on an unfocused app also activates the control |
| compact_message_group_spacing? | double | Spacing between compact message groups in CSS pixels |
| scroll_to_bottom_on_message_send? | bool | Whether sending a message scrolls to the bottom |
| dim_strikethrough_text? | bool | Whether strikethrough text is dimmed |
| sequential_file_send? | bool | Whether multiple files are sent one message at a time |
| mobile_splash_zoom_animation? | bool | Whether the mobile splash screen plays its zoom animation |
| message_double_click_actions? | bool | Whether double-clicking a message edits your own message or replies to others |
| Value | Name | Description |
|---|
| 0 | CHANNEL_TYPING_INDICATOR_MODE_UNSPECIFIED | No mode is set |
| 1 | CHANNEL_TYPING_INDICATOR_MODE_AVATARS | Show typing users as avatars |
| 2 | CHANNEL_TYPING_INDICATOR_MODE_INDICATOR_ONLY | Show the indicator without avatars |
| 3 | CHANNEL_TYPING_INDICATOR_MODE_HIDDEN | Hide the indicator |
| Value | Name | Description |
|---|
| 0 | DM_MESSAGE_PREVIEW_MODE_UNSPECIFIED | No mode is set |
| 1 | DM_MESSAGE_PREVIEW_MODE_ALL | Preview all direct messages |
| 2 | DM_MESSAGE_PREVIEW_MODE_UNREAD_ONLY | Preview only unread direct messages |
| 3 | DM_MESSAGE_PREVIEW_MODE_NONE | Hide previews |
| Value | Name | Description |
|---|
| 0 | HDR_DISPLAY_MODE_UNSPECIFIED | No mode is set |
| 1 | HDR_DISPLAY_MODE_FULL | Show HDR media at full range |
| 2 | HDR_DISPLAY_MODE_STANDARD | Limit HDR media to standard dynamic range |
| Field | Type | Description |
|---|
| gif_autoplay_dirty | bool | GIF autoplay dirty flag |
| animate_emoji_dirty | bool | Emoji animation dirty flag |
| animate_stickers_dirty | bool | Sticker animation dirty flag |
Line wrapping in the inline preview of a text attachment.
| Field | Type | Description |
|---|
| wrap_text | bool | Whether long lines wrap |
How often and how recently one emoji, sticker or meme was used.
| Field | Type | Description |
|---|
| count | uint32 | Number of uses |
| last_used_ms | int64 | Unix time in milliseconds of the last use |
Emoji usage, favorites and collapsed categories. Fluxer clients key emoji as unicode:<name> or custom:<guild id>:<emoji id>.
| Field | Type | Description |
|---|
| usage | map[string, usage stat object] | Usage keyed by emoji key |
| favorite_emoji_ids | array[string] | Favorite emoji keys in display order |
| collapsed_category_ids | array[string] | Collapsed category IDs |
Sticker usage, favorites and collapsed categories.
| Field | Type | Description |
|---|
| usage | map[string, usage stat object] | Usage keyed by sticker ID |
| favorite_sticker_ids | array[string] | Favorite sticker IDs in display order |
| collapsed_category_ids | array[string] | Collapsed category IDs |
Meme usage, favorites and collapsed categories. The memes are in the account's memes.
| Field | Type | Description |
|---|
| usage | map[string, usage stat object] | Usage keyed by meme ID |
| favorite_meme_ids | array[string] | Favorite meme IDs in display order |
| collapsed_category_ids | array[string] | Collapsed category IDs |
| Field | Type | Description |
|---|
| skin_tone | string | Unicode skin tone modifier (U+1F3FB to U+1F3FF), or empty for the default |
| Value | Name | Description |
|---|
| 0 | EMOJI_PICKER_LAYOUT_UNSPECIFIED | No layout is set |
| 1 | EMOJI_PICKER_LAYOUT_LIST | List layout |
| 2 | EMOJI_PICKER_LAYOUT_GRID | Grid layout |
| Value | Name | Description |
|---|
| 0 | STICKER_PICKER_VIEW_MODE_UNSPECIFIED | No view mode is set |
| 1 | STICKER_PICKER_VIEW_MODE_COZY | Roomy layout |
| 2 | STICKER_PICKER_VIEW_MODE_COMPACT | Compact layout |
Fluxer clients keep favorite GIFs here, or in the account's memes when save_as_saved_media is true.
| Field | Type | Description |
|---|
| entries | array[favorite GIF entry object] | Favorite GIFs in display order |
| save_as_saved_media | bool | Whether favoriting a GIF saves it as a meme |
| seen_first_time_prompt | bool | Whether the first-time favorite prompt was shown |
One favorite GIF, in the same format as a resolved GIF entry.
| Field | Type | Description |
|---|
| url | string | Source URL of the GIF |
| proxy_url | string | Media Proxy URL of the preview |
| width | uint32 | Preview width in pixels, or 0 if unknown |
| height | uint32 | Preview height in pixels, or 0 if unknown |
| media | map[string, favorite GIF media format object] | Formats keyed by format name |
| content_type | string | Media type of the preview, or empty for image/gif |
| placeholder | string | Thumbhash placeholder, or empty |
One encoding of a favorite GIF, in the same format as a GIF media format.
| Field | Type | Description |
|---|
| src | string | Direct URL of this format |
| proxy_src | string | Media Proxy URL of this format |
| width | uint32 | Width in pixels |
| height | uint32 | Height in pixels |
Favorite channels and the categories they're grouped in. They aren't guild categories.
| Field | Type | Description |
|---|
| channels | array[favorite channel object] | Favorite channels |
| categories | array[favorite category object] | Favorite categories |
| collapsed_category_ids | array[string] | Collapsed favorite category IDs |
| hide_muted_channels | bool | Whether muted channels are hidden |
| muted | bool | Whether favorites are muted |
| Field | Type | Description |
|---|
| channel_id | string | The ID of the channel |
| guild_id | string | The ID of the guild |
| parent_id? | string | The id of the favorite category it's in |
| position | int32 | Position in the favorites list |
| nickname? | string | Nickname the user gave the channel |
| Field | Type | Description |
|---|
| id | string | Category ID chosen by the client, not a snowflake |
| name | string | Category name |
| position | int32 | Category position |
| Field | Type | Description |
|---|
| include_everyone? | bool | Whether to include @everyone mentions (true when absent) |
| include_roles? | bool | Whether to include role mentions (true when absent) |
| include_guilds? | bool | Whether to include mentions in guild channels (true when absent) |
| Field | Type | Description |
|---|
| inline_dms_collapsed | bool | Whether the inline direct message section is collapsed |
| show_collapsed_unread_dms_badge? | bool | Whether the collapsed section shows an unread badge (true when absent) |
| show_incoming_friend_request_badge? | bool | Whether the sidebar shows a friend request badge (true when absent) |
| Field | Type | Description |
|---|
| members_open? | bool | Whether the member list is open |
| Field | Type | Description |
|---|
| collapsed_channel_ids | array[string] | IDs of collapsed channels in the unread view |
How often and how recently the account mentioned each user, per guild, for ranking mention autocomplete.
The mention records for one guild, declared as MentionFrecencyState.Scope.
| Field | Type | Description |
|---|
| guild_id | string | The ID of the guild |
| entries | array[mention frecency entry object] | Mention records for the guild |
Mentions of one user, declared as MentionFrecencyState.Entry.
| Field | Type | Description |
|---|
| user_id | string | The ID of the mentioned user |
| count | uint32 | Number of mentions |
| last_at_ms | int64 | Unix time in milliseconds of the last mention |
How often and how recently the account opened each channel.
| Field | Type | Description |
|---|
| total_uses | uint32 | Number of uses |
| recent_uses_ms | array[int64] | Unix times in milliseconds of recent uses |
Each field is true when the account dismissed that notice. In the map fields, a missing key means the notice wasn't dismissed.
| Field | Type | Description |
|---|
| ios_install | bool | iOS install notice |
| pwa_install | bool | Progressive web app install notice |
| push_notification | bool | Push notification notice |
| desktop_notification | bool | Desktop notification notice |
| premium_grace_period | bool | Premium grace period notice |
| premium_expired | bool | Premium expired notice |
| premium_onboarding | bool | Premium onboarding notice |
| premium_trial_expiring | bool | Premium trial expiring notice |
| gift_inventory | bool | Gift inventory notice |
| desktop_download | bool | Desktop download notice |
| guild_membership_cta | bool | Guild membership notice |
| pending_bulk_deletion | map[string, bool] | Pending bulk deletion notices, keyed by deletion ID |
| invites_disabled | map[string, bool] | Disabled invites notices, keyed by guild ID |
| guild_mfa_requirement | map[string, bool] | Guild MFA requirement notices, keyed by guild ID |
| Field | Type | Description |
|---|
| picker_premium | bool | Whether the premium upsell in the picker is dismissed |
The guilds, categories and channels where the account accepted the mature content notice, each accepted separately.
| Field | Type | Description |
|---|
| agreed_channel_ids | array[string] | Channel IDs |
| agreed_guild_ids | array[string] | Guild IDs |
| agreed_category_ids | array[string] | Category IDs |
| Field | Type | Description |
|---|
| last_dismissed_entry_id? | string | ID of the last dismissed update entry |
These preferences don't change the privacy fields of the user settings object.
| Field | Type | Description |
|---|
| disable_stream_previews | bool | Whether the client stops uploading stream preview frames |
| show_active_now? | bool | Whether the active now view is shown |
| preupload_message_attachments? | bool | Whether attachments upload before the message is sent |
Overrides for how the client shows the SPAMMER public user flag. They change only the display, and not_spammer_user_ids wins over both the other list and the flag.
| Field | Type | Description |
|---|
| spammer_user_ids | array[string] | User IDs shown as spammers |
| not_spammer_user_ids | array[string] | User IDs shown as not spammers |
Volumes are percentages from 0 to 200, where 100 is the default.
| Field | Type | Description |
|---|
| all_sounds_disabled | bool | Whether all sounds are off |
| master_volume? | double | Master volume |
| disabled_sounds | map[string, bool] | Disabled sounds keyed by sound identifier |
| sound_overrides | map[string, double] | Volume per sound, keyed by sound identifier |
The API accepts any key. Fluxer clients use these.
| Value | Description |
|---|
| deaf | Deafen |
| undeaf | Undeafen |
| mute | Mute |
| unmute | Unmute |
| message | Message notification |
| direct-message | Direct message notification |
| same-channel-message | Message in the channel you're viewing |
| incoming-ring | Incoming call |
| user-join | Someone joins voice |
| user-leave | Someone leaves voice |
| user-move | Someone is moved in voice |
| viewer-join | Stream viewer joins |
| viewer-leave | Stream viewer leaves |
| voice-disconnect | Voice disconnects |
| camera-on | Camera on |
| camera-off | Camera off |
| screen-share-start | Screen share starts |
| screen-share-stop | Screen share stops |
| Field | Type | Description |
|---|
| enabled? | bool | Whether spellcheck is on |
| languages | array[string] | Spellcheck languages |
| personal_dictionary | array[string] | Words in the personal dictionary |
| auto_detect? | bool | Whether languages are detected automatically |
| engine? | string | Spellcheck engine (auto, system or hunspell) |
Provider IDs that the client defines.
| Field | Type | Description |
|---|
| text_search_engine_id? | string | Text search engine |
| reverse_image_search_engine_id? | string | Reverse image search engine |
| translation_provider_id? | string | Translation provider |
Layout of the permission editor.
| Value | Name | Description |
|---|
| 0 | PERMISSION_LAYOUT_MODE_UNSPECIFIED | No layout is set |
| 1 | PERMISSION_LAYOUT_MODE_COMFY | Roomy layout |
| 2 | PERMISSION_LAYOUT_MODE_DENSE | Dense layout |
| Value | Name | Description |
|---|
| 0 | PERMISSION_GRID_MODE_UNSPECIFIED | No grid mode is set |
| 1 | PERMISSION_GRID_MODE_SINGLE | One category at a time |
| 2 | PERMISSION_GRID_MODE_GRID | Categories in a grid |
| Value | Name | Description |
|---|
| 0 | GUILD_MEMBER_VIEW_MODE_UNSPECIFIED | No view mode is set |
| 1 | GUILD_MEMBER_VIEW_MODE_TABLE | Table |
| 2 | GUILD_MEMBER_VIEW_MODE_GRID | Grid |
The folders themselves are guild_folders on the user settings object.
| Field | Type | Description |
|---|
| expanded_folder_ids | array[fixed64] | IDs of expanded guild folders |
| Field | Type | Description |
|---|
| download_button | bool | Whether the download button is hidden |
| help_button | bool | Whether the help button is hidden |
| Field | Type | Description |
|---|
| seen | bool | Whether the keyboard navigation introduction was shown |
| Field | Type | Description |
|---|
| seen_cta | bool | Whether the input monitoring prompt was shown |
Voice confirmations the account chose to skip.
| Field | Type | Description |
|---|
| skip_hide_own_camera_confirm | bool | Skip confirming before hiding your own camera |
| skip_hide_own_screenshare_confirm | bool | Skip confirming before hiding your own screen share |
| skip_p2p_join_confirm | bool | Skip confirming before joining a peer-to-peer call |
| Field | Type | Description |
|---|
| hide_publish_nudge | bool | Whether the prompt to publish in an announcement channel is hidden |
The verification method used last for sudo mode, which clients preselect next time.
| Field | Type | Description |
|---|
| last_used_mfa_method? | int32 | MFA method |
| Value | Name | Description |
|---|
| 0 | MFA_METHOD_UNSPECIFIED | No method is recorded |
| 1 | MFA_METHOD_TOTP | Authenticator app (totp) |
| 3 | MFA_METHOD_WEBAUTHN | Security key or passkey (webauthn) |
| Field | Type | Description |
|---|
| custom_keybinds | array[custom keybind object] | Custom keybinds |
| transmit_mode | string | voice_activity (default) or voice_push_to_talk |
| push_to_talk_release_delay_ms? | uint32 | Push-to-talk release delay in milliseconds (20-2000) |
| Field | Type | Description |
|---|
| id | string | Keybind ID chosen by the client |
| action? | string | Action the client runs |
| combo? | keybind combo object | Input combination |
| enabled | bool | Whether the keybind is on |
The key, modifiers and buttons that trigger a keybind.
| Field | Type | Description |
|---|
| key | string | Key value |
| code? | string | Physical key code |
| ctrl_or_meta | bool | Whether Meta on macOS or Control elsewhere is needed |
| ctrl | bool | Whether Control is needed |
| alt | bool | Whether Alt is needed |
| shift | bool | Whether Shift is needed |
| meta | bool | Whether Meta is needed |
| global? | bool | Whether the combination works when the app is unfocused |
| enabled? | bool | Ignored for custom keybinds, which use the keybind's own enabled |
| modifier_only | bool | Whether the combination is only modifier keys |
| both_sides | bool | Whether either side of a paired modifier works |
| mouse_button? | uint32 | Mouse button number |
| gamepad_button? | uint32 | Gamepad button number |
| Field | Type | Description |
|---|
| convert_emoticons? | bool | Whether emoticons turn into emoji |
The same format as the reaction emoji object.
| Field | Type | Description |
|---|
| id? | string | The ID of a custom emoji, absent for a Unicode emoji |
| name | string | The Unicode emoji, or the custom emoji's name |
What a double tap on a message does on mobile.
| Value | Name | Description |
|---|
| 0 | DOUBLE_TAP_ACTION_UNSPECIFIED | No action is set, which Fluxer clients treat as react |
| 1 | DOUBLE_TAP_ACTION_REACT | React with double_tap_reaction |
| 2 | DOUBLE_TAP_ACTION_EDIT | Edit the message if it's your own |
| 3 | DOUBLE_TAP_ACTION_NONE | Do nothing |
What a right to left swipe in a channel does on mobile.
| Value | Name | Description |
|---|
| 0 | SWIPE_ACTION_UNSPECIFIED | No action is set |
| 1 | SWIPE_ACTION_CHANNEL_DETAILS | Open the channel details |
| 2 | SWIPE_ACTION_REPLY | Reply to the message |