Skip to content
Fluxer API

Admin instance

Instance configuration is everything an operator can change at runtime. It covers single sign-on, Gateway rollout, registration policy, branding and legal links, instance policy, third party integrations, premium billing, media retention, and the ordered limit configuration. The Instance resource serves the subset published to unauthenticated clients.

Every write is a merge over the stored configuration, and an omitted key leaves the stored value unchanged. The limit configuration write is the one exception and replaces the stored document.

Reading configuration requires the Admin ACL instance:config:view, and writing it requires instance:config:update. The limit configuration has its own pair, instance:limit_config:view and instance:limit_config:update.

That relaxation applies only to a session credential, so an Admin API key and a bearer token are evaluated normally even before setup is complete. Completing setup grants the acting session the wildcard ACL. Registration URLs, pending registrations, and limit configuration always need their own ACL.

The complete runtime configuration of the deployment. Every configuration operation here except the limit configuration returns it.

Missing settings use the defaults documented below. Invalid stored configuration causes an error rather than silently resetting a policy. Operators can find recovery guidance under stored instance policy.

FieldTypeDescription
ssoSSO configuration objectSingle sign-on settings
gateway_rolloutGateway rollout configuration objectGateway admission and dispatch tuning
push_relaypush relay configuration objectOperator consent to the Fluxer-run push relay
domain_migrationdomain migration configuration objectWeb domain migration rollout
voice_p2ppeer-to-peer voice configuration objectPeer-to-peer voice rollout
captchacaptcha configuration objectALTCHA proof-of-work captcha settings
experiment_deliveryexperiment delivery configuration objectCadence every client polls the experiments route on
registrationregistration configuration objectRegistration policy, issued URLs, and pending registrations
self_hostedbooleanWhether the deployment runs in self-hosted mode
account_identityaccount identity configuration objectHow members sign in, and whether that can still change
app_publicpublic application configuration objectBranding, legal, setup, and registration field policy
policyinstance policy objectCommunity, direct message, premium, and gating policy
integrationsinstance integrations objectThird party provider settings and their resolved availability
mediainstance media objectAttachment retention settings
billinginstance billing objectPremium billing settings and the state resolved from them

How members of the deployment sign in. It is read-only here. The setup wizard chooses it through set the setup sign-in method, and Sign-in methods explains the rules.

FieldTypeDescription
modestringThe account identity mode in effect, email or username
locked1booleanWhether the mode can no longer change
tag_stylestringHow usernames are tagged, one of the tag styles

1 True on a hosted deployment, and on a self-hosted one once setup is complete or the first account exists

Single sign-on settings for the deployment’s OpenID Connect provider.

FieldTypeDescription
enabledbooleanWhether single sign-on is offered
enforced1booleanWhether single sign-on is the only accepted login method
display_name?stringProvider name shown on the login screen
issuer?stringOpenID Connect issuer
authorization_url?stringAuthorisation endpoint
token_url?stringToken endpoint
userinfo_url?stringUserinfo endpoint
jwks_url?stringJWKS endpoint
client_id?stringRegistered client identifier
client_secret_setbooleanWhether a client secret is stored
scope?stringSpace-separated scope string
allowed_domains2array[string]Email domains permitted to sign in (max 100 entries)
auto_provisionbooleanWhether a first-time sign-in creates an account
redirect_uri3?stringRedirect URI to register with the provider

1 A deployment that has never stored the value reports the same value as enabled

2 Each entry is stored lowercased and IDNA encoded, duplicates are collapsed, and an empty entry is dropped

3 The configured web application endpoint followed by /auth/sso/callback. It is the only redirect URI the provider needs, mobile sign-in included. No operation can set it

Admission and dispatch tuning for the Gateway cluster.

FieldTypeDescription
session_rollout_percentagenumberPercentage of sessions admitted to the new Gateway (0-100, default 100)
session_rollout_modestringmodulo or random (default modulo)
guild_rollout_percentagenumberPercentage of guilds admitted to the new Gateway (0-100, default 100)
rpc_request_timeout_msintegerDeadline for one Gateway RPC (1000-60000, default 10000)
max_concurrent_session_startsintegerSession starts admitted at once (1-10000, default 512)
max_concurrent_guild_startsintegerGuild starts admitted at once (1-10000, default 256)
gateway_dispatch_relay_shardsintegerDispatch relay shard count (1-10000, default 32)
gateway_dispatch_relay_max_queueintegerDispatch relay queue ceiling (0-1000000, default 50000)
voice_e2ee_scopestringguild_feature_only or platform_wide (default guild_feature_only)

Every field is present on read. An absent document or missing field uses the defaults above.

Admin reads and writes name this field rpc_request_timeout_ms. The legacy stored name is covered in the operator configuration reference.

The operator’s consent to the push relay supplemental privacy notice.

FieldTypeDescription
relay_consent_acceptedbooleanWhether the operator accepted the push relay supplemental privacy notice (default false)
relay_consent_accepted_at?stringISO 8601 timestamp of that acceptance, or null when the notice stands unaccepted (default null)
relay_consent_accepted_by?snowflakeAccount that accepted the notice, or null when the notice stands unaccepted (default null)

Every field is present on read. An absent document or missing field uses the defaults above.

The notice covers only the Fluxer-run relay that reaches Apple and Google for the official mobile apps. A subscription whose endpoint points at another distributor, such as a self-hosted UnifiedPush server or ntfy, never reaches that relay and needs no acceptance.

The instance rollout that moves the official web client from its legacy origin to a new one. Experiments defines what a signed-in client resolves from it. The instance discovery document publishes enabled, anonymous_rollout_basis_points, rollout_salt, and standalone_forwarding for clients that are not signed in.

FieldTypeDescription
enabledbooleanWhether the rollout runs at all (default false)
config_versionintegerRevision counter, raised by Fluxer and never accepted from a request
rollout_basis_pointsintegerShare of accounts the rollout selects, in basis points (0-10000, default 0)
rollout_country_codesarray[string]Countries the sampled share is limited to, as unique uppercase ISO 3166-1 alpha-2 codes, up to 250 (default empty)
rollout_saltstringSalt of the sampling hash (1-64 printable ASCII characters, default domain-migration-v1)
included_user_idsarray[snowflake]Accounts the rollout always selects, up to 1000 entries (default empty)
included_guild_idsarray[snowflake]Guilds whose members the rollout always selects, up to 1000 entries (default empty)
include_premium_usersbooleanWhether the rollout always selects accounts with active premium (default false)
excluded_user_idsarray[snowflake]Accounts the rollout never selects, up to 1000 entries (default empty)
anonymous_rollout_basis_pointsintegerShare of logged-out devices the rollout moves, in basis points (0-10000, default 0)
standalone_forwardingbooleanWhether installed desktop web apps forward to the new origin once their data has moved (default false)

Every field is present on read. An absent document or missing field uses the defaults above.

excluded_user_ids wins over every other rule. Otherwise the rollout selects an account in included_user_ids, a member of a guild in included_guild_ids, or a premium account while include_premium_users is true, whatever rollout_basis_points says.

While rollout_country_codes is empty, rollout_basis_points samples every account. Once it lists a country, the sampled share only selects an account whose request comes from a listed country, and a request with an unknown country is never sampled. The list does not affect excluded_user_ids, included_user_ids, included_guild_ids, include_premium_users, or anonymous_rollout_basis_points.

An installed Chromium desktop web app moves its data like a browser tab, then stays on the legacy origin and offers to install the app from the new one. Set standalone_forwarding once the web app manifest lists the new origin in scope_extensions and the new origin serves the matching association file. From then on the installed app forwards like a browser tab. Installed mobile and Safari web apps never forward, whatever the value.

Only the official web client acts on this configuration. On any other instance it changes nothing a client does.

The instance rollout that lets small voice calls connect their participants directly instead of through the voice servers. Experiments defines what a client resolves from it.

FieldTypeDescription
enabledbooleanWhether the rollout runs at all (default false)
config_versionintegerRevision counter, raised by Fluxer and never accepted from a request
rollout_basis_pointsintegerShare of accounts the rollout selects, in basis points (0-10000, default 0)
rollout_country_codesarray[string]Countries the sampled share is limited to, as unique uppercase ISO 3166-1 alpha-2 codes, up to 250 (default empty)
rollout_saltstringSalt of the sampling hash (1-64 printable ASCII characters, default voice-p2p-v1)
included_user_idsarray[snowflake]Accounts the rollout always selects, up to 1000 entries (default empty)
included_guild_idsarray[snowflake]Guilds whose members the rollout always selects, up to 1000 entries (default empty)
include_premium_usersbooleanWhether the rollout always selects accounts with active premium (default false)
excluded_user_idsarray[snowflake]Accounts the rollout never selects, up to 1000 entries (default empty)
max_participantsintegerMost participants a peer-to-peer call holds (2-4, default 2)

Every field is present on read. An absent document or missing field uses the defaults above.

excluded_user_ids wins over every other rule. Otherwise the rollout selects an account in included_user_ids, a member of a guild in included_guild_ids, or a premium account while include_premium_users is true, whatever rollout_basis_points says.

While rollout_country_codes is empty, rollout_basis_points samples every account. Once it lists a country, the sampled share only selects an account whose request comes from a listed country, and a request with an unknown country is never sampled. The list does not affect excluded_user_ids, included_user_ids, included_guild_ids, or include_premium_users.

The rules above select who may start a peer-to-peer call. Joining a call that already runs peer-to-peer needs only enabled, so a partial rollout does not keep unselected accounts out of running calls.

max_participants applies to every account, selected or not. A join that would take a peer-to-peer call past it is refused as full, as Peer-to-peer voice describes. Lowering it removes nobody from a running call.

The ALTCHA proof-of-work check that the API issues and verifies itself on gated operations. CAPTCHA handling defines the challenge exchange and lists the gated operations.

FieldTypeDescription
enabledbooleanWhether gated operations require a solved challenge (default true)
costintegerPBKDF2 iterations per solving attempt (1000-20000, default 5000)
max_counterintegerUpper bound of the hidden counter a client searches for (100-20000, default 1000)

Every field is present on read. An absent document or missing field uses the defaults above, so the check is on until an administrator sets enabled to false. Setting enabled to false turns the check off for the whole instance.

Each challenge hides its counter between half of max_counter and max_counter, and a client tries counters from 0 upward. Solve time grows with cost times max_counter. Fluxer spends one attempt at cost to issue each challenge.

How often a client polls Get experiment assignments, and how widely those polls are spread. The setting is instance-wide and applies to every experiment at once, so adding an experiment adds no second cadence to tune.

FieldTypeDescription
poll_interval_secondsintegerSeconds between client revalidations (60-86400, default 300)
poll_jitter_percentintegerMaximum random change to each revalidation interval, as a percentage in either direction (0-50, default 15)

Every field is present on read. An absent document or missing field uses the defaults above.

Both fields are served to every account, whether or not any experiment targets that account, and neither one is versioned by config_version. A client that has never received a response from the experiments route uses built-in defaults of 300 seconds and 15 per cent, which equal the defaults above. A client that cannot read the route never receives either field.

Registration policy in force, plus every issued registration URL and every account awaiting a decision.

FieldTypeDescription
modestringRegistration mode
admin_registration_urls_enabled1booleanWhether Admin-issued registration URLs are accepted
urls2array[registration URL object]Every issued registration URL, including revoked and exhausted records
pending_registrations3array[pending registration object]Accounts awaiting a decision

1 While the value is false, registration refuses every supplied registration URL code, so an issued URL stops working without being revoked

2 Ordered by creation time, newest first

3 Ordered by request time, oldest first

Both collections are embedded in the configuration response. There is no separate listing operation and no pagination, so every configuration read returns every issued URL.

ValueDescription
openAnyone can register
approvalAnyone can register, and an Admin decision is required before the account can be used
closedPublic registration is closed

A valid registration URL is accepted in every mode, including closed, and its own approval_required replaces the mode for the account it creates.

A registration URL is an invitation an Admin can issue while the registration mode is closed or approval. It has its own expiry, use budget, and approval requirement.

Fluxer accepts a URL while it has no revocation time, has not passed its expiry, and has a use count below max_uses. A URL failing any of those tests is still reported here.

FieldTypeDescription
id1stringIdentifier of the registration URL (1-128 characters)
label?stringAdmin note attached to the URL, or null when unset
created_by_user_idsnowflakeAdmin account that issued the URL
created_atISO8601 timestampTime the URL was issued
expires_at?ISO8601 timestampTime the URL stops working, or null when it never expires
max_uses?integerMaximum permitted uses, or null for unlimited use
use_countintegerHow many registrations have completed through the URL
revoked_at?ISO8601 timestampTime the URL was revoked, or null while it has not been revoked
approval_required2booleanWhether an account created through the URL still needs an Admin decision
last_used_at?ISO8601 timestampTime the URL was last used, or null when it never has been
last_used_by_user_id?snowflakeMost recent account created through the URL, or null when there is none

1 A randomly generated UUID that is also the bearer code authorising registration, so every reader of the configuration can redeem an unrevoked URL

2 The value replaces the instance registration mode for an account created through this URL, in both directions. A URL with the value false lets an account skip approval on an instance in approval mode

{
"id": "3f2a91c4-6d1e-4a77-9f0b-2c5d8e114a20",
"label": "Design team",
"created_by_user_id": "1478812292088791040",
"created_at": "2026-08-20T10:00:00.000Z",
"expires_at": null,
"max_uses": 25,
"use_count": 3,
"revoked_at": null,
"approval_required": false,
"last_used_at": "2026-08-29T18:22:10.000Z",
"last_used_by_user_id": "1500901337221828608"
}

One account that registered and is still waiting for an Admin decision.

FieldTypeDescription
user_idsnowflakeAccount awaiting a decision
usernamestringUsername chosen at registration
discriminatorintegerDiscriminator tag from 0 to 9999
global_name?stringDisplay name of the account, or null when unset
email?stringEmail address of the account, or null when none is stored
requested_atISO8601 timestampTime the account registered
registration_url_id?stringRegistration URL the account signed up through (1-128 characters), or null when it registered directly
client_ip1?stringIP address the account registered from, or null when none was recorded

1 Stored at registration time and never refreshed, so it can be stale by the time an Admin reads it

Branding, legal, setup and registration field policy, in the Admin form of what the Instance resource publishes to clients.

FieldTypeDescription
brandingpublic branding objectProduct name, image URLs, and theme colour
setup1objectHas the single boolean configured
legalpublic legal configuration objectTerms, privacy, and community guidelines URLs
registration2public registration fields objectRegistration field collection policy

1 The Instance resource publishes admin_url in this object as well

2 The object has the single boolean collect_date_of_birth

Community, direct message, premium and gating policy for the whole deployment.

FieldTypeDescription
single_community_enabledbooleanWhether the deployment presents one community
single_community_guild_id?stringGuild used as that community, or null before one has been created
direct_messages_disabledbooleanWhether direct messages are disabled
direct_messages_locked1booleanWhether the direct message setting is locked against further change
guild_create_accessbooleanWhether every account can create communities, or only admins and holders of the feature_guild_create limit
premium_modestringPremium mode
servicesobjectOperator overrides for gif_enabled, youtube_enabled, and bluesky_enabled. Each is nullable, and null means no override
services_resolved2objectThe same keys as concrete booleans, resolved from the override and the provider’s own availability
services_available3objectProvider availability for gif, youtube, and bluesky, with no operator override applied

1 The lock is set each time direct messages are re-enabled. Update instance configuration clears it when the policy object has direct_messages_locked set to false

2 Each key is the operator override when one is set, and otherwise the matching services_available value

3 gif and youtube report whether an API key resolves from the stored configuration or the deployment configuration. bluesky is the value of integrations.bluesky.effective_enabled

ValueDescription
mirrorResolve premium access from the account’s own entitlement and premium flags
everyoneGrant premium access to every account on a self-hosted deployment

A self-hosted deployment issues gift codes and sells premium only in mirror.

Every provider reports its stored settings, a _set boolean in place of each secret, and the availability resolved from the stored settings and the deployment configuration.

FieldTypeDescription
gifobjectklipy_api_key_set and effective_available
youtubeobjectapi_key_set and effective_available
emailemail integration objectOutbound email settings
blueskyBluesky integration objectBluesky client settings

Outbound email settings, and the provider resolved from them.

FieldTypeDescription
enabled?booleanOperator override, or null for no override
effective_enabledbooleanWhether outbound email is in force
provider?stringOperator override of smtp or none, or null for no override
effective_providerstringProvider in use, either smtp or none
from_email?stringEnvelope sender address
from_name?stringEnvelope sender name, or null when none is set and mail is sent under the instance product name
smtp1objectThe SMTP server settings
disable_new_ip_authorizationbooleanWhether new-IP authorisation email is suppressed by the stored setting
effective_disable_new_ip_authorization2booleanWhether it is suppressed once outbound email state is taken into account

1 Holds host, port, username, tls_mode, effective_tls_mode, and password_set. host and username are nullable, port is a nullable integer from 1 to 65535, and password_set is a plain boolean. tls_mode is the saved SMTP TLS mode, or null when none is saved. effective_tls_mode is the mode outgoing email uses, or null while the provider is not smtp

2 True whenever the stored setting is true or outbound email is not in force

On a deployment whose account identity mode is username, effective_enabled is always false whatever the stored settings hold.

Client identity the deployment presents to Bluesky, and the number of signing keys in its effective configuration.

FieldTypeDescription
enabled?booleanOperator override, or null for no override
effective_enabledbooleanWhether the integration is enabled with at least one configured signing key
client_name?stringClient name presented to Bluesky
client_uri?stringClient URI
logo_uri?stringClient logo URI
tos_uri?stringClient terms URI
policy_uri?stringClient policy URI
key_countintegerNumber of configured signing keys

Signing keys are write-only and must have unique identifiers.

Stripe billing for the premium tier. Each stored field is nullable, and null falls back to the deployment configuration.

FieldTypeDescription
enabled?booleanOperator override of the billing switch, or null for no override
effective_enabledbooleanWhether billing is switched on once the override and the deployment configuration are combined
stripe_secret_key_setbooleanWhether a Stripe secret key is stored or supplied by deployment configuration
stripe_webhook_secret_setbooleanWhether a Stripe webhook secret is stored or supplied by deployment configuration
stripe_secret_key_storedbooleanWhether a Stripe secret key is stored, not counting deployment configuration
stripe_webhook_secret_storedbooleanWhether a Stripe webhook secret is stored, not counting deployment configuration
automatic_tax4?booleanStored switch for Stripe automatic tax at checkout, or null for the default
tax_id_collection4?booleanStored switch for collecting a buyer tax ID at checkout, or null for the default
terms_consent_required4?booleanStored switch for requiring terms of service consent at checkout, or null for the default
effective_automatic_taxbooleanWhether checkout uses Stripe automatic tax
effective_tax_id_collectionbooleanWhether checkout collects a buyer tax ID
effective_terms_consent_requiredbooleanWhether checkout requires terms of service consent
default_currency?stringCurrency used when no country mapping applies, or null
prices1?map[string, billing price set object]Stored price sets keyed by currency, or null to use the deployment configuration
country_currencies?objectStored map of two-letter country codes to currencies, or null
legacy_prices2?objectStored map of legacy price slots to arrays of Stripe price IDs, or null to use the deployment configuration
billing_active3booleanWhether premium purchases are available
stripe_serviceable5booleanWhether existing Stripe subscriptions can be managed, cancelled and billed
catalog_modestringoperator while prices is stored, otherwise env
webhook_urlstringThe URL to register as the Stripe webhook endpoint

1 Stored prices replace the deployment catalogue entirely and take any three-letter currency code. A buyer gets the currency mapped to their country, then default_currency, then the first configured currency. Fluxer’s country checks for localised currencies do not apply to them

2 A slot is monthly, yearly, gift_1_month, or gift_1_year, an underscore, and a currency, such as monthly_GBP. Existing subscriptions on a listed price keep renewing

3 True 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 tiering is in force. Premium tiering is always in force on a hosted deployment, and on a self-hosted one only in the mirror premium mode

4 A hosted deployment always turns all three on. A self-hosted deployment defaults all three to off. Automatic tax needs Stripe Tax set up, and terms consent needs a terms of service URL in the Stripe public details

5 True while a Stripe secret key is set and premium tiering is in force. On a hosted deployment billing must also be switched on. Only the checkout routes follow billing_active

The Stripe price IDs for one currency. Each is nullable.

FieldTypeDescription
monthly?stringPrice ID of the monthly recurring plan
yearly?stringPrice ID of the yearly recurring plan
gift_1_month?stringPrice ID of the one-month gift
gift_1_year?stringPrice ID of the one-year gift

Attachment retention overrides the operator has set, and the values in force.

FieldTypeDescription
attachment_decay1objectNullable operator overrides plus an effective object of the same keys with concrete values

1 The override keys are enabled, min_size_mb, max_size_mb, max_eligible_size_mb, min_lifetime_days, max_lifetime_days, curve, renew_threshold_days, and renew_window_days. Each is null when the deployment default applies, and effective reports the value in force. enabled is a boolean, curve is a number from 0 to 1, the _mb keys are positive numbers, and the _days keys are positive safe integers

Fluxer clears max_size_mb when it is not above min_size_mb, clears max_eligible_size_mb when it is below max_size_mb, and clears max_lifetime_days when it is below min_lifetime_days. A cleared key uses the deployment default. The effective size range must have a finite maximum above its minimum, and retention must produce a valid expiry date. Check the returned effective values after an update.

ValueDescription
iconWrites branding.icon_url
symbolWrites branding.symbol_url
logoWrites branding.logo_url
wordmarkWrites branding.wordmark_url
faviconWrites branding.favicon_url

How the connection to the SMTP server is encrypted.

ValueDescription
implicitTLS from the first byte, usually on port 465
starttlsA plain connection that must upgrade with STARTTLS, usually on port 587
opportunisticA plain connection that upgrades with STARTTLS when the server offers it
noneNo TLS, even when the server offers STARTTLS

With no mode saved, Fluxer follows FLUXER_EMAIL_SMTP_TLS_MODE, then the older FLUXER_EMAIL_SMTP_SECURE. With neither set it uses implicit on port 465 and starttls on every other port.

Whether one Create SMTP test connection attempt succeeded, and the failure text when it did not.

FieldTypeDescription
okbooleanWhether the server accepted the connection and credentials
error1?stringFailure text, or null when the test succeeded

1 The message reported by the SMTP client, so it can repeat text supplied by the remote server

{
"ok": false,
"error": "Invalid login: 535 5.7.8 Authentication credentials invalid"
}

One issued registration URL together with the link an Admin hands out.

FieldTypeDescription
registration_urlregistration URL objectRecord that was issued
code1stringBearer code that authorises registration (1-256 characters)
url2stringComplete registration link built from the configured web application endpoint

1 Equal to registration_url.id, so it can be recovered from any later configuration read

2 The configured web application endpoint followed by /register?registration_url= and the percent-encoded code

The effective limit configuration together with the deployment defaults and the metadata an editor needs.

FieldTypeDescription
limit_configlimit configuration objectEffective configuration on the serving node
limit_config_jsonstringThe same document rendered as JSON indented by two spaces, for an editor to display
self_hostedbooleanWhether the deployment runs in self-hosted mode
defaults1map[string, map[string, integer]]Deployment default limits, keyed by rule identifier and then by limit key
metadatamap[string, limit key metadata object]Display metadata for each limit key
categories2map[string, string]Display label for each metadata category
limit_keysarray[string]Every limit key in registry order
bounds?3map[string, object]Optional min and max pair for each limit key

1 Built for the deployment and the premium mode currently loaded by the serving node. Self-hosted mirror mode includes the premium rule

2 The keys are messages, guilds, channels, expressions, files, social, and features

3 Absent from every response

Trait definitions and the ordered rules that decide each limit key.

FieldTypeDescription
traitDefinitionsarray[string]Trait names a rule filter can match
rulesarray[limit rule object]Ordered limit rules

The field names are camelCase, unlike the rest of the Admin API.

One rule in that ordered set, with the filters that scope it and the limits it sets.

FieldTypeDescription
idstringRule identifier (at least 1 character)
filters?objectOptional traits and guildFeatures string arrays that scope the rule
limitsmap[string, integer]Non-negative value for each limit key the rule sets
modifiedFields?1array[string]Limit keys whose value differs from the deployment default

1 Compared with the deployment default rule of the same identifier, or with the deployment’s default rule for a custom identifier. A set key absent from that default counts as modified. A rule with no differing key omits the field. Computing this field changes no value in limits

Display metadata for one limit key, which an editor uses to render its control.

FieldTypeDescription
keystringThe limit key
labelstringDisplay label
descriptionstringDescription of what the limit bounds
categorystringCategory key, resolved against categories
scopestringuser, guild, or both
isTogglebooleanWhether the key is a feature gate whose value is 0 or 1
unit?stringbytes or count
min?numberSuggested minimum for an editor
max?numberSuggested maximum for an editor
GET/v1/admin/instance/configAudit reason

Returns the instance configuration object. Requires instance:config:view, or a session credential until setup is marked complete.

StatusBodyCondition
200instance configuration objectConfiguration was returned

The operation records one Admin audit entry with action get_instance_config, target type instance_config, target ID 0, and metadata keys registration_url_count and pending_registration_count. Before setup is complete, a session credential holding no Admin ACL records the entry with its own account as the acting Admin.

200 requests per minute for each authenticated user, on the admin:lookup bucket.

PATCH/v1/admin/instance/configAudit reason

Applies a merge patch to the stored configuration and returns the resulting instance configuration object. Requires instance:config:update, or a session credential until setup is marked complete.

FieldTypeDescription
sso?1objectEvery SSO configuration field except client_secret_set and redirect_uri, plus client_secret
gateway_rollout?objectAny subset of the Gateway rollout configuration fields, each bound as documented there
push_relay?objectrelay_consent_accepted from the push relay configuration
domain_migration?objectAny subset of the domain migration fields
voice_p2p?objectAny subset of the peer-to-peer voice fields
captcha?objectAny subset of the captcha configuration fields
experiment_delivery?objectAny subset of the experiment delivery fields
registration?objectmode and admin_registration_urls_enabled
app_public?2objectbranding, setup, legal, and registration sub-objects, each merged field by field
integrations?3objectgif, youtube, email, and bluesky sub-objects, the last of which also has the keys array
media?objectattachment_decay overrides, each nullable to restore the deployment default
policy?instance policy update objectCommunity, direct message, premium, and gating policy
billing?4objectStored instance billing fields, with stripe_secret_key and stripe_webhook_secret for the secrets

1 The supplied fields are merged over the stored configuration and the result is validated as a whole. Every supplied endpoint URL uses https, has no credentials and no fragment, and resolves to a publicly routable address, otherwise the request returns 400 INVALID_FORM_BODY with INVALID_URL_FORMAT or URL_NOT_PUBLICLY_ROUTABLE

2 branding.product_name is 1 to 80 characters, every branding and legal URL is at most 2048 characters and nullable, branding.theme_color is a hex colour (#rgb or #rrggbb, the # is optional) and nullable, and setup.configured and registration.collect_date_of_birth are booleans. The theme colour is returned as lowercase #rrggbb, and pure black is treated as unset and returned as null. branding.premium_product_name is 1 to 40 characters, and null restores the default. branding.premium_info_url and legal.guidelines_url are absolute http or https URLs. Every string is trimmed before it is stored, and null or an empty string clears a legal URL

push_relay takes only relay_consent_accepted. Fluxer sets relay_consent_accepted_at and relay_consent_accepted_by itself on the request that changes that flag, and accepts neither from a request. Turning the flag on stamps the current time and the acting account, and turning it off clears both to null. A request that repeats the flag it already holds leaves the stamp alone.

domain_migration takes every domain migration configuration field except config_version, each bound as documented there. Fluxer raises config_version by one on each request that supplies at least one of them. A section that is absent, or present with no field set, writes nothing and leaves config_version alone.

voice_p2p works the same way, over the peer-to-peer voice configuration fields and its own config_version.

captcha takes any subset of the captcha configuration fields, each bound as documented there. Fluxer merges the supplied fields over the stored ones. The section has no config_version.

experiment_delivery takes both experiment delivery configuration fields, each bound as documented there. It is a section of its own, so a write to it changes no config_version and changes no assignment, only the cadence on which clients ask for one.

3 A secret such as klipy_api_key, api_key, or the SMTP password is written when supplied and left alone when absent. integrations.email.smtp takes host, port, username, password, and tls_mode, an SMTP TLS mode, and null clears a saved value so the environment applies again. The older boolean secure is still read when tls_mode is absent, with true as implicit and false as opportunistic. integrations.bluesky.keys is the only way to write the Bluesky signing keys counted as bluesky.key_count. It takes up to 8 entries of kid (1-255 characters) and nullable private_key (up to 10000 characters), and replaces the stored key set outright

4 Accepted only on a self-hosted deployment. A hosted deployment rejects the section, and app_public.branding.premium_product_name and premium_info_url, with 400 INVALID_FORM_BODY. A Stripe secret, enabled, automatic_tax, tax_id_collection and terms_consent_required are written when supplied, cleared by null, and left alone when absent. A null enabled follows FLUXER_STRIPE_ENABLED. prices, country_currencies, and legacy_prices replace the stored value outright, a price slot left out is stored as null, and an empty prices object restores the deployment catalogue. A price ID is price_ followed by letters and digits. A currency is three upper-case letters and a country code is two

FieldTypeDescription
single_community_enabled?1booleanWhether the deployment presents one community
single_community_name?1stringName used only when the community has to be created (1-100 characters)
direct_messages_disabled?2booleanWhether direct messages are disabled
direct_messages_locked?2booleanWhether the direct message setting stays locked
guild_create_access?booleanWhether every account can create communities
premium_mode?stringPremium mode
services?objectNullable gif_enabled, youtube_enabled, and bluesky_enabled overrides

1 Setting single_community_enabled to true adopts the already designated guild when one still exists. When none is designated or the designated guild was deleted, it creates a community using single_community_name or the configured product name. When the stored guild ID is not a valid ID, or the guild lookup fails for a reason other than an unknown guild, the operation fails and Fluxer creates no community. On a deployment whose setup is already complete, enabling it while no guild is designated fails with 400 INSTANCE_POLICY_TRANSITION_NOT_ALLOWED, as does enabling it when the acting Admin account cannot be resolved. Setting it to false only clears the flag and leaves the guild in place

2 The setting can be changed only while direct_messages_locked is false, and a change attempted after the lock is set fails with 400 INSTANCE_POLICY_TRANSITION_NOT_ALLOWED unless the same request sets direct_messages_locked to false. Re-enabling direct messages sets the lock again

direct_messages_locked accepts only false, and a body that sets it to true fails with 400 INVALID_FORM_BODY.

On a self-hosted deployment, billing and the everyone premium mode exclude each other. A body that would leave billing switched on in everyone fails with 400 INVALID_FORM_BODY and writes nothing, whether it enables billing or switches the premium mode.

StatusBodyCondition
200instance configuration objectThe patch was applied
400error responseA policy transition is refused, returned as INSTANCE_POLICY_TRANSITION_NOT_ALLOWED

Fluxer publishes a gateway_rollout change to the Gateway cluster. A push_relay change reaches the push service without a restart. A billing change applies without a restart. Premium mode changes affect the limits in force without replacing the saved limit configuration. On self-hosted deployments, everyone hides premium-filtered rules. Switching back to mirror restores them unless an Admin has replaced the limit configuration in the meantime. Enabling single community mode creates the community when none is designated, with the acting Admin as owner.

Initial setup completes on the first update that sets app_public.setup.configured to true from a session credential whose account holds neither admin:authenticate nor the wildcard. That update grants the account the wildcard Admin ACL and marks the deployment as bootstrapped.

The operation records one Admin audit entry with action update_instance_config, target type instance_config, and target ID 0. The metadata key sections lists the names of the non-null top-level sections in the body, comma-separated in alphabetical order, and is absent when the body supplies none. The update that completes initial setup and grants the wildcard ACL also records granted_acls as *. No value from the body is recorded. A request that fails part way records no entry.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

POST/v1/admin/instance/config/branding-assetsAudit reason

Uploads an image, stores its Media Proxy URL in the selected branding slot, and returns the resulting instance configuration object. Requires instance:config:update, or a session credential until setup is marked complete.

FieldTypeDescription
kindstringBranding asset kind naming the slot to write
image?1 2?stringBase64 image or data URI (max 16000000 characters)

1 Omitting the key and sending null both clear the slot

2 The image decodes to no more than the resolved avatar_max_size limit, which defaults to 10485760 bytes, and is a PNG, JPEG, WebP, GIF, APNG, AVIF, HEIC, HEIF, JXL, or SVG. An animated AVIF is refused

StatusBodyCondition
200instance configuration objectThe slot was written or cleared
4001error responseThe image cannot be decoded, exceeds the size ceiling, or is not an accepted format

1 Returned as 400 INVALID_FORM_BODY with IMAGE_SIZE_EXCEEDS_LIMIT, INVALID_IMAGE_FORMAT, or FAILED_TO_UPLOAD_IMAGE against image

The stored image is served through the Media Proxy. Non-JPEG images are re-encoded to strip metadata and JPEG images are re-encoded at quality 100. The previously referenced image is not deleted.

The operation records one Admin audit entry with action upload_branding_asset, target type instance_config, target ID 0, and metadata keys kind and cleared. cleared is true when the request cleared the slot.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

POST/v1/admin/instance/config/smtp-testsAudit reason

Opens a connection to an SMTP server, authenticates against it, and reports the outcome as an SMTP test result object without storing anything. Requires instance:config:update, or a session credential until setup is marked complete.

FieldTypeDescription
host??stringSMTP host to connect to (1-255 characters after trimming)
port??integerSMTP port to connect to (1-65535)
username??stringSMTP username to authenticate with (1-320 characters after trimming)
password??stringSMTP password to authenticate with (1-4096 characters after trimming)
tls_mode?1?stringSMTP TLS mode to connect with

Every field left out or sent as null is filled from the saved configuration, the one outgoing email uses. The saved password is filled in only while host and username are left out or match the saved ones. A test that names another host or username without a password fails before any connection is made.

An empty body tests exactly what a send would use. It fails without connecting while outgoing email is not in force, which covers email turned off, a provider other than smtp, a missing from address, a missing host, username or password, and an instance that signs in with usernames. A test with fields in the body fails the same way when the host, username or password ends up empty.

1 Left out, the saved mode applies. Sent as null, the mode follows FLUXER_EMAIL_SMTP_TLS_MODE, then the port

StatusBodyCondition
200SMTP test result objectThe test ran to completion, including a rejected credential

No configuration is written and the supplied credentials are discarded when the request completes. The connection, greeting, and socket each have a ten-second deadline.

The operation records one Admin audit entry with action test_smtp_connection, target type instance_config, target ID 0, and metadata keys port, tls_mode, and ok. The host, username, password, and failure text are not recorded.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

POST/v1/admin/instance/registration-urlsAudit reason

Issues a registration URL an Admin can hand out while the registration mode is closed or approval, and returns a registration URL creation object. Requires instance:config:update.

FieldTypeDescription
label?1?stringAdmin note to attach to the URL (1-120 characters), or null for none
expires_at??ISO8601 timestampTime the URL stops working, or null for a URL that never expires
max_uses??integerMaximum permitted uses (1-1000000), or null for unlimited use
approval_required?booleanWhether an account created through the URL still needs an Admin decision (default false)

1 The label is trimmed before it is length checked, so a whitespace-only label fails body validation. Omit the key or send null for a URL with no label

StatusBodyCondition
200registration URL creation objectThe URL was issued

A newly issued URL has a use count of zero, no revocation time, and the acting Admin as its issuer. It is the first entry of registration.urls on the next configuration read. The operation changes no account.

The operation records one Admin audit entry with action create_registration_url, target type registration_url, target ID 0, and metadata key approval_required, plus max_uses when the body sets it. The label is not recorded. The entry has no registration URL identifier, because the identifier is the bearer code.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

DELETE/v1/admin/instance/registration-urls/{registration_url_id}Audit reason

Revokes one registration URL so it can no longer be redeemed and returns the resulting instance configuration object. Requires instance:config:update.

FieldTypeDescription
registration_url_idstringIdentifier of the registration URL to revoke (1-128 characters)
StatusBodyCondition
2001instance configuration objectThe revocation was applied

1 An identifier naming no registration URL answers 200 with the configuration unchanged. Revoking an already revoked URL keeps the original revocation time

The URL records its revocation time and stays in the configuration response afterwards. The operation changes no account.

The operation records one Admin audit entry with action revoke_registration_url, target type registration_url, target ID 0, and no metadata, including for an identifier that names no registration URL. The entry has no registration URL identifier, because the identifier is the bearer code.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

PATCH/v1/admin/instance/pending-registrations/{user_id}Audit reason

Approves or rejects one pending registration and returns the resulting instance configuration object. Requires instance:config:update.

FieldTypeDescription
user_idsnowflakeAccount awaiting a decision
FieldTypeDescription
statusstringEither approved or rejected
StatusBodyCondition
2001instance configuration objectThe decision was applied

1 An account that no longer exists still answers 200. The pending registration is removed and no trait is written

Approval removes both the registration_pending_approval trait and the registration_rejected trait, and joins the account to the single community when that mode is enabled and a guild is designated. A join that fails is logged and does not fail the request. Rejection removes the registration_pending_approval trait and adds the registration_rejected trait, which blocks login and every later session creation. A session issued before the decision stays valid. The pending registration is removed either way.

When the stored pending registration list fails validation, the request fails before Fluxer changes the account. A failure after Fluxer writes the account traits leaves those traits written and can leave the entry in the pending list. Check the account traits and the pending list before retrying.

One Admin audit entry with the action approve_registration or reject_registration targets the account and records the audit reason. It has no metadata, except for an account that no longer exists, whose entry has the metadata key account_found set to false.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.

GET/v1/admin/limit-configAudit reason

Returns the limit configuration response object. Requires instance:limit_config:view.

StatusBodyCondition
200limit configuration response objectThe configuration was returned

The response reflects the configuration in force on the node that serves the request, so two nodes can report different values while a change propagates.

The operation records one Admin audit entry with action get_limit_config, target type limit_config, target ID 0, and metadata key rule_count.

200 requests per minute for each authenticated user, on the admin:lookup bucket.

PUT/v1/admin/limit-configAudit reason

Replaces the stored limit configuration with the supplied document and returns the resulting limit configuration response object. Requires instance:limit_config:update.

FieldTypeDescription
limit_config1limit configuration objectComplete replacement document

1 traitDefinitions can be omitted and is then stored as an empty array. Every key inside a rule’s limits map is a known limit key and every value is a non-negative safe integer, otherwise the body fails validation. modifiedFields is not accepted on input and is recomputed

StatusBodyCondition
200limit configuration response objectThe configuration was replaced
400error responseBody validation fails, including an unknown limit key, returned as INVALID_FORM_BODY

On a self-hosted deployment whose premium mode is everyone, Fluxer drops the premium trait definition and every rule filtered on the premium trait before storing the document.

Each rule’s modifiedFields is then recomputed and the merged document replaces the stored one. Every API node adopts the new configuration. Clients observe it through the published limit configuration.

The operation records one Admin audit entry with action update_limit_config, target type limit_config, target ID 0, and metadata keys rule_count, changed_rule_count, and trait_definition_count, each taken from the stored document. changed_rule_count is the number of rule identifiers added, removed, or stored with different filters or limits, compared with the configuration the serving node held before the write.

100 requests per minute for each authenticated user, on the admin:user:modify bucket.