Farmstead Mods
RU

Web dashboard

Installation, login, account linking via Discord and the external hosting mode.

On this page

Commands 4#

CommandSyntaxAliasesPermissionDescription
/apikey/apikey <create <label> [role] | list | revoke <id>>—neoessentials.dashboard.apikeysManage long-lived API keys for external dashboard integrationsThe root requires neoessentials.dashboard.apikeys (validatePermission). Bare /apikey is incomplete — there is no .executes on the root. <label> and <id> are words. [role] defaults to ADMIN; completion offers ADMIN, OPERATOR, MODERATOR, VIEWER. The full token is printed once (a copyable component) and is never stored in plain form again. list shows id/label/role/enabled/last used, not the secret. Unlike /dashboard, isCommandEnabled("apikey") is not checked — the command is always registered.
/dashboard/dashboard [start | stop | restart | status | url | pair <dashboardUrl> <code> | unpair]—neoessentials.admin.dashboardStart/stop/status/URL for the web dashboardThe root is gated by neoessentials.admin.dashboard via validateAdminPermission (the console and OP level 2 always pass). Bare /dashboard equals status. pair/unpair additionally require neoessentials.dashboard.pair (validatePermission, no admin bypass). <dashboardUrl> is StringArgumentType.string(): a URL with : and / must be quoted, otherwise Brigadier splits the token. start looks at webDashboard.enabled and modules.webDashboardEnabled; autoStart ships as false — HTTP does not come up on its own. The command is registered only if commands.dashboard is enabled.
/dashboardregister/dashboardregister [start | complete <username> <password> | discord | status]—neoessentials.dashboard.accessRegister a web dashboard accountA player needs neoessentials.dashboard.access; the console is allowed with OP 2, but every branch except help replies players_only. A bare call prints help. <password> is greedy (spaces allowed), at least 8 characters; <username> is a word of 3–20 characters. The start token lives for 5 minutes in memory and is not written to the DataStore. discord requires a ready SDLink / Mc2Discord / DCIntegration and an already linked Discord account.
/linkaccount/linkaccount <code>—neoessentials.dashboard.linkaccountLink your Minecraft account to an existing dashboard accountWithout neoessentials.dashboard.linkaccount the command is not in the tree. The console passes .requires, but execute replies players_only. The code comes from POST /api/auth/link-minecraft/start: 8 characters from ABCDEFGHJKLMNPQRSTUVWXYZ23456789, TTL 5 minutes; input is upper-cased. This is the reverse direction of /dashboardregister: it links an existing dashboard account to a player name instead of creating a new one.

Examples#

Start the API by hand and get the address#

The build ships with webDashboard.autoStart: false and port: 8080 — after server start HTTP stays silent until you run start.

/dashboard status
/dashboard start
/dashboard url

status prints running/offline, whether the config is enabled and, if it was stopped by command, a manually disabled mark. start brings up REST and WebSocket (websocketPort, 8081 as shipped). url repeats the base http://: and refuses if the server is not running. With enabled: false, start replies disabled_in_config and listens on nothing.

A key for an external panel#

A Laravel/external backend calls /api/* with Authorization: Bearer. No human login is needed for that.

/apikey create farmstead-dash ADMIN
/apikey list
/dashboard status

create prints the token once — put it in the panel's server-side config, not in a browser. list shows the id (needed for revoke) and last used: never until the key is used. GET /api/ping without a header should return 200 and {"success":true,"mod":"neoessentials","mode":"external|internal"} — this checks the port, not the key.

A player registers their own panel account#

Not an API key but a login/password for a person. Two steps: a token, then complete.

/dashboardregister start
/dashboardregister complete steve_admin S3cretPass
/dashboardregister status

start issues a one-time token for 5 minutes. complete looks up the pending entry by UUID (no need to paste the token into chat again), checks the name/password length and creates a dashboard user linked to this Minecraft account. If the player already has Discord linked through a companion mod, complete also auto-links it. A repeated start for an already registered player gives already_registered. status shows the panel name, player name, time and Discord.

Registration via a linked Discord account#

No password is set: later you log in with the Discord button on the panel side, if the companion mod provides the link.

/dashboardregister discord
/dashboardregister status

Requires an installed and ready Simple Discord Link, Mc2Discord or DCIntegration, plus a Discord account already linked to this UUID. Success creates an account with dashboard name = Minecraft name. Without a companion mod — discord_unavailable and a suggestion to use start/complete. DiscordSRV is not supported (it is a Bukkit plugin). NeoEssentials itself never calls discord.com.

The panel shows a code on its Configuration/Settings page; the mod gives it an API key and remembers the return token.

/dashboard pair "https://dash.example.com" ABCD1234
/linkaccount K7MNPQ2R
/dashboard unpair

pair (quotes are required) POSTs to {url}/api/pair/complete with code, modToken (a new key labelled dashboard-pairing, role ADMIN), serverName and websocketPort. On 200 + dashboardToken, url/token/keyId are written to webDashboard.externalDashboard. The player takes the linkaccount code from the Settings page (POST /api/auth/link-minecraft/start); success links that player name to that dashboard account. unpair revokes the pairing key and clears externalDashboard.

Edge cases#

internal vs external is a separate page#

How the port listens, what / serves, and how webDashboard.mode (external as shipped, internal/both) matters when diagnosing "the panel does not connect" is covered on the dashboard connectivity page. Here it is enough to know: mode is read when HTTP starts, /neoe reload does not change it; /api/ping is alive in every mode and without a Bearer token.

What to do: Changing the mode needs a restart of the mod's HTTP (/dashboard restart or a server restart). Bind/firewall/key troubleshooting is on the "Dashboard connectivity" page.

`/dashboard stop` sets a flag until the JVM restarts#

stopDashboard raises the static manuallyDisabled. In the current session auto-start has already happened (it runs only on ServerStartedEvent), so the flag is mostly for status ("override manually disabled"). After a full process restart the flag is false again: if autoStart: true, HTTP comes up by itself even if it was stopped by command in the previous session. start clears the flag. restart cannot bring up a server that is already down — it first prints not_running and suggests start.

What to do: The build ships with autoStart: false — after a server restart you need /dashboard start again, regardless of stop. Do not confuse stop with webDashboard.enabled: false.

pair needs a second node; the URL only in quotes#

The /dashboard root lets OP 2 through via validateAdminPermission. The pair/unpair branch additionally runs validatePermission(neoessentials.dashboard.pair). With opsBypassPermissions: false, an operator without this node can start HTTP, but pair is denied. An unquoted string in Brigadier is [0-9A-Za-z_\-+.]; colon and slash are not allowed, so http://127.0.0.1:3000 without quotes does not parse. A trailing / is stripped from the URL. A non-200 or a body without dashboardToken immediately revokes the dashboard-pairing key.

What to do: Always use /dashboard pair "https://host" CODE. For pair, grant neoessentials.dashboard.pair (or keep the OP bypass on).

/dashboardregister creates a new dashboard user from an online player (token 5 min, username 3–20, password ≥ 8). /linkaccount confirms ownership of a player name for an already existing dashboard user (8-character code, 5 min, no password; needs neoessentials.dashboard.linkaccount). A repeated link while the UUID is already linked is rejected — unlink through the API first. The registration token is lost on server restart (RAM only). The first HTTP start with an empty users collection creates admin with a random password written to the log (Temporary password: …, change it on first login) — this is not /dashboardregister.

What to do: A player without an account — register. An account created in the panel/by an admin — Settings → code → /linkaccount. Lost the admin password — check the boot log or reset via /api/users/{id}/password.

WebSocket can die separately from REST#

Both start and auto-start catch Throwable around WebSocket (a NoClassDefFoundError from a missing Java-WebSocket must not crash the server). HTTP may then be running while live events on websocketPort are not. status/url show only the HTTP URL, not WS.

What to do: If REST is alive but the panel "does not stream", look in the WEB_DASHBOARD log for Failed to start WebSocket server and check that port 8081 is free and differs from the HTTP port.

Known issues#

An unknown role in /apikey create still creates an ADMIN key#

On garbage like admins, parseRole sends sendFailure "expected ADMIN, OPERATOR, MODERATOR, or VIEWER. Defaulting to ADMIN" and returns User.Role.ADMIN. Brigadier then calls create anyway — the key appears and the token is printed. The failure does not roll back the branch.

What to do: Run /apikey list right away: if the role is ADMIN and you wanted VIEWER, /apikey revoke <id> and create it again. Do not take the red line in chat as a sign that no key exists.

/apikey cannot be disabled through the commands section#

The neighbouring dashboard commands check isCommandEnabled. ApiKeyCommand.register does not: with the mod loaded, /apikey is always in the tree, gated only by the neoessentials.dashboard.apikeys node (plus the PermissionAPI OP bypass for players and OP 2 for the console).

What to do: Remove the node from non-admins. The current build cannot disable the command with commands.apikey: false.

Permissions 4#

NodeIn registryWhat it grants
neoessentials.dashboard.accessregistry: noRegister a web dashboard account (/dashboardregister)
neoessentials.dashboard.apikeysregistry: noCreate/list/revoke API keys for external dashboard integrations (/apikey)
neoessentials.dashboard.linkaccountregistry: noLink Minecraft account to an existing dashboard user (/linkaccount)
neoessentials.dashboard.pairregistry: noPair/unpair this server with an external dashboard (/dashboard pair, /dashboard unpair)

Detailed guide#

The section below is the project's original documentation (docs/Wiki/WebDashboard.md). Links to other wiki pages are rewritten to this site; the guides themselves are not edited, so upstream syncs stay conflict-free.

Version: 1.0.5+build.54 · Config: config.json → webDashboard section (dashboard on/off is controlled by both webDashboard.enabled and modules.webDashboardEnabled — either one set to false disables it)


Overview#

NeoEssentials runs an embedded HTTP server (plus a WebSocket server for live updates) exposing a full REST API for server monitoring and administration. There are now two ways to actually use it, controlled by webDashboard.mode:

  • "external" (the shipped default) — the mod serves only /api/*; a separately-hosted dashboard app (the NeoEssentials-Dashboard Laravel project) is the actual browser UI, talking to this API from outside. See API System and docs/API.md for the full REST/WebSocket reference it's built against.
  • "internal" / "both" — the mod serves its own bundled dashboard UI directly from /, no separate app to install at all. As of build.13 this internal UI is feature-complete and covers the same ground as the external app: Overview, Players (with a full per-player control page), Economy, Warps, Kits, Holograms, Discord, dashboard account management, Backups, Commands, Logs, Permissions, a public no-login player-lookup page, and (as of build.15) an account Settings page — see Account Settings & Minecraft Account Linking below. "both" is just an explicit alias for "internal", useful when you deliberately run the built-in UI and point an external app at the same API at the same time.

The account system, permission model, and moderation/economy/etc. backing data described below are shared by both dashboards — they're the same accounts and data either one authenticates against and reads/writes through the API.


Setup#

  1. Set webDashboard.enabled: true and modules.webDashboardEnabled: true in config.json (both default to true)
  2. Configure port (default 8080) and websocketPort (default 8081)
  3. Start the server, then run /dashboard start (webDashboard.autoStart ships false, so the API server doesn't come up on its own unless you set autoStart: true)
  4. Create a credential for whatever's going to call the API: - An external dashboard backend (recommended path): create an API key in-game — /apikey create <label> [role] — and give the printed token to that dashboard's server config. See API System → Authentication for the full picture. - A human dashboard account: register in-game via /dashboardregister start then /dashboardregister complete <username> <password> (or /dashboardregister discord if Simple Discord Link is linked) — or use one of the other paths below.
  5. Point your external dashboard app at http://<server-ip>:<port>/api/... (port from step 2) using the API key or session token as a Bearer token.

Account Registration#

Players register their dashboard account in-game, via the separate /dashboardregister command (not a subcommand of /dashboard) — they do not need to be online at login time after registering.

/dashboardregister start
/dashboardregister complete <username> <password>

Or, if Simple Discord Link, Mc2Discord, or DCIntegration is installed and the player has linked their Discord account:

/dashboardregister discord

Requires permission neoessentials.dashboard.access. Registration tokens from start expire after 5 minutes; passwords must be at least 8 characters. Run /dashboardregister status to check your current registration state.

Other ways to get dashboard access:

  1. API key (for an external dashboard backend, not a human) — /apikey create <label> [role] in-game, or POST /api/apikeys once a first key exists. Not a login account at all; see API System and docs/API.md.
  2. Default admin account — the first time the dashboard starts with no accounts at all, an admin account is auto-created with a random temporary password, printed once to the server console/log (Temporary password: ...) and flagged to require a password change on first login. There is no fixed default password — check the boot log if you've lost it, or reset it via /api/users/{id}/password (admin session) if you still have another admin account.
  3. Minecraft-permission login (self-service, works offline, deprecated) — on the login page, authenticate with just your Minecraft username (no password). The server checks whether that player has neoessentials.dashboard.access and auto-creates an account with role assigned from neoessentials.dashboard.admin/.moderator/.access. Predates the /dashboardregister flow above and is marked deprecated in server logs, but still functional.
  4. Discord OAuth (optional, self-service) — see below. If allowAutoRegistration: true (the default), logging in with Discord auto-creates an account on first use.
  5. Admin-created accounts — an existing admin can create accounts directly via POST /api/users/create (or whatever user-management screen the external dashboard exposes for it), or push-sync one from the external dashboard's own user table with POST /api/users/sync — see docs/API.md.

Discord Auth (Optional)#

If a supported Discord companion mod — Simple Discord Link or Mc2Discord — is installed, players can link their Discord account, and the dashboard can source their Discord identity and roles from it. The mod is fully optional — standalone account registration works without it.


Discord-Linked Dashboard Identity#

NeoEssentials does not talk to Discord's API directly — no bot token, no OAuth2 code exchange, no REST calls to discord.com. All Discord communication is delegated entirely to whichever companion mod is installed (Simple Discord Link or Mc2Discord); NeoEssentials only reads the account-link data that mod already has.

How It Works#

Player links their account in-game (via SDLink's or Mc2Discord's own commands)
         │
         ▼
ChatIntegrationManager.findLinkedDiscordId(uuid)  ── checks whichever companion mod is ready
         │
         ▼
DiscordAuthProvider  ── resolves Discord ID + role IDs for that player
         │
         ▼
Dashboard: GET /api/auth/discord?username=<name>
  1. Look up the linked Discord account
  2. Check blacklist / whitelist roles
  3. Map Discord roles → dashboard role
  4. Get-or-create dashboard user, create session

There is no "Login with Discord" OAuth2 button — a player must first link their account in-game through Simple Discord Link's or Mc2Discord's own linking flow.

Companion mods#

Mod Chat relay Account link lookup Notes
Simple Discord Link (SDLink) ✅ ✅ Real compile-time API (com.hypherionmc.sdlink.api.*), also requires CraterLib
Mc2Discord ✅ ✅ Real compile-time API (fr.denisd3d.mc2discord.core.*)
DCIntegration — (self-relays) ✅ Real compile-time API (de.erdbeerbaerlp.dcintegration.common.*). Relays chat/join/leave/commands to Discord on its own via mixins — NeoEssentials doesn't push those events to it, only reads account links
DiscordSRV ❌ ❌ Not supported — it's a Bukkit/Paper plugin and cannot run on a NeoForge server

Detection is purely runtime (ModList.isLoaded(...)) — neither mod is a hard dependency, and NeoEssentials works fine standalone if neither is installed.

Config (discord_auth.json)#

Located at config/neoessentials/discord_auth.json. Auto-generated on first start.

Key Default Description
enabled false Enable Discord-linked dashboard identity/login
requireLinkedAccount true Require the player's Minecraft account to actually be linked to Discord
allowAutoRegistration true Auto-create a dashboard account on first Discord-linked login
defaultRole VIEWER Dashboard role given when no Discord role is mapped

Role mapping

Discord role IDs (not names) are mapped to dashboard roles. Enable Developer Mode in Discord Settings → Advanced, then right-click a role → Copy ID.

"roleMapping": {
  "123456789012345678": "ADMIN",
  "234567890123456789": "MODERATOR",
  "345678901234567890": "VIEWER"
}

Whitelist / Blacklist

"whitelistedRoles":  ["123456789012345678"],   // only these role IDs can log in (empty = everyone)
"blacklistedUsers":  ["987654321098765432"]    // these Discord user IDs are always denied

Without a Discord companion mod#

If none of SDLink, Mc2Discord, or DCIntegration is installed, GET /api/auth/discord returns 503 — Discord-linked login is unavailable entirely (there's no account-link data to read). Standalone username/password login is unaffected.

Troubleshooting#

Symptom Likely Cause
GET /api/auth/discord/status reports linkAdapterAvailable: false No supported companion mod is installed, or its bot connection isn't ready yet
"No Discord account linked" error Player hasn't linked their account in-game via the companion mod's own command
"does not have a whitelisted role" User doesn't hold one of the whitelistedRoles IDs

Config (config.json → webDashboard)#

Key Default Description
enabled true Enable the dashboard system
autoStart false Start dashboard on server boot. If false (the shipped default), start it manually with /dashboard start
port 8080 HTTP port
websocketPort 8081 WebSocket port for live updates
bindAddress "0.0.0.0" IP to bind (use 127.0.0.1 for local-only)
mode "external" "external" serves only /api/* (default — use with the separate NeoEssentials-Dashboard app). "internal"/"both" also serves the mod's own bundled dashboard UI at / — see Dashboard Connectivity
userSyncWebhookUrl "" (disabled) Optional: POST a notification here whenever a dashboard_user is created/updated/deleted, so an external dashboard can mirror the change into its own user table. See docs/API.md
userSyncWebhookSecret "" HMAC-SHA256 secret for signing the webhook above (X-NeoEssentials-Signature header)
securitySettings.requireAuthentication true Require a Bearer token (session or API key) on dashboard API endpoints
securitySettings.enableRateLimiting true Enable per-IP rate limiting on the dashboard API
securitySettings.maxRequestsPerMinute 60 Max API requests per IP per minute when rate limiting is enabled
securitySettings.publicModerationLookupEnabled true Enable the no-login /api/public/moderation/* routes (see below)
roleSync.enabled false Opt-in: automatically sync a linked player's dashboard role from their real in-game permission — see Dashboard Security above
roleSync.intervalSeconds 300 How often the periodic reconciliation sweep runs, in addition to an immediate check on join
roleSync.adminPermission "neoessentials.admin.dashboard" A player with this permission node is granted the dashboard ADMIN role
roleSync.adminGroup "admin" A player in this permission group is granted the dashboard ADMIN role (checked in addition to, i.e. OR'd with, adminPermission)

The dashboard's on/off switch is now split across two keys that both have to allow it: webDashboard.enabled (this section) and modules.webDashboardEnabled (the mod-wide modules block at the top of config.json, alongside economyEnabled/chatEnabled/etc.). Either one set to false disables the whole dashboard.

The apiSettings, uiSettings, loggingSettings, enableCORS, and maxThreads keys from earlier documentation do not exist in the current codebase — the dashboard's security-related settings live entirely under securitySettings, and there is no config option to disable REST endpoints or config editing independently.


What the Dashboard Can Do#

Both the internal (bundled) and external (Laravel) dashboards cover the same 13 pages, since both are built against the same REST API: Overview (/api/stats + /api/server), Players + full per-player control page (/api/player + /api/moderation), Economy, Warps, Kits, Holograms, Discord, dashboard account management (/api/users), Backups, Commands/console (/api/commands), Logs (/api/logging), Permissions (/api/permissions), and a public no-login player-lookup page. Full endpoint detail in API System → docs/API.md.

Account Settings & Minecraft Account Linking#

Both dashboards have an account Settings/Profile page (the internal one gained this in build.15; it was previously just a disabled "not yet ported" placeholder) covering:

  • Change password — same on both dashboards.
  • Link a Minecraft account — new this pass, and the first way to do this without needing Discord: the Settings page generates a short one-time code, and you type /linkaccount <code> in-game to confirm ownership. Works for any dashboard account regardless of how it was created (self-registered, admin-created, or via /dashboardregister). Self-service unlink is also available. See docs/API.md's /api/auth/link-minecraft/* routes.
  • Discord status — read-only on the internal dashboard (resolved via whichever Discord companion mod is installed — see below); the external dashboard keeps its existing full OAuth2 "Connect Discord" flow. A genuine browser-initiated Discord OAuth2 flow for the internal dashboard (so it gets the same "Connect Discord" button) is a planned follow-up, not built yet — the mod deliberately doesn't perform Discord OAuth2 itself today (see DiscordAuthProvider's own doc comment).
  • Once linked, the sidebar's user avatar on both dashboards shows your actual Minecraft skin instead of a generic icon.

Dashboard Security#

  • /apikey create now prints the generated token as a click-to-copy chat component instead of plain text.
  • The external dashboard's paired auth token (the Bearer token it presents on its outbound account-sync webhook) is now encrypted at rest in config.json (AES-256-GCM) instead of stored in plaintext — existing plaintext values are migrated transparently the next time they're read, no action needed.
  • New opt-in setting, webDashboard.roleSync (off by default): automatically grants a linked player's dashboard account the ADMIN role the moment they have a configured in-game permission node or belong to a configured permission group, and revokes it again the moment they don't — no more manually re-running /apikey create/the API every time an admin's in-game status changes. Runs an immediate check on join plus a periodic sweep, so it also catches permission changes made outside the mod entirely (e.g. a direct LuckPerms edit). Never touches a role that was set manually — it only ever adjusts a role it granted itself.

Moderation API#

The dashboard's moderation endpoints are backed directly by the same manager classes that power the in-game /ban, /mute, /kick, /warn, /note, and /report commands (see Moderation System) — there is no separate dashboard-only ban store, so actions taken here actually enforce in-game and vice versa. The dashboard's own accounts (dashboard_users, dashboard_registrations) are themselves persisted through the same pluggable backend — see Storage Backend.

Route Method Description
/api/moderation/overview GET Summary counts across all moderation categories
/api/moderation/bans/active, /bans, /bans/{uuid} GET Active bans / all bans / a player's ban history
/api/moderation/ban POST Issue a ban
/api/moderation/ban/{uuid} DELETE Unban a player
/api/moderation/ipbans/active, /ipbans GET Active IP bans / all IP ban history
/api/moderation/ipban POST Issue an IP ban
/api/moderation/ipban/{ip} DELETE Unban an IP
/api/moderation/mutes/active, /mutes, /mutes/{name} GET Active mutes / all mutes / a player's mute history
/api/moderation/mute POST Issue a mute
/api/moderation/mute/{name} DELETE Unmute a player
/api/moderation/ipmutes GET All IP mutes
/api/moderation/ipmute POST Issue an IP mute
/api/moderation/ipmute/{ip} DELETE Remove an IP mute
/api/moderation/kicks, /kicks/{name} GET Kick history (all / one player)
/api/moderation/warns, /warns/{name} GET Warnings (all / one player)
/api/moderation/warn/{id} DELETE Remove a warning
/api/moderation/notes/{name} GET A player's staff notes
/api/moderation/note POST Add a staff note
/api/moderation/note/{id} DELETE Remove a staff note
/api/moderation/reports, /reports/all, /reports/{id} GET Pending / all / one report
/api/moderation/reports/{id}/review POST Accept or dismiss a report
/api/moderation/freeze/list GET Currently-frozen players
/api/moderation/freeze POST Freeze a player
/api/moderation/freeze/{name} DELETE Unfreeze a player
/api/moderation/vanish/list GET Currently-vanished players
/api/moderation/vanish POST Vanish/unvanish a player
/api/moderation/vanish/{name} DELETE Force a player visible
/api/moderation/jails, /jail-locations GET Jailed players / configured jail cell locations
/api/moderation/jail, /jail-location POST Jail a player / define a jail cell location
/api/moderation/jail/{name}, /jail-location/{name} DELETE Release a player / remove a jail cell location

All routes above require the standard dashboard Bearer-token authentication (session or API key); mutating routes (POST/DELETE) additionally require the ADMIN role specifically — a MODERATOR-role credential can read but not act.

Public Moderation Lookup (no login required)#

A separate, unauthenticated set of routes — matching ban-management plugins' public transparency page, where anyone can look up a player's punishment history without an account:

Route Method Description
/api/public/moderation/lookup/{name} GET Bans, mutes, kicks, and warns for one player, by name
/api/public/moderation/recent GET Recent active bans + mutes across all players, newest first

These deliberately never expose IP bans, IP mutes, staff notes, or player reports (privacy — notes/reports contain staff commentary and a reporter's identity). Still CORS/rate-limited the same as every other dashboard route, just without the Bearer-token check. Gated by webDashboard.securitySettings.publicModerationLookupEnabled (default true) — set to false to disable public lookup entirely.

Player names in chat show a small clickable ↗ icon that opens that player's public lookup page in a browser. By default this points at whichever NeoEssentials dashboard is actually reachable — the paired external (Laravel) dashboard if you've run /dashboard pair, else the mod's own bundled UI via webDashboard.publicUrl.

If you have your own website instead (a stats page, forum profile, custom fan site), set webDashboard.customProfileUrlTemplate to point the link there instead — it takes priority over both of the above when set:

"customProfileUrlTemplate": "https://myserver.com/players/{player}"

Supports {player} (URL-encoded username) and {uuid} placeholders. Leave empty (the default) to keep using one of the two dashboards.


Commands#

All /dashboard subcommands (including the bare /dashboard) require neoessentials.admin.dashboard — this is checked on the dashboard literal itself, so pair/unpair need it in addition to neoessentials.dashboard.pair listed below (brigadier requires every node from the root down to pass, not just the leaf). Account registration is a separate command tree, /dashboardregister, gated by neoessentials.dashboard.access.

Command Permission Description
/dashboard neoessentials.admin.dashboard Show the REST API + WebSocket server's status
/dashboard start neoessentials.admin.dashboard Start the API server if stopped
/dashboard stop neoessentials.admin.dashboard Stop the API server
/dashboard restart neoessentials.admin.dashboard Restart the API server
/dashboard status neoessentials.admin.dashboard Show the API server's status
/dashboard url neoessentials.admin.dashboard Show the API base URL
/dashboard pair "<dashboardUrl>" <code> neoessentials.dashboard.pair Complete the pairing handshake with an external dashboard — see API System → Pairing
/dashboard unpair neoessentials.dashboard.pair Clear the paired connection and revoke its API key
/dashboardregister neoessentials.dashboard.access Show registration help
/dashboardregister start neoessentials.dashboard.access Begin manual registration (issues a 5-minute token)
/dashboardregister complete <username> <password> neoessentials.dashboard.access Finish manual registration
/dashboardregister discord neoessentials.dashboard.access Register instantly using a linked Discord account (via SDLink, Mc2Discord, or DCIntegration)
/dashboardregister status neoessentials.dashboard.access Check your registration status
/apikey create <label> [role] neoessentials.dashboard.apikeys Create an API key for an external dashboard backend — prints the token once, as a click-to-copy chat component
/apikey list neoessentials.dashboard.apikeys List keys (label/role/enabled/last-used — never the secret)
/apikey revoke <id> neoessentials.dashboard.apikeys Revoke a key immediately
/linkaccount <code> none — open to everyone Finish linking your Minecraft account to a dashboard account, using the code shown on that account's Settings page

/apikey is a separate command tree from /dashboard//dashboardregister — see API System → Authentication for the full picture of what these keys are for and how they differ from a human dashboard account. /linkaccount is the reverse direction of /dashboardregister — it links an MC account to an existing dashboard account (started from the dashboard's own Settings page), rather than creating a brand-new dashboard account starting from an in-game player.


Permissions#

Node Default Description
neoessentials.dashboard.access 🔒 Register an account and log in to the dashboard (/dashboardregister)
neoessentials.dashboard.view 🔒 View dashboard (read-only)
neoessentials.dashboard.manage 🔒 Access console and management tools
neoessentials.dashboard.moderator 🔒 Moderator-level dashboard access
neoessentials.dashboard.admin 🔒 Full admin dashboard access
neoessentials.admin.dashboard 🔒 Start/stop/manage the API server (/dashboard)
neoessentials.dashboard.apikeys 🔒 Create/list/revoke API keys for external dashboard integrations (/apikey)
neoessentials.dashboard.pair 🔒 Pair/unpair this server with an external dashboard (/dashboard pair, /dashboard unpair)

Unlike most permission nodes documented on the Permission System page, the dashboard nodes above (other than neoessentials.dashboard.apikeys/.pair, which are registered) are not pre-registered in PermissionRegistry — they're checked ad hoc, so grant them explicitly to non-OP groups rather than relying on a documented default.

As of build.16, /help <command> shows each command's real permission node (this table included) instead of guessing neoessentials.<commandname> — that guess used to be wrong for /apikey specifically (it showed neoessentials.apikey instead of the real neoessentials.dashboard.apikeys), and for roughly 160 other commands mod-wide.


Back to Wiki Home