@wumx-labs/noxaeapi-sdk

Official JS / TS SDK

Typed JS/TS SDK for NoxAeApi, a REST + WebSocket API plugin/mod for Minecraft servers — ships for both Fabric and Bukkit/Spigot/PaperMC.

Features & Architecture

Zero Runtime Dependencies

Ultra lightweight, leveraging native fetch and native WebSocket APIs.

Cross-Platform Identical

Identical REST surface across Fabric, Bukkit, Spigot, and PaperMC.

Auto-Reconnect & Backoff

Automatic exponential backoff reconnects on unexpected socket drops.

Typed Error Hierarchy

Comprehensive error subclasses for 401, 403, 404, 429, 5xx, and network timeouts.

Installation

Install the package from npm via your package manager of choice:

Terminal
npm install @wumx-labs/noxaeapi-sdk
# pnpm
pnpm add @wumx-labs/noxaeapi-sdk
# yarn
yarn add @wumx-labs/noxaeapi-sdk
# bun
bun add @wumx-labs/noxaeapi-sdk

Basic Usage

Initialize the client with your server baseUrl and secret API key:

index.ts
import { NoxAeApiClient } from "@wumx-labs/noxaeapi-sdk";

const client = new NoxAeApiClient({
  baseUrl: "http://localhost:8080",
  apiKey: "your-api-key",
});

// 1. Players & Server moderation
const players = await client.players.list();
await client.server.broadcast("Hello from the TypeScript SDK!");

// 2. Deterministic cross-server identity (v0.5.2)
const identity = await client.identity.get("NoxlyDev");
console.log(identity.identityUuid, identity.hasPlayedBefore);

// 3. Economy & Pluggable Leaderboards
const balance = await client.economy.getBalance(players[0]?.uuid);
const topScores = await client.leaderboards.getTop("mcmmo-power", 10);
const profile = await client.leaderboards.getPlayerProfile(players[0]?.uuid);

From Environment Variables

You can automatically read credentials from the environment with NoxAeApiClient.fromEnv():

env-setup.ts
import { NoxAeApiClient } from "@wumx-labs/noxaeapi-sdk";

// Reads NOXAEAPI_BASE_URL (or NOXAEAPI_URL) and NOXAEAPI_KEY from process.env.
// In Node.js environments using a .env file, load it first (e.g. with dotenv):
// import "dotenv/config";

// 1. Standard environment variable loading
const client = NoxAeApiClient.fromEnv();

// 2. Or pass a custom environment dictionary and client options
const customClient = NoxAeApiClient.fromEnv(process.env, {
  timeoutMs: 15_000,
});

Environment Note

Reads NOXAEAPI_BASE_URL and NOXAEAPI_KEY from process.env. If you use a .env file, load it first (e.g. with dotenv) — the SDK never reads .env files implicitly.

Realtime (Console Tail / Events)

Stream server console logs and live events directly using WebSockets:

realtime.ts
import { NoxAeApiClient } from "@wumx-labs/noxaeapi-sdk";

const client = NoxAeApiClient.fromEnv();

// 1. Connect to live console output stream (authenticates via ?key= query parameter)
const consoleSocket = client.connect({ route: "console" });

consoleSocket.on("open", () => console.log("Connected to console stream"));
consoleSocket.on("console", (line) => console.log("[Minecraft Console]", line));
consoleSocket.on("error", (err) => console.error("WebSocket error:", err));
consoleSocket.on("close", () => console.log("Console connection closed"));

// 2. Connect to live game events (joins, quits, deaths, kicks, bans, chat)
const eventsSocket = client.connect({ route: "events" });

eventsSocket.on("event", (evt) => {
  console.log("Live Event:", evt.event, "Player:", evt.player?.name);
});

// Sockets include built-in automatic reconnect with exponential backoff.

Error Handling

All non-2xx responses throw a typed subclass of NoxAeApiError:

Error Classes
NoxAeApiUnauthorizedError401 — Missing or invalid API key
NoxAeApiForbiddenError403 — Key valid but not permitted for this endpoint
NoxAeApiNotFoundError404 — Resource or player not found
NoxAeApiRateLimitError429 — Rate limited (SDK auto-retries these by default)
NoxAeApiServerError5xx — Server error (also auto-retried by default)
NoxAeApiNetworkErrorRequest never completed (timeout, DNS, connection refused)
errors.ts
import {
  NoxAeApiForbiddenError,
  NoxAeApiNotFoundError,
  NoxAeApiRateLimitError,
} from "@wumx-labs/noxaeapi-sdk";

try {
  await client.server.restart();
} catch (err) {
  if (err instanceof NoxAeApiForbiddenError) {
    console.error("This API key isn't allowed to restart the server.");
  } else if (err instanceof NoxAeApiNotFoundError) {
    console.error("The requested resource was not found.");
  } else if (err instanceof NoxAeApiRateLimitError) {
    console.error("Rate limit hit, consider lowering request frequency.");
  } else {
    throw err;
  }
}

Request Encoding

The server is a Javalin app, and most endpoints read their body with ctx.formParam(...) — i.e. application/x-www-form-urlencoded — rather than JSON. The SDK follows the same split:

  • Form-urlencoded: everything in economy, players, server (except luckperms/noxauth), worlds, plugins, and placeholders.
  • JSON: client.luckperms.* & client.noxauth.checkPassword only — these are read server-side with ctx.bodyAsClass(...).

SDK Modules & Methods

The NoxAeApiClient exposes 10 modular services covering all core Minecraft server subsystems and integrated third-party plugins:

client.players.list(): Promise<OnlinePlayer[]>
REST Spec

Get an array of all currently online players with locations, health, and metadata.

client.players.listAll(options?: { page?: number; limit?: number }): Promise<OfflinePlayer[]>
REST Spec

Get paginated list of all players who have ever connected to the server.

client.players.get(uuid: string): Promise<OnlinePlayer>
REST Spec

Get in-depth attributes and real-time state for a specific online player by UUID.

client.players.getInventory(playerUuid: string, worldUuid?: string): Promise<InventorySlot[]>
REST Spec

Inspect full armor, hotbar, offhand, and storage inventory slots in a world.

client.players.kick(uuid: string, reason?: string): Promise<void>Admin
REST Spec

Disconnect an online player with a custom formatted kick notice.

client.players.ban(uuid: string, reason?: string, expiry?: string | number): Promise<void>Admin
REST Spec

Ban a player UUID with optional reason and ISO timestamp/epoch expiration.

client.players.unban(uuid: string): Promise<void>Admin
REST Spec

Remove a player ban entry by UUID.

client.players.teleport(uuid: string, target: { x: number; y: number; z: number; world: string }): Promise<void>
REST Spec

Teleport player to target coordinates in a specified world dimension.

client.players.setGamemode(uuid: string, gamemode: "SURVIVAL" | "CREATIVE" | "ADVENTURE" | "SPECTATOR"): Promise<void>Admin
REST Spec

Update the active gamemode for an online player.

client.players.getStats(uuid: string): Promise<PlayerStats>
REST Spec

Fetch gameplay statistics (kills, deaths, play time, distance walked).

client.players.resolve(name: string): Promise<PlayerResolveResult>
REST Spec

Resolve a player username to their local UUID using the server's local player cache.

client.economy.info(): Promise<{ defaultCurrency: string; currencies: string[] }>
REST Spec

Get economy plugin information, default currency, and registered currency providers.

client.economy.getBalance(uuid: string): Promise<{ uuid: string; balance: number }>
REST Spec

Query the current default currency balance for a player UUID.

client.economy.getTopBalance(limit?: number): Promise<LeaderboardEntry[]>
REST Spec

Fetch top richest players on the server for default currency (default 10, max 100).

client.economy.pay(uuid: string, amount: number, reason?: string): Promise<{ success: boolean; newBalance: number }>
REST Spec

Credit / deposit an amount into a player default balance.

client.economy.debit(uuid: string, amount: number, reason?: string): Promise<{ success: boolean; newBalance: number }>Admin
REST Spec

Debit funds from a player default balance.

client.economy.listCurrencies(): Promise<string[]>
REST Spec

List all supported multi-currencies (ExcellentEconomy/CoinsEngine).

client.economy.getCurrencyBalance(currency: string, uuid: string): Promise<{ uuid: string; balance: number }>
REST Spec

Query the balance of a specific currency for a player UUID.

client.economy.payCurrency(currency: string, uuid: string, amount: number, reason?: string): Promise<{ success: boolean; newBalance: number }>
REST Spec

Credit / deposit an amount of specific currency into a player balance.

client.economy.debitCurrency(currency: string, uuid: string, amount: number, reason?: string): Promise<{ success: boolean; newBalance: number }>Admin
REST Spec

Debit funds of specific currency from a player balance.

client.economy.setCurrencyBalance(currency: string, uuid: string, amount: number, reason?: string): Promise<{ success: boolean; newBalance: number }>Admin
REST Spec

Set absolute balance of a specific currency for a player.

client.economy.getCurrencyTop(currency: string, limit?: number): Promise<LeaderboardEntry[]>
REST Spec

Fetch top richest players for a specific currency.

Network Endpoints Notice

Multi-Server Network Endpoints Awaiting Dedicated Wrapper

Multi-server proxy REST API endpoints (such as /v1/network/status, /v1/network/health, /v1/network/players, and /v1/network/broadcast) are currently not wrapped inside the SDK client instance. To query the proxy cluster, dispatch requests directly via native fetch or your preferred HTTP library:

velocity-hub.ts
import { NoxAeApiNetworkHubClient } from "@wumx-labs/noxaeapi-sdk";

// Client for the standalone NoxAeApi-Velocity network proxy hub
const hub = new NoxAeApiNetworkHubClient({
  baseUrl: "http://localhost:9090", // Hub API port
  apiKey: "your-hub-key",
});

// Query live network status & players across all connected backend nodes
const status = await hub.network.statusAll();
const { total, players } = await hub.network.players();

// Forward any REST request to a specific backend server via the proxy:
await hub.network.forward("survival", "POST", "server/exec", {
  body: { command: "say hi from velocity hub" },
  form: true,
});

Advanced Module Examples

Real-world recipes for player moderation, world manipulation, runtime plugin installations, and RPG skill integrations:

1. Player Moderation & Teleportation

player-actions.ts
import { NoxAeApiClient } from "@wumx-labs/noxaeapi-sdk";

const client = NoxAeApiClient.fromEnv();

// Find player and teleport to safe coordinates
const player = await client.players.get("069a79f4-44e9-4726-a5be-fca90e38aaf5");

await client.players.teleport(player.uuid, {
  x: 0.5,
  y: 70.0,
  z: 0.5,
  world: "world",
});

// Set gamemode to SURVIVAL
await client.players.setGamemode(player.uuid, "SURVIVAL");

// Moderation: Temporary ban with reason
// await client.players.ban(player.uuid, "Griefing spawn area", "2026-12-31T23:59:59Z");

2. World Control & Backup Archiving

world-control.ts
// Set daylight to morning and clear storms
const worlds = await client.worlds.list();
const overworld = worlds.find((w) => w.environment === "NORMAL");

if (overworld) {
  await client.worlds.setTime(overworld.uuid, 1000); // 1000 ticks = morning
  await client.worlds.setWeather(overworld.uuid, "CLEAR");
}

// Synchronous world save before maintenance
await client.worlds.save();

// Download full ZIP world backup archive
const archiveBuffer = await client.worlds.download();
// fs.writeFileSync("world-backup.zip", Buffer.from(archiveBuffer));

3. Runtime Plugin Management

plugins-admin.ts
// Enumerate all active plugins
const plugins = await client.plugins.list();
console.log("Plugins:", plugins.map(p => `${p.name} (${p.version}) - ${p.enabled ? "Active" : "Disabled"}`));

// Install plugin JAR from remote URL
await client.plugins.install("https://cdn.example.com/plugins/CustomScoreboard.jar");

// Enable the freshly downloaded plugin
await client.plugins.enable("CustomScoreboard");

4. LuckPerms Permissions & mcMMO Skills

permissions-skills.ts
// Check resolved permission including group inheritance
const { result: canFly } = await client.luckperms.checkPlayerPermission(
  "069a79f4-44e9-4726-a5be-fca90e38aaf5",
  "essentials.fly"
);

// Inspect mcMMO RPG levels
const skills = await client.skills.getMcmmoSkills("069a79f4-44e9-4726-a5be-fca90e38aaf5");
console.log("Swords Skill Level:", skills.SWORDS);
console.log("Mining Skill Level:", skills.MINING);

Advanced Configuration

Fine-tune timeout limits, retry strategies, and custom headers in the constructor:

client-options.ts
new NoxAeApiClient({
  baseUrl: "https://mc.example.com",
  apiKey: "...",
  timeoutMs: 10_000,          // per-request timeout, default 10s
  retry: {
    attempts: 3,               // total attempts including the first, default 3
    baseDelayMs: 300,
    maxDelayMs: 5000,
  },
  // retry: false,             // disable retries entirely
  headers: { "X-Extra": "..." },
});