Skip to content
Fluxer API

Instance

Discover a deployment’s endpoints, available features, and limits, look up the client’s approximate location, download its OpenAPI document, or choose how members of a new deployment sign in.

Get instance discovery is the entry point of the API. A client that knows only a Fluxer origin reads /.well-known/fluxer first, and that one unauthenticated response has every field of the instance discovery object. Those values include the API base URLs, the main Gateway WebSocket URL, and the Media Proxy base URL. They override the endpoint path defaults a deployment would otherwise serve from its canonical public origin.

Every route here is unauthenticated. A credential changes no response body. One that resolves to an account moves the rate limit bucket from the client IP address onto that account.

Each GET route answers with Access-Control-Allow-Origin: *, replaced by the request Origin when the deployment-wide cross-origin policy allows that origin. The Admin Instance API defines the operator side of the same configuration.

The discovery document is the complete public description of one deployment. Every field without a ? is always present. This server never sends codename or age_policy, and domain_migration and endpoints.upload_relay are absent only from a server older than this version.

FieldTypeDescription
codename?stringThe protocol generation the deployment speaks
api_code_version1integerThe version of the API server code this deployment runs
endpointsinstance endpoints objectPublic service endpoints for this deployment
captchacaptcha configuration objectPublic CAPTCHA configuration
featuresinstance features objectPublic deployment feature state
gifGIF provider objectThe active GIF provider and its attribution requirement
ssoSSO status objectPublic single sign-on state
registrationregistration policy objectPublic registration policy
communitycommunity policy objectCommunity defaults and direct message policy
servicesservice availability objectResolved third-party integration availability
limitslimit configuration objectOrdered limit rules and the trait names the deployment declares
pushpush configuration objectPublic Web Push identity
app_publicpublic application configuration objectPublic client configuration
age_policy?age policy objectRegional age policy for the deployment
domain_migration?domain migration objectWeb domain migration switch and logged-out rollout

1 The value is a plain integer that increases when the API introduces a change a client is expected to notice, and the current value is 1

Each value is an absolute URL supplied by the operator. A value can be a bare origin or an origin with a path prefix, because a deployment can serve several roles from one canonical public origin. A client accepts two endpoints that share an origin and MUST NOT infer a separate host, scheme, or port for any of them.

FieldTypeDescription
api1stringBase URL for authenticated API requests
api_client1stringBase URL for client API requests
api_publicstringBase URL for public API requests
gateway2stringThe main Gateway WebSocket URL
mediastringMedia Proxy base URL
upload_relay?stringAttachment upload relay base URL
static_cdn3stringStatic asset base URL
marketingstringMarketing site base URL
adminstringAdmin application base URL
invitestringInvite link base URL
giftstringGift link base URL
webappstringWeb application base URL
docs?stringDocumentation website base URL

1 Both fields are the same configured client API endpoint, which the first-party web application reads. api_public is the separately configured public API endpoint, which a bot, a library, or any other third-party client reads. A deployment can point the two at one origin, and the instance Fluxer hosts does not

2 The value is the configured Gateway endpoint and its scheme is ws or wss as the operator configured it

3 When a deployment configures a separate static asset domain, the value is https:// followed by that domain, with no port

Every value is the exact origin the deployment advertises, including its scheme and any explicit port, and a deliberately plain HTTP deployment publishes http and ws values here.

The operator configures one canonical public origin with an exact http or https scheme, a host, and an optional explicit port. The web application is served at that origin itself, and the other endpoints default to a path under it:

EndpointDefault path
HTTP API/api
Media Proxy/media
Admin application/admin
Marketing site/marketing
Invite links/invite
Gift links/gift
Gateway/gateway

The Gateway scheme is ws or wss. A port that equals the default for its scheme is omitted.

A deployment can configure a separate static asset domain, invite domain, and gift domain, and it can replace any single endpoint with an exact override.

{
"api": "https://api.example.com",
"api_client": "https://api.example.com",
"api_public": "https://public.example.com",
"gateway": "wss://gateway.example.com",
"media": "https://media.example.com",
"static_cdn": "https://cdn.example.com",
"marketing": "https://example.com",
"admin": "https://admin.example.com",
"invite": "https://example.com/invite",
"gift": "https://example.com/gift",
"webapp": "https://app.example.com"
}

Whether this deployment asks for a CAPTCHA on gated operations.

FieldTypeDescription
providerstringThe CAPTCHA provider in use
ValueDescription
altchaAn ALTCHA proof-of-work challenge gates the operations that require one
noneThe deployment requires no CAPTCHA

The complete challenge handshake, including the X-Captcha-Token request header, is defined in CAPTCHA handling.

Deployment-wide switches a client reads before it offers a feature, plus whether the deployment calls itself self-hosted.

FieldTypeDescription
voice_enabledbooleanWhether voice and video calling is enabled
stripe_enabled2booleanWhether premium purchases through Stripe billing are available
premium_enabled3booleanWhether the deployment has a premium tier, so premium state, gifts and perks apply
stripe_serviceable4booleanWhether existing Stripe subscriptions can be managed, cancelled and billed
self_hostedbooleanWhether this deployment identifies itself as self-hosted
presigned_attachment_uploadsbooleanWhether a client can request presigned attachment upload URLs
emails_enabled1booleanWhether the deployment sends email
phone_verification_enabledbooleanDeprecated. Always false
account_identity5stringHow members sign in, one of the account identity modes
tag_style6stringHow usernames are tagged, one of the tag styles
desktop_modules_enabled?booleanWhether desktop clients may load downloadable modules
account_deletion_grace_period_hours?integerHours between a deletion request and the permanent deletion of the account (1-8,760)
max_background_gateway_connections?integerMaximum Gateway connections a client may keep open for background accounts (0-64)

1 The value is true only when email is switched on and the transport is completely configured. It is always false on a username deployment

2 True only when billing is switched on, a Stripe secret key is set, at least one currency has both a monthly and a yearly price, and premium_enabled is true. It is computed on each request

3 Always true on a hosted deployment. A self-hosted deployment reports true only while its premium mode is mirror

4 On a hosted deployment, true while billing is switched on and a Stripe secret key is set. A self-hosted deployment reports true while a Stripe secret key is set and premium_enabled is true, even after billing is switched off

5 Always email on a hosted deployment. A client treats a missing value as email, which is what a deployment from before the field existed means

6 Always none on a username deployment. Always random on a hosted deployment and on an instance that existed before the field. A client treats a missing value as random

A deployment that reports emails_enabled as false sends no verification, password recovery, or IP authorisation message, and the flows that depend on one are unusable there. Deployment availability states which routes a self-hosted deployment does not serve at all.

ValueDescription
emailMembers register and sign in with an email address
usernameMembers register and sign in with a username, and the deployment collects no email address
ValueDescription
noneUsernames are unique and shown without a tag. Every account that is not a bot has the discriminator 0000
randomEvery account gets a random tag. Tags are shown and can be changed

A username deployment answers its email routes with 400 EMAIL_UNAVAILABLE_ON_INSTANCE. Authentication and Email and password changes list them. Routes that exist only for username sign-in, such as recover an account, answer 400 USERNAME_SIGN_IN_ONLY on an email deployment.

The GIF provider this deployment has bound, and whether a client shows its attribution mark.

FieldTypeDescription
providerstringStable machine name of the active GIF provider
display_namestringHuman-readable provider name a client shows
attribution_required1booleanWhether a client shows the provider attribution

1 A client that renders GIF results displays the provider’s attribution mark alongside them when this value is true

The fields describe the provider a deployment has bound even when service availability reports gif_enabled as false. A client reads gif_enabled to decide whether to offer the picker at all. A deployment that has bound no GIF provider still publishes the stock values klipy, Klipy, and false.

Who can register an account on this deployment.

FieldTypeDescription
modestringThe registration mode
admin_registration_urls_enabled1booleanWhether an administrator-issued registration URL code is accepted

1 When true, Register an account accepts registration_url_code, a valid code admits registration even while mode is closed, and the code’s own approval requirement replaces the one the mode would set

ValueDescription
openAnyone can register and receives a session immediately
approvalRegistration succeeds but the account waits for administrator approval before it can sign in
closedPublic registration is refused

Whether this deployment runs as one community, and whether direct messages exist on it at all.

FieldTypeDescription
single_communitybooleanWhether this deployment runs as one community that every account joins
single_community_guild_id1?snowflakeThe ID of the guild every account joins in single-community mode, or null
direct_messages_disabledbooleanWhether direct messages and friend requests are disabled for the whole deployment
guild_create_accessbooleanWhether every account can create communities, or only admins and holders of the feature_guild_create limit

1 The identifier is published only while single_community is true and the deployment has designated a community guild

Each field reports whether one optional integration is available on this deployment.

FieldTypeDescription
gif_enabledbooleanWhether the GIF picker is available
youtube_enabledbooleanWhether YouTube link enrichment is available
bluesky_enabledbooleanWhether Bluesky connections are available

This deployment’s public Web Push identity.

FieldTypeDescription
public_vapid_key1?stringThe deployment’s Web Push VAPID public key, or null
delivery_mode?stringHow push notifications reach devices, one of direct, external_relay, or hybrid
event_resolution_path?stringAPI path a client calls to resolve the payload of a push event
external_relay_url??stringURL of the external push relay, or null when there is none
relay_signing_key_hashes??array[string]Hashes of the keys the external push relay signs with, or null

1 Null when the deployment has configured no Web Push identity

The ordered rules a client evaluates to work out the limits that apply to an account or a guild.

FieldTypeDescription
versionintegerThe wire format version, always 2
traitDefinitions1array[string]The trait names this deployment declares
rulesarray[limit rule object]The rules to evaluate
defaultsHash2stringA hash of the release’s built-in default limit values

1 A stock hosted configuration publishes the single name premium, which is computed from the account’s premium state

2 The value is computed from the release’s default limit values alone, so an operator editing a rule leaves it unchanged. It changes when a release changes the defaults, which invalidates a resolution a client cached against the older ones

Each rule publishes only the keys whose values differ from the release defaults. The defaults themselves are not published in this document, so a client MUST hold its own copy of them. Before it resolves anything, a client MUST also rebuild every rule into a full limit map, taking the default value of every limit key and overlaying that rule’s overrides on it.

The client starts from the default value of every key. It evaluates the rules from least specific to most specific, where specificity is the total number of trait and guild feature names in a rule’s filters. Two rules of equal specificity keep their published order. A rule matches when every trait it names is present in the evaluation context and every guild feature it names is present.

A rule that names no trait and no guild feature replaces the current value for each key it has. A rule that names at least one raises the current value to its own value when that is higher. Because a rebuilt rule has every key, an unfiltered rule returns each key it did not override to the default. A matching filtered rule raises each key it did not override to at least the default.

The evaluation contexts are listed below. A client reads the key’s scope and the rule’s filters to decide which keys an evaluation applies. The limit key registry states the scope of each key.

ScopeUser evaluationGuild evaluation
userAppliedApplied only when the rule has no guild feature filter
guildNot appliedApplied when the rule has a guild feature filter, or when the rule has no trait filter at all
bothAppliedApplied

Nothing validates a rule’s traits filter against traitDefinitions, so a rule can filter on a name that collection omits. A self-hosted deployment whose premium mode is everyone publishes an empty collection and has no rule that filters on premium.

One rule of the limit configuration, with the filters that select it and the values it sets.

FieldTypeDescription
idstringThe stable rule identifier
filters?limit filters objectThe traits and guild features that select the rule, omitted when the rule always matches
overrides1map[string, integer]Integer values keyed by limit key

1 An entry whose value is negative or is not a finite number is ignored when the rule is applied

{
"id": "premium",
"filters": {"traits": ["premium"]},
"overrides": {
"max_message_length": 4000,
"max_guild_emojis": 250
}
}

The traits and guild features a limit rule requires before it matches.

FieldTypeDescription
traits?array[string]Trait names that must all be present for the rule to match
guildFeatures?array[string]Guild feature names that must all be present for the rule to match

An empty or omitted collection imposes no condition. A rule whose filters object has neither collection always matches, and it replaces each key’s current value exactly as a rule that omits filters does.

Each key names one limit. A key whose name begins with feature_ is a feature gate whose value is 0 when the feature is unavailable and 1 when it is available. Every other key’s value is a bound in the unit named by its description.

ValueDescription
avatar_max_sizeMaximum file size for avatar uploads in bytes, effective up to 104857600, in user scope
emoji_max_sizeMaximum file size for emoji uploads in bytes, effective up to 104857600, in guild scope
feature_animated_avatarAllow animated avatar uploads, in user scope
feature_animated_bannerAllow animated banner uploads, in user scope
feature_custom_discriminatorAllow custom discriminator selection, in user scope. Ignored for people on an instance with the none tag style
feature_custom_notification_soundsAllow custom notification sounds, in user scope
feature_early_accessAccess to beta features, in user scope
feature_global_expressionsUse expressions across all guilds, in user scope
feature_guild_createCreate communities while the instance restricts community creation, in user scope
feature_higher_video_qualityAccess to higher video streaming quality, in user scope
feature_per_guild_profilesDifferent profile per guild, in user scope
feature_voice_entrance_soundsPlay a sound when joining voice, in user scope
max_attachment_file_sizeMaximum size of each attachment file in bytes, in user and guild scope
max_attachments_per_messageMaximum number of file attachments per message, in user and guild scope
max_bio_lengthMaximum characters in a user biography, in user scope. At most 320
max_bookmarksMaximum bookmarked messages, in user scope
max_channels_per_categoryMaximum channels per category, in guild scope
max_custom_backgroundsMaximum custom profile backgrounds, in user scope
max_embeds_per_messageMaximum number of embeds per message, in user and guild scope
max_favorite_meme_tagsMaximum meme tags to track, in user scope
max_favorite_memesMaximum favourited memes, in user scope
max_group_dm_recipientsMaximum members per group direct message, in user scope
max_group_dms_per_userMaximum group direct messages a user can own, in user scope
max_guild_channelsMaximum channels per guild, in guild scope
max_guild_emojisMaximum total emojis per guild, in guild scope
max_guild_emojis_animated1Compatibility alias for older clients, in guild scope
max_guild_emojis_animated_more1Compatibility alias for older clients, in guild scope
max_guild_emojis_static1Compatibility alias for older clients, in guild scope
max_guild_emojis_static_more1Compatibility alias for older clients, in guild scope
max_guild_invitesMaximum active invites per guild, in guild scope
max_guild_membersMaximum members per guild, in guild scope
max_guild_rolesMaximum roles per guild, in guild scope
max_guild_stickersMaximum stickers per guild, in guild scope
max_guild_stickers_more2Compatibility alias for older clients, in guild scope
max_guildsMaximum number of guilds a user can join, in user scope
max_message_lengthMaximum number of characters per message, in user and guild scope
max_private_channels_per_userMaximum direct message channels per user, in user scope
max_reactions_per_messageMaximum distinct reactions per message, in guild scope
max_relationshipsMaximum friend and blocked relationships, in user scope
max_screen_share_bitrateHighest screen share video bitrate in bits per second, from 1000000 to 50000000, in user scope
max_users_per_message_reactionMaximum users who can use the same reaction on a message, in guild scope
max_voice_message_durationMaximum voice message duration in seconds, in user and guild scope
max_webhooks_per_channelMaximum webhooks per channel, in guild scope
max_webhooks_per_guildMaximum webhooks per guild, in guild scope
sticker_max_sizeMaximum file size for sticker uploads in bytes, effective up to 104857600, in guild scope

1 Emoji limits are enforced as one shared total against max_guild_emojis, and the aliases exist only for older clients. The default of each alias equals the max_guild_emojis default

2 Sticker limits are enforced as one shared total against max_guild_stickers

No key sets a thread or forum limit. Thread lifecycle, Thread members, and Forum channel fields state those fixed bounds. max_guild_channels counts forum and media channels and counts no thread.

Where a rule sets max_guild_emojis, max_guild_stickers, or one of the compatibility aliases, it republishes that key in its own overrides even when the value matches the default.

Branding, setup state, legal documents, and registration fields a client reads before an account signs in.

FieldTypeDescription
brandingpublic branding objectPublic instance identity
setuppublic setup state objectInitial configuration state
legalpublic legal configuration objectLegal and policy document URLs
registrationpublic registration fields objectRegistration field collection policy

The instance identity a client renders: its name, its images, its theme colour, its status page links, and the name of its premium tier. The image URLs customise browser metadata, install metadata, and link previews.

FieldTypeDescription
product_namestringThe configured instance name a client displays
icon_url?stringFull application icon URL, or null
symbol_url?stringCompact application symbol URL, or null
logo_url?stringApplication logo URL, or null
wordmark_url?stringApplication wordmark URL, or null
favicon_url?stringBrowser favicon URL, or null
theme_color?stringBrand and browser theme colour as lowercase #rrggbb, or null
status_page_url?stringPublic status page URL, or null
status_page_incident_history_url?stringStatus page incident history URL, or null
premium_product_namestringName of the premium tier a client displays. A self-hosted deployment reports Premium until the operator sets a name
premium_info_url?stringAbsolute URL of a page describing the premium tier, or null

Whether the deployment has finished its initial configuration, and where an operator goes to continue it.

FieldTypeDescription
configuredbooleanWhether initial deployment configuration is complete
admin_url1?stringThe admin application URL used to continue setup, or null
account_identity_locked?booleanWhether the sign-in method can no longer change, sent only while a self-hosted deployment is not configured

1 The value is the deployment’s configured admin endpoint, and it is null when no admin endpoint is configured

account_identity_locked is true once the first account exists, and on a deployment stored as already in use. Set the setup sign-in method returns 409 there.

The public document URLs a client links from its registration form and its report flows.

FieldTypeDescription
terms_url?stringPublic terms of service URL, or null
privacy_url?stringPublic privacy policy URL, or null
guidelines_url1?stringPublic community guidelines URL, or null

1 The URL the operator set. A report flow and the account enforcement emails link it. When it is null, a hosted instance links its own guidelines page, and a self-hosted instance hides every guidelines link

Which extra fields public registration collects.

FieldTypeDescription
collect_date_of_birthbooleanWhether public registration collects and validates a date of birth

The public part of the instance domain migration configuration. The official web client reads it before sign-in to decide whether its legacy origin forwards to the new one. Every instance publishes it, and only the official web client acts on it.

FieldTypeDescription
enabledbooleanWhether the migration runs at all
anonymous_rollout_basis_pointsintegerShare of logged-out devices moved to the new origin, in basis points (0-10000)
rollout_saltstringSalt of the sampling hash, shared by accounts and devices
standalone_forwardingbooleanWhether installed desktop web apps forward to the new origin once their data has moved

enabled is the instance-wide switch. While it is false, no client starts a migration and a client that already migrated stops forwarding from the legacy origin. No passkey update opens, and the passkey bridge keeps working for people already on a new origin.

A logged-out device draws its own random ID once and keeps it. The device moves when its bucket over that ID and rollout_salt falls below anonymous_rollout_basis_points. Signed-in accounts use the domain migration assignment instead.

While standalone_forwarding is false, an installed desktop web app moves its data and stays on the legacy origin. Browser tabs forward either way.

The regions where the deployment gates access behind an age check or blocks it.

FieldTypeDescription
geosarray[age policy region object]Regions with an age policy
FieldTypeDescription
country_codestringThe ISO 3166-1 alpha-2 country code
region_code?stringThe ISO 3166-2 subdivision code, or null when the entry covers the whole country
actionstringrestrict to require an age check, or block to refuse access
card_verification_availablebooleanWhether card age verification is available in the region

The approximate location Fluxer resolved for the request, together with the regions where mature content is gated behind an age check or is unavailable.

FieldTypeDescription
countryCode1 2?stringThe detected ISO 3166-1 alpha-2 country code, or null
regionCode1 2?stringThe detected ISO 3166-2 subdivision code within the country, or null
latitude1 3?stringThe approximate latitude, or null
longitude1 3?stringThe approximate longitude, or null
ageRestrictedGeosarray[geo entry object]Locations where mature content requires an age check
ageBlockedGeosarray[geo entry object]Locations where mature content is unavailable

1 All detected fields are null when the location is unknown. A known location can still omit the subdivision code or coordinates

2 The value is upper case

3 The value is a decimal string

The geo collections are fixed by the release, so they are identical in every response. A client resolves its own country and subdivision from the detected fields and then selects the matching entry itself.

{
"countryCode": "GB",
"regionCode": "ENG",
"latitude": "51.5074",
"longitude": "-0.1278",
"ageRestrictedGeos": [{"countryCode": "US", "regionCode": "TX"}],
"ageBlockedGeos": []
}

A geo entry names a whole country when its regionCode is null and names one subdivision otherwise.

FieldTypeDescription
countryCodestringThe ISO 3166-1 alpha-2 country code
regionCode?stringThe ISO 3166-2 subdivision code within the country, or null when the entry covers the whole country

The sign-in method a new deployment uses after set the setup sign-in method.

FieldTypeDescription
modestringThe account identity mode now in effect
tag_stylestringHow usernames are tagged, one of the tag styles
GET/.well-known/fluxerUnauthenticated

Returns the instance discovery object describing this deployment.

The path has no /v1 prefix.

StatusBodyCondition
200instance discovery objectThe discovery document was returned

60 requests per minute for each authenticated user, or for each client IP address when the request has no credential, on the instance:info bucket. Get OpenAPI document shares this bucket.

GET/v1/ipUnauthenticated

Returns the geolocation object for the request’s client address.

A lookup that resolves nothing still returns 200 with countryCode, regionCode, latitude, and longitude all null. Treat this as an unknown location.

StatusBodyCondition
200geolocation objectThe location was resolved, fully, partly, or not at all

30 requests per minute for each authenticated user, or for each client IP address when the request has no credential, on the ip:geo_lookup bucket.

PUT/v1/instance/setup/account-identityUnauthenticated

Chooses how members sign in on a new self-hosted deployment, and on an email deployment whether usernames have tags. Returns an account identity object with the choice now in effect.

The setup wizard calls this before the owner account exists. The choice stays open on a self-hosted deployment until setup is complete or the first account exists. After that, on a deployment that was already in use before username sign-in existed, and on every hosted deployment, the route returns 409 ACCOUNT_IDENTITY_LOCKED. The choice and the first registration take turns, so a choice never lands after the first account exists. A repeated call while the choice is open replaces the earlier one.

FieldTypeDescription
modestringThe account identity mode to use
tag_style?1stringHow usernames are tagged, one of the tag styles. Defaults to none

1 A username instance always uses none. Sending random with username returns the field code TAG_STYLE_REQUIRES_EMAIL_SIGN_IN on tag_style

StatusBodyCondition
200account identity objectThe mode was stored
400error responseThe body is invalid, or random tags were requested with username
409error responseACCOUNT_IDENTITY_LOCKED, because the sign-in method can no longer change
423error responseGENERAL_ERROR, because a registration or another choice held the turn for more than 15 seconds
429rate limit responseRoute or global bucket denies the request

The deployment stores the choice, and instance discovery reports it as account_identity and tag_style from then on. No Gateway Dispatch is emitted.

10 requests per minute for each authenticated user, or for each client IP address when the request has no credential, on the instance:setup:account_identity bucket.

GET/v1/openapi.jsonUnauthenticated

Returns the deployment’s OpenAPI 3.1 document as JSON with Content-Type: application/json; charset=utf-8.

The document has no ETag. Its server URL is the deployment’s api_client endpoint followed by /v1. Every path is relative to that URL.

StatusBodyCondition
200OpenAPI 3.1 documentThe document was returned

60 requests per minute for each authenticated user, or for each client IP address when the request has no credential, on the instance:info bucket. The allowance is shared with Get instance discovery.