Deployment availability
The routes listed under Conditional routes depend on the deployment. The deployment Fluxer hosts serves all of them. A self-hosted deployment serves some of them only while its operator runs a premium tier or sells it, and never serves the rest. Both deployments run the same release, and most of the HTTP API is identical on both.
When a self-hosted deployment does not serve one of these routes, a request to it returns 404 NOT_FOUND with no feature-specific code, so a caller cannot tell an unavailable route from an unrecognised path.
Credentials, permissions, premium state and OAuth2 scopes do not change route availability. Read the deployment kind and the premium flags from instance discovery.
Deployment kind
Section titled “Deployment kind”Every deployment reports its kind in self_hosted on the instance features object. The unauthenticated instance discovery document publishes it before a client holds any credential. A hosted deployment serves every route below whatever the other flags say.
On a self-hosted deployment, three flags on the same object decide which routes below are served. All three are computed on each request, so an operator’s change applies without a restart.
premium_enabledis true while the instance premium mode ismirror. The routes under Served in the mirror premium mode are served only then.stripe_enabledis true while billing is active. Billing is active when the operator has switched it on, set a Stripe secret key, and set a monthly and a yearly price for at least one currency, andpremium_enabledis true. The routes under Served while billing is active are served only then.stripe_serviceableis true while a Stripe secret key is set andpremium_enabledis true. The routes under Served while Stripe is serviceable are served only then, so existing subscriptions can still be managed after the operator stops sales.- The routes under Never served on a self-hosted deployment are never served.
Receive Stripe webhook also needs a Stripe webhook secret.
When billing is switched off or no Stripe secret key is configured on a hosted deployment, the answer depends on the operation. An operation that has to reach the provider fails with 400 STRIPE_PAYMENT_NOT_AVAILABLE, and Receive Stripe webhook fails with 400 STRIPE_WEBHOOK_NOT_AVAILABLE. These read operations report the absence in a 200 body instead:
- Get refund eligibility reports
eligiblefalse with the reasonfeature_unavailable. - Get current subscription price reports null.
- Get price IDs reports the configured price IDs with every amount null.
Conditional routes
Section titled “Conditional routes”Served in the mirror premium mode
Section titled “Served in the mirror premium mode”| Method | Route | Operation |
|---|---|---|
| GET | /v1/gifts/{code} | Get gift |
| POST | /v1/gifts/{code}/redeem | Redeem gift |
| GET | /v1/users/@me/gifts1 | List current user gifts |
Served while billing is active
Section titled “Served while billing is active”| Method | Route | Operation |
|---|---|---|
| POST | /v1/stripe/checkout/subscription | Create subscription checkout |
| POST | /v1/stripe/checkout/gift | Create gift checkout |
| GET | /v1/premium/price-ids | Get price IDs |
Served while Stripe is serviceable
Section titled “Served while Stripe is serviceable”| Method | Route | Operation |
|---|---|---|
| POST | /v1/stripe/webhook2 | Receive Stripe webhook |
| GET | /v1/premium/current-subscription-price3 | Get current subscription price |
| POST | /v1/premium/customer-portal | Create customer portal |
| POST | /v1/premium/grace/end | End premium grace period |
| POST | /v1/premium/cancel-subscription | Cancel subscription |
| POST | /v1/premium/reactivate-subscription | Reactivate subscription |
| POST | /v1/premium/change-subscription | Change subscription billing cycle |
| POST | /v1/premium/cancel-pending-subscription-change | Cancel pending subscription change |
Never served on a self-hosted deployment
Section titled “Never served on a self-hosted deployment”| Method | Route | Operation |
|---|---|---|
| POST | /v1/donations/request-link | Request donation management link |
| GET | /v1/donations/manage | Manage donation |
| POST | /v1/donations/checkout | Create donation checkout |
| POST | /v1/users/@me/age-verification1 | Create age verification session |
| GET | /v1/premium/refund-eligibility4 | Get refund eligibility |
| POST | /v1/premium/refund-latest | Refund latest purchase |
| POST | /v1/premium/switch-to-list-price | Switch subscription to the list price |
| POST | /v1/premium/visionary/rejoin | Rejoin Visionary guild |
| GET | /v1/premium/store | Get in-app purchase context |
| POST | /v1/premium/store/app-store/transactions | Claim App Store transaction |
| POST | /v1/premium/store/google-play/purchases | Claim Google Play purchase |
| GET | /v1/premium/store/purchases | List in-app purchases |
| DELETE | /v1/premium/store/purchases/{purchase_id} | Release in-app subscription |
1 These are the only /users/@me routes a self-hosted deployment may not serve
2 The webhook takes no credential and is authenticated by the provider signature header alone
3 The same object appears as billing.current_subscription_price on Get premium state, which every deployment serves
4 The same object appears as billing.refund_eligibility on Get premium state, which every deployment serves, and there a self-hosted deployment reports eligible false with the reason feature_unavailable
The two store notification webhooks are never served on a self-hosted deployment either.
Registered routes that resolve differently
Section titled “Registered routes that resolve differently”A route every deployment registers can still produce a different answer on a self-hosted instance. Each operation page documents that difference.
Premium state is the clearest case. Every deployment registers Get premium state and Set premium perks disabled. A self-hosted instance still reports premium state and still records the perks-disabled flag. The response repeats the deployment kind in self_hosted on the effective premium state object. That flag alone does not make is_premium true. A self-hosted deployment grants premium to every account only while its instance premium mode is everyone. That mode also overrides the perks-disabled flag, so is_premium stays true while premium_perks_disabled is true.
The other instance feature flags published by instance discovery work the same way. voice_enabled, presigned_attachment_uploads, and emails_enabled each report whether a capability is switched on. The routes for that capability stay registered when the flag is false, so a client reads the flag before it uses them.
account_identity is the same kind of flag. Every deployment registers the email routes and the username-only routes alike. A username deployment answers the email routes with 400 EMAIL_UNAVAILABLE_ON_INSTANCE, and an email deployment answers the username-only routes with 400 USERNAME_SIGN_IN_ONLY. A hosted deployment is always email.