Fluxer API Docs

API Reference

An overview of how the Fluxer API works and how to use it

Fluxer exposes an HTTP API for most of the read and write operations in the app. You can use it to build bots, automations, and integrations that talk to Fluxer from your code. For real-time events, connect to the Fluxer Gateway over WebSocket.

If you've used the Discord API before, Fluxer will feel familiar. In many cases you can adapt existing Discord bot libraries to work with Fluxer with only small changes.

Base URL

All HTTP API requests go through the same base URL:

https://api.fluxer.app

API Versioning

Fluxer uses versioned API endpoints. The current version is v1, and all documented endpoints are prefixed with /v1/.

GET /v1/...

If you omit the version prefix, you'll hit the latest stable version. That can change over time, so for anything you care about not breaking, it's better to pin a specific version like /v1/.

Error Responses

Generic Error Response

When a request fails, the API returns an HTTP status code plus a JSON body with error details:

{
	"code": "UNKNOWN_USER",
	"message": "Unknown User"
}

code is a machine-readable error string. message is meant for humans and may change, so don't rely on it for program logic.

Form Validation Errors

For endpoints that accept form data, failed validation returns 400 Bad Request and a list of field-level errors:

{
	"code": "INVALID_FORM_BODY",
	"message": "Input Validation Error",
	"errors": [
		{"path": "username", "message": "Username must be at least 3 characters long."},
		{"path": "email", "message": "Email must be a valid email address."}
	]
}

For nested structures, path uses dot and index notation to point at the field that failed:

{
	"code": "INVALID_FORM_BODY",
	"message": "Input Validation Error",
	"errors": [
		{"path": "profile.address.street", "message": "Street is required."},
		{"path": "items.0.quantity", "message": "Quantity must be a positive integer."}
	]
}

Treat code as the stable part of the error and use errors[*].path to locate invalid inputs.

Authentication

Most API requests require authentication. Send your bot token in the Authorization header:

Authorization: Bot YOUR_BOT_TOKEN

Replace YOUR_BOT_TOKEN with the token from User Settings > Developer Applications in the Fluxer web/desktop app.

Bot tokens are secret. Don't commit them to source control or ship them in client-side code.

Encryption

All HTTP and WebSocket connections to Fluxer must use TLS (https:// and wss://). The minimum supported version is TLS 1.2.

Plain http:// and ws:// endpoints are not available.

Snowflakes

Fluxer uses Twitter Snowflakes as IDs for users, messages, channels, and other entities.

Within a single entity type (for example, messages), Snowflakes are unique. Different entity types may happen to share the same numeric Snowflake, so always keep track of what an ID refers to.

Snowflakes are 64-bit unsigned integers that encode a timestamp plus some extra bits. In JSON, they're always sent as strings to avoid precision issues in languages that don't handle 64-bit integers well. Treat them as opaque strings unless you explicitly need to decode them.

ComponentBitsDescription
Timestamp42Milliseconds since the Fluxer epoch (1420070400000, the first second of 2015)
Worker ID5ID of the worker that generated the Snowflake
Process ID5ID of the process that generated the Snowflake
Sequence Number12Counter for IDs generated in the same millisecond

If you decode the timestamp part, you can tell when a resource was created.

function snowflakeToTimestamp(snowflake: string): number {
	const fluxerEpoch = 1420070400000n;
	const timestamp = (BigInt(snowflake) >> 22n) + fluxerEpoch;
	return Number(timestamp);
}

Pagination with Snowflakes

Many API endpoints return lists of items. To help you paginate through large result sets, these endpoints accept before, after, and limit query parameters. Check the individual endpoint docs to see which ones support pagination.

Because Snowflake IDs encode timestamps, you can also generate Snowflakes from timestamps to paginate by time:

function timestampToSnowflake(timestamp: number): string {
	const fluxerEpoch = 1420070400000n;
	const snowflake = (BigInt(timestamp) - fluxerEpoch) << 22n;
	return snowflake.toString();
}

const currentTimeMs = Date.now();
const currentSnowflake = timestampToSnowflake(currentTimeMs);

To specify the beginning of time, use the Snowflake 0.

ISO 8601 Timestamps

Timestamps in Fluxer API responses use the ISO 8601 format with UTC timezone. You can parse them with standard libraries in your language of choice.

Nullable & Optional Fields

To stay close to Discord's API docs, the Fluxer API docs use this convention for nullable and optional fields in tables:

Field NameTypeDescription
optional_field?stringAn optional field that may be missing in the response
nullable_field?stringA nullable field that may be null in the response, but is always present
optional_nullable_field??stringAn optional field that may be missing or null in the response

Backwards Compatibility

New fields added to responses, documented or not, are considered backwards-compatible additions. Your client should ignore any fields it doesn't recognize.

Breaking changes to the API will be announced in advance, and a migration period will be provided where both the old and new versions of the API are available.

HTTP API

User Agent

When making HTTP requests to the Fluxer API, it's good practice to set a custom User-Agent header that identifies your application. Example:

User-Agent: MyFluxerBot ($url, $version)

Content Type

Set the Content-Type header to application/json, application/x-www-form-urlencoded, or multipart/form-data as appropriate for the request body you're sending.

Rate Limits

Rate limits are reported via HTTP headers in the response. If you exceed a rate limit, you'll receive a 429 Too Many Requests response. For more details, see the Rate Limits documentation.

Gateway API (WebSocket)

Fluxer's Gateway API lets you maintain a long-lived WebSocket connection for real-time events. For details on how to connect and interact with the Gateway, see the Gateway API documentation.

Message Formatting

Fluxer supports rich message formatting using Markdown-style syntax. Compatibility with most Discord-flavored Markdown is intentional so you can port bots and integrations with minimal changes.

Format Types

In addition to standard formatting such as bold, italics, underline, strikethrough, inline code, code blocks, blockquotes, headings, lists, and links, Fluxer supports the following formatting options:

TypeSyntaxExample
Spoiler||text||||spoiler|| (hidden until clicked)
Subtext (small gray text)-# your text-# extra context / footnote
Email link<hello@example.com><hello@example.com>
Phone link<+1234567890><+1234567890>
Mention user<@user_id><@123456789012345678>
Mention channel<#channel_id><#123456789012345678>
Mention role<@&role_id><@&123456789012345678>
Standard emojiUnicode emoji😄
Custom emoji<:name:emoji_id><:custom_emoji:123456789012345678>
Custom emoji (animated)<a:name:emoji_id><a:animated_emoji:123456789012345678>
Unix timestamp<t:timestamp><t:1445444940>
Unix timestamp (styled)<t:timestamp:style><t:1445444940:R>

Timestamp Styles

When using Unix timestamps, you can specify a style character to control how the timestamp is displayed:

StyleDescriptionExample Output
tShort time16:29
TMedium time16:29:00
dShort date10/21/2015
DLong dateOctober 21, 2015
f*Long date, short timeOctober 21, 2015 at 16:29
FFull date, short timeWednesday, October 21, 2015 at 16:29
sShort date, short time10/21/2015, 16:29
SShort date, medium time10/21/2015, 16:29:00
RRelative time2 hours ago

* Default if no style is provided.

User Content CDN

Base URL

https://fluxerusercontent.com

All user-uploaded media content is served through the User Content CDN at the above base URL.

CDN Endpoints

Resource TypePath TemplateSupported Formats
User Avatar/avatars/{user_id}/{avatar_hash}.{ext}PNG, JPEG, WebP, GIF
Guild Icon/icons/{guild_id}/{icon_hash}.{ext}PNG, JPEG, WebP, GIF
Guild Banner/banners/{guild_id}/{banner_hash}.{ext}PNG, JPEG, WebP, GIF
Guild Splash/splashes/{guild_id}/{splash_hash}.{ext}PNG, JPEG, WebP, GIF
Custom Emoji/emojis/{emoji_id}.{ext}PNG, JPEG, WebP, GIF
Sticker/stickers/{sticker_id}.{ext}WebP, GIF
Guild Member Avatar/guilds/{guild_id}/users/{user_id}/avatars/{avatar_hash}.{ext}PNG, JPEG, WebP, GIF
Guild Member Banner/guilds/{guild_id}/users/{user_id}/banners/{banner_hash}.{ext}PNG, JPEG, WebP, GIF
Attachment/attachments/{channel_id}/{attachment_id}/{filename}Various

All CDN endpoints support query parameters for dynamic image transformation and optimization.

Query Parameters

CDN endpoints support the following query parameters for transforming and optimizing media on the fly:

Avatar, Icon, Banner, Splash, and Emoji Endpoints

These endpoints support the ImageQuerySchema:

ParameterTypeDefaultDescription
sizeinteger128The desired width in pixels. Must be one of: 16, 20, 22, 24, 28, 32, 40, 44, 48, 56, 60, 64, 80, 96, 100, 128, 160, 240, 256, 300, 320, 480, 512, 600, 640, 1024, 1280, 1536, 2048, 3072, 4096. The image will be resized proportionally.
qualitystringhighImage quality preset. Options: high (80% quality), low (20% quality), lossless (100% quality).
animatedbooleanfalseWhether to preserve animation for WebP images. Note: GIF images are always animated regardless of this parameter.

Attachment Endpoints

Attachment endpoints support more flexible transformations via the ExternalQuerySchema:

ParameterTypeDefaultDescription
widthinteger-The desired width in pixels (1-4096). If only width is specified, height is calculated to maintain aspect ratio.
heightinteger-The desired height in pixels (1-4096). If only height is specified, width is calculated to maintain aspect ratio.
formatstring-Convert the image to the specified format. Options: png, jpg, jpeg, webp, gif.
qualitystringlosslessImage quality preset. Options: high (80% quality), low (20% quality), lossless (100% quality).
animatedbooleanfalseWhether to preserve animation for GIF and WebP images. Must be set to true to preserve animation in attachments.

For attachment endpoints, if no transformations are specified (no width, height, format, or quality other than lossless), the original file is served directly.

Examples

# Get a 256px user avatar in high quality
https://fluxerusercontent.com/avatars/123456789012345678/a_abc123.webp?size=256&quality=high

# Get an animated guild icon
https://fluxerusercontent.com/icons/123456789012345678/a_def456.gif?size=512&animated=true

# Get an attachment resized to 800x600 in WebP format
https://fluxerusercontent.com/attachments/123/456/image.png?width=800&height=600&format=webp

# Stream a video attachment without transformation
https://fluxerusercontent.com/attachments/123/456/video.mp4

Static Assets CDN

Base URL

https://fluxerstatic.com

Default avatars can be accessed through the Static Assets CDN at the above base URL.

CDN Endpoints

Resource TypePath TemplateSupported Formats
Default Avatar/avatars/{index}.png*PNG

* {index} is a number from 0 to 5, representing the six default avatar options. Use index = user_id % 6 to select a default avatar based on the user's ID.

function getDefaultAvatarUrl(userId: string): string {
	const index = Number(BigInt(userId) % 6n);
	return `https://fluxerstatic.com/avatars/${index}.png`;
}

Image Data

Image data is a data URI scheme supporting PNG, JPEG, WebP, and GIF formats. It consists of a prefix indicating the media type and encoding, followed by the base64-encoded image data.

data:image/{format};base64,{base64_data}

Replace {format} with the actual image format (for example, png, jpeg, webp, gif) and {base64_data} with the base64-encoded string of the image.

Uploading Files

The file upload size limit applies to each file in a request. The default limit is 25 MiB for free users and 500 MiB for premium users. At most 10 files can be uploaded in a single message.

Multipart Form Data Upload

Upload files directly with your message using multipart/form-data:

const form = new FormData();

form.append(
	'payload_json',
	JSON.stringify({
		content: 'Check out these files!',
		attachments: [
			{id: 0, filename: 'cat.png', description: 'A cute cat'},
			{id: 1, filename: 'dog.jpg', description: 'A good dog'},
		],
	}),
);

form.append('files[0]', catImageBlob, 'cat.png');
form.append('files[1]', dogImageBlob, 'dog.jpg');

const response = await fetch('https://api.fluxer.app/v1/channels/123456789012345678/messages', {
	method: 'POST',
	headers: {
		Authorization: 'Bot YOUR_BOT_TOKEN',
	},
	body: form,
});

Editing Messages with Attachments

Existing attachments must be specified when PATCHing messages with new attachments. Any attachments not specified will be removed and replaced with the specified list. If you don't specify attachments at all, the existing attachments will remain unchanged.

Using Attachments in Embeds

Use the special attachment://{filename} URL format to reference uploaded files within embed objects.

Only PNG, JPEG, WebP, and GIF image formats may be used at this time. Other file types are not supported.

{
	"embeds": [
		{
			"title": "Look at this image",
			"image": {
				"url": "attachment://cat.png"
			}
		}
	]
}

On this page