⚠️ The latest release is unstable. Use preview builds instead
Skip to content

Public Server Status ​

The API's /status endpoint reports whether the server is online, how many players are connected, the current invite codes, and the in-game date. It needs no API key, so a web page can read it directly and show your players a live status card.

What /status exposes ​

The endpoint returns the fields documented in the API reference. The invite codes look sensitive but are public information: JunimoServer forces the lobby public, so the code alone never gates entry. Turn on password protection before publishing the status anywhere. Every other endpoint stays behind API_KEY.

The HTTPS requirement ​

A browser on an HTTPS page refuses to fetch plain http://<ip>:8080/status, so the API needs an HTTPS URL. HTTPS & Reverse Proxy sets that up, with or without a domain; the status URL is then the server's proxy URL plus /status. Cross-origin reads are already allowed, so nothing else is needed.

Embedding the widget ​

VitePress sites ​

Copy ServerStatusWidget.vue and the state mapping it imports, serverState.ts, into your theme and point the widget's import at the copied file. Register the component in enhanceApp and place it on a page:

md
<ServerStatusWidget api-url="https://203.0.113.10/farm" />

Props:

PropDescriptionDefault
api-urlHTTPS base URL of the API; the widget fetches /status under itrequired
refresh-intervalPoll interval in milliseconds; 0 disables polling30000

The header shows the server's SERVER_NAME, else the farm name, the same rule the Discord bot uses for its nickname. The widget reports the same states as the bot: Online (isOnline and isReady), Busy (isOnline but saving, changing day, or running an event), Starting (isOnline false: the container is downloading game files, launching the game, or loading the save), and Offline (the request failed). It also shows the image and Stardew versions, the in-game clock, the measured tick rate, the browser's round-trip to the API, and the uptime beside the Online badge. The top accent line fills over one refresh interval, and a reload resumes the cycle from the last poll.

Anywhere else ​

The whole contract is one fetch:

js
const res = await fetch("https://203.0.113.10/farm/status", { cache: "no-store" });
if (!res.ok) throw new Error("unreachable");
const status = await res.json();
// status.isOnline, status.isReady, status.phase ("downloading" or "starting" before the game runs),
// status.playerCount, status.maxPlayers,
// status.steamInviteCode (null until the Steam lobby is published), status.gogInviteCode,
// status.farmName, status.serverName (SERVER_NAME, empty when unset),
// status.season, status.day, status.year, status.timeOfDay,
// status.serverVersion (the running image version), status.gameVersion,
// status.tps (measured game ticks per second, a 30-second average),
// status.startedAtUtc (when the server process started; null until known)

Released under the MIT License. Not affiliated with or endorsed by ConcernedApe LLC.