Skip to Content
FluxStore is currently invite-only. Some sections of this documentation are still being written and expanded.
DevelopersPlugin Protocol

Plugin Protocol

The FluxStore Minecraft plugin is open source. If you want to build your own plugin for a platform we don’t officially support, or you want to customize how commands are delivered, you can implement your own client as long as it follows the protocol described on this page.

You don’t need any of this to use FluxStore normally. This page is for developers who want to build a custom plugin implementation.

Our API is rate limited. Be reasonable with how often you make requests. Excessive or abusive usage (spamming FetchPendingCommands, reconnecting in tight loops, etc.) may result in your server being temporarily or permanently blocked. If you’re unsure whether your usage pattern is acceptable, reach out to support before deploying.

Delivery methods

FluxStore supports two ways to deliver commands to your plugin, and you can use either or both:

WebSocket (recommended) maintains a persistent connection using SignalR. When a customer makes a purchase, commands are pushed to your plugin instantly. This is the fastest and most efficient approach since there’s no delay and no unnecessary requests.

Polling lets your plugin periodically call FetchPendingCommands to check for new commands. This is simpler to implement but adds latency since commands are only picked up on the next poll. If you use polling, respect the NextCheckSeconds value returned by the server and don’t poll more frequently than that.

You can combine both. Keep a WebSocket connection open for instant delivery, and use occasional polling as a fallback to catch anything that might have been missed during a brief disconnect.

Connection

FluxStore uses SignalR  for real-time communication between your server and the FluxStore platform. SignalR is built on WebSocket with automatic fallback to other transports if needed.

SignalR client libraries are available for most languages including Java, C#, JavaScript, Python, and Go.

Hub endpoint: wss://api.fluxstore.net/plugin-hub

Authentication

Authentication must be the first message sent after connecting. The combined key is in the format serverId:secret, where serverId is the GUID of your server and secret is the 32 character token generated when you add a server in your dashboard.

If authentication fails, the connection is closed immediately with no error message.

Authenticate

Direction: Plugin to server

Method: Authenticate(HandshakeRequest request, string combinedKey) HandshakeRequest { ServerSoftware: string // Server platform, e.g. "Spigot 1.20.1" } Returns: HandshakeResponse { ServerId: guid // Your server's unique identifier StoreName: string // The store name NextCheckSeconds: int // Recommended interval before next check (default 300) PendingCommandCount: int // Number of commands waiting to be delivered }

Plugin to server methods

These are methods your plugin calls on the hub.

PlayerJoin

Call this when a player joins your server. FluxStore checks for any commands waiting for that player and pushes them immediately.

Method: PlayerJoin(string playerUuid, string playerUsername)

PlayerLeave

Call this when a player leaves your server.

Method: PlayerLeave(string playerUuid)

FetchPendingCommands

Forces an immediate check for all pending commands for your server. If any exist, the server responds with an ExecuteCommands message. Don’t call this more frequently than the NextCheckSeconds interval.

Method: FetchPendingCommands()

AcknowledgeCommands

After executing commands, send back the results so FluxStore can update the order status. Always send results in a batch, not individually.

Method: AcknowledgeCommands(List<CommandResult> results) CommandResult { CommandId: guid // The ID of the command (from PluginCommandDto.Id) Status: string // "success", "failed", or "player_offline" Error: string (optional) // Error message if status is "failed" } Returns: int // Number of commands successfully acknowledged

Status values:

StatusMeaningWhat FluxStore does
successCommand ran successfullyMarks as completed
failedCommand execution failedRetries with backoff (30s, 60s, 120s), up to 3 attempts
player_offlinePlayer not on the serverHolds command until next PlayerJoin for that player

Server to plugin messages

These are messages the server pushes to your plugin over the WebSocket connection. Listen for them on your SignalR client.

ExecuteCommands

Sent when there are commands for your server to execute. This is triggered by purchases, PlayerJoin events, FetchPendingCommands calls, or the background sweep service.

Message: ExecuteCommands(List<PluginCommandDto> commands) PluginCommandDto { Id: guid // Unique command ID (include in AcknowledgeCommands) Command: string // The command to execute, e.g. "give Steve diamond 64" PlayerUsername: string // Target player's username PlayerUuid: string // Target player's UUID (may be null) RequireOnline: bool // Only execute if the player is currently online CommandType: string // e.g. "Initial", "Chargeback", "Expiry" PackageName: string // Name of the package (may be null) ExecutionOrder: int // Execute in this order (lower first) Conditions: { // Optional execution conditions Slots: int // Only execute if player has this many empty inventory slots DelaySeconds: int // Wait this many seconds before executing } }

Typical lifecycle

Here’s the expected flow for a custom plugin implementation:

  1. Connect to wss://api.fluxstore.net/plugin-hub using a SignalR client
  2. Call Authenticate with your combined key and server info
  3. Register a listener for ExecuteCommands messages
  4. Call PlayerJoin and PlayerLeave as players connect and disconnect
  5. When you receive ExecuteCommands, execute each command on your server and call AcknowledgeCommands with the results
  6. Optionally call FetchPendingCommands on an interval as a polling fallback
  7. If the connection drops, reconnect and re-authenticate. Any commands that were pending will be re-sent.

Building a custom plugin

If you’re building your own implementation, here are some things to keep in mind:

  • Authentication must come first. Any other method call before Authenticate will fail.
  • Always acknowledge commands. If you don’t send AcknowledgeCommands, FluxStore assumes the commands weren’t delivered and will keep retrying.
  • Handle reconnection gracefully. Network interruptions are normal. Reconnect, re-authenticate, and pending commands will be pushed again. Don’t reconnect in a tight loop. Use exponential backoff.
  • Respect RequireOnline. If a command has RequireOnline set to true and the player isn’t on the server, report player_offline in your acknowledgment rather than skipping it silently.
  • Execute in order. Sort commands by ExecutionOrder before executing them.
  • Check Conditions. If a command has Conditions.DelaySeconds, wait before executing. If it has Conditions.Slots, check the player’s inventory first.
  • Respect rate limits. Don’t poll more often than NextCheckSeconds suggests. Don’t spam methods in a loop. If you’re rate limited, back off.

The official FluxStore plugin is open source and serves as a reference implementation. If you’re unsure about any part of the protocol, reading the plugin source code is the best way to understand the expected behaviour.