HTTP API
Use the HTTP API to read and change resources. Every path starts with /v1 under the base URL in /.well-known/fluxer, and third-party clients use endpoints.api_public.
Limits such as attachment counts differ between instances, and instance discovery lists them. Field tables use the field notation for optional and nullable fields.
Resource pages
Section titled “Resource pages”| Page | Covers |
|---|---|
| Errors | Error responses, status codes and every error code |
| Deployment availability | Routes served only while premium or billing is on |
| Authentication operations | Registration, login, MFA, WebAuthn, SSO, recovery, sessions |
| Gateway | Gateway endpoint discovery and the session start budget |
| Instance | Instance discovery, geolocation, limit keys, the OpenAPI document |
| Experiments | Experiment assignments and how to poll for them |
| OAuth2 | Authorization, consent, tokens, introspection, revocation |
| Applications | Applications, bot accounts, client secrets, bot tokens |
| Connections | External account connections |
| Users | The user object and shared user enumerations |
| Current user | Your account, profile, lifecycle and policy acceptance |
| User settings | Account, notification and privacy settings, guild folders |
| User settings Protobuf | Structured client preference messages |
| Email and password changes | The ticketed credential change flows |
| Multi-factor authentication | TOTP, backup codes, WebAuthn credentials, sudo verification |
| Relationships | Friends, friend requests, blocks |
| User notes | Private notes on users |
| Private channels | Direct message and group DM channels |
| Push notifications | Registering a device for push delivery |
| User content collections | Recent mentions, saved messages, message deletion |
| Gift inventory | Premium gift codes you created |
| Data harvests | Requesting and downloading your data |
| Read states | Read acknowledgements and mention counts |
| Memes | Saved media and GIF URL resolution |
| GIFs | GIF search, featured and trending listings, share registration |
| Themes | Shareable custom CSS themes |
| Channels | Channels, recipients, permission overwrites, slowmode |
| Threads | Starting, archiving and searching threads |
| Thread members | Joining and leaving threads, notification settings |
| Forums | Forum and media channels, tags, posts |
| Calls | Call eligibility, regions, ringing, termination |
| Peer-to-peer voice | Connection outcome reports for peer-to-peer calls |
| Streams | Stream keys, regions, previews |
| Entrance sounds | The entrance sound collection and playback |
| Messages | Messages, attachments, embeds, history, pins, reactions, typing |
| Guilds | Guild objects and lifecycle |
| Guild channels | Listing, creating and positioning guild channels |
| Guild members | Members, profiles, voice moderation, roles |
| Guild member search | Member search filters and sorting |
| Guild moderation | Bans and temporary bans |
| Guild emojis | Guild emoji management |
| Guild stickers | Guild sticker management |
| Expressions | Emoji and sticker metadata |
| Guild audit logs | Audit entries, filters and the audit reason |
| Roles and permissions | Permission flags and roles |
| Discovery | Public guild listings and listing applications |
| Invites | Invite lookup, creation, acceptance, deletion |
| Webhooks | Webhook management, execution and provider callbacks |
| Search | Global message search |
| Unfurl | External URL metadata |
| Billing | Stripe checkout, gift purchase, the Stripe webhook |
| Premium | Pricing, entitlement state, subscription self-service |
| Gifts | Gift code lookup and redemption |
| Reports | Safety reports and Digital Services Act notices |
Request format
Section titled “Request format”Send JSON bodies with Content-Type: application/json. Responses are UTF-8 JSON unless an operation says otherwise, and every GET route also answers HEAD.
Unknown paths, including a known path with a trailing slash, return 404 NOT_FOUND. An overloaded instance returns 503 SERVICE_UNAVAILABLE with Retry-After: 1.
Request body formats
Section titled “Request body formats”Create message, Modify message, Execute webhook and Start thread take multipart/form-data with these fields when you attach files.
| Field | Type | Description |
|---|---|---|
| payload_json? | string | The JSON request payload of the operation |
| files[n]? | file | The attachment file at index n |
The index n must be below the instance's max_attachments_per_message limit and matches the id of an entry in the attachments array of payload_json. Indexes don't need to start at zero or be consecutive.
A malformed multipart body returns 400 INVALID_FORM_BODY with the validation code FAILED_TO_PARSE_MULTIPART_FORM_DATA. To upload files before sending, see Attachment uploads. The OAuth2 token operations take application/x-www-form-urlencoded or multipart/form-data bodies.
Input normalization
Section titled “Input normalization”Before validation, empty strings and empty nested objects become null, and an empty body counts as {}. Create message, Modify message, Execute webhook and Start thread skip this step. Malformed JSON returns 400 INVALID_FORM_BODY with the path body and the code INVALID_FORMAT.
Authentication
Section titled “Authentication”Each operation says which credentials it accepts, and Authentication has the Authorization schemes. An OAuth2 bearer token works only on routes marked OAuth2, and other routes return 403 ACCESS_DENIED.
Standard request headers
Section titled “Standard request headers”| Field | Type | Description |
|---|---|---|
| Authorization? | string | The credential for an authenticated request |
| Content-Type? | string | The body media type and, for multipart bodies, the boundary |
| Accept-Language? | string | The locale for an error message, used when the account has none set |
| X-Audit-Log-Reason? | string | A reason for the audit log entry (up to 512 characters) |
| X-Fluxer-Sudo-Mode-JWT? | string | The sudo token from Multi-factor authentication |
| X-Captcha-Token? | string | The solved ALTCHA challenge, see CAPTCHA handling |
| X-Request-ID? | string | An identifier you choose, echoed in the response |
Standard response headers
Section titled “Standard response headers”| Field | Type | Description |
|---|---|---|
| X-Fluxer-Version? | string | The build version of the instance |
| X-Request-ID? | string | The request identifier, generated when you send none |
| X-Fluxer-Sudo-Mode-JWT? | string | The sudo mode token, sent when an operation completes a sudo proof |
| Cache-Control? | string | no-cache unless the operation sets its own value or the body is media |
| Retry-After? | string | Whole seconds to wait after a 429 or 503 |
The X-RateLimit-* headers are listed under Rate limits.
Rate limits
Section titled “Rate limits”Every route has its own bucket, and most routes also count against a global bucket. A denial returns 429 RATE_LIMITED, as described in Rate limits.
Conditional routes
Section titled “Conditional routes”A self-hosted instance serves some routes only while its premium mode or billing is on, and answers the others with 404 NOT_FOUND. Deployment availability lists them.
Cross-origin requests
Section titled “Cross-origin requests”Only the instance's web app and marketing origins are allowed. A request from one of them gets Access-Control-Allow-Origin set to that origin and Vary: Origin. Browsers don't send cookies cross-origin, and you send your token in Authorization.
Get instance discovery, Get OpenAPI document and Get client geolocation answer any origin with *. The webhook execution routes also allow any origin, with the exceptions under Origin refusal.
Browser scripts can read only the X-Fluxer-Version and ETag response headers. Cross-origin requests can send the headers in Standard request headers plus X-Requested-With, If-None-Match, X-Captcha-ID and the X-Fluxer-* client headers.
Error response object
Section titled “Error response object”Errors lists every status code and code value.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| code | string | The stable API error code |
| message | string | A description in the request locale |
| errors? | array[validation error object] | The request fields that failed validation |
Some codes add more top-level fields, listed under Extra fields. Ignore fields you don't recognize.
Validation error object
Section titled “Validation error object”A 400 INVALID_FORM_BODY response has one validation error object in errors for each field that failed, and Validation errors lists the codes.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| path | string | The failed field as a dotted path like embeds.0.title, root for the whole object or body for malformed JSON |
| code? | string | The validation error code |
| message | string | A description of the failure |
Example
Section titled “Example”{ "code": "INVALID_FORM_BODY", "message": "Invalid form body.", "errors": [ {"path": "name", "code": "INVALID_FORMAT", "message": "The provided value is in an invalid format."} ]}