REST API
The dedicated server exposes an HTTP REST API (port 8080 by default, see API_PORT) for monitoring and controlling your server programmatically. Behind the optional HTTPS proxy the same API is served under the server's proxy URL.
Use the sidebar to browse available endpoints.
Endpoint Overview
The API provides endpoints for:
- Server: Status, health checks, rendering control
- Players: Connected players and invite codes
- Farmhands: Farmhand slot management
- Settings: Server configuration from
server-settings.json - Cabins: Cabin state and positions
- Time: In-game time control
Configuration
The API is enabled by default. Configure via environment variables:
| Variable | Description | Default |
|---|---|---|
API_ENABLED | Enable/disable the API | true |
API_PORT | Port for the API server | 8080 |
API_KEY | API key required by authenticated endpoints | (empty = no auth; startup then requires ALLOW_INSECURE_SETUP=true) |
Authentication
If API_KEY is set, send it with every request:
Authorization: Bearer <your-api-key>Each endpoint page in this reference says whether it needs the key. Health, status and the docs pages work without one. To show /status on a website, see Public Server Status.
Example
# Without auth (will fail if API_KEY is set)
curl "http://localhost:8080/players"
# With auth
curl "http://localhost:8080/players" \
-H "Authorization: Bearer your-api-key"Generate a Secure Key
openssl rand -base64 32WebSocket
The server also provides a WebSocket endpoint at /ws for real-time bidirectional communication, primarily used for chat relay with the Discord bot.
Connection
ws://localhost:8080/wsAuthentication
When API_KEY is set, WebSocket clients must authenticate within 10 seconds of connecting:
const ws = new WebSocket("ws://localhost:8080/ws");
ws.onopen = () => {
// Send auth message immediately after connecting
ws.send(JSON.stringify({
type: "auth",
payload: { token: "your-api-key" }
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "auth_success") {
console.log("Authenticated!");
// Now you can send/receive messages
}
if (msg.type === "auth_failed") {
console.error("Auth failed:", msg.error);
// Connection will be closed by server
}
};Message Format
All messages are JSON with a type field and optional payload:
{
"type": "message_type",
"payload": { ... }
}Message Types
Client → Server
| Type | Description | Payload |
|---|---|---|
auth | Authenticate (required first if API_KEY set) | { "token": "api-key" } |
ping | Heartbeat | None |
chat_send | Send chat message to game | { "author": "Name", "message": "Hello" } |
Server → Client
| Type | Description | Payload |
|---|---|---|
auth_success | Authentication successful | None |
auth_failed | Authentication failed | { "error": "reason" } |
pong | Heartbeat response | None |
chat | Player chat message from game | { "playerName": "Name", "message": "Hello", "timestamp": "ISO8601" } |
Example
const ws = new WebSocket("ws://localhost:8080/ws");
ws.onopen = () => {
// Authenticate first (if API_KEY is set)
ws.send(JSON.stringify({
type: "auth",
payload: { token: "your-api-key" }
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "auth_success") {
// Start heartbeat after auth
setInterval(() => {
ws.send(JSON.stringify({ type: "ping" }));
}, 30000);
}
if (msg.type === "chat") {
console.log(`${msg.payload.playerName}: ${msg.payload.message}`);
}
};
// Send chat to game (after authenticated)
ws.send(JSON.stringify({
type: "chat_send",
payload: { author: "Discord User", message: "Hello from Discord!" }
}));POST Endpoint Parameters
POST endpoints accept parameters via query string. All write endpoints require authentication when API_KEY is set.
POST /rendering
Set the server render rate. fps=0 disables rendering; fps=N (N > 0) renders at N fps.
# Enable rendering at 15 fps
curl -X POST "http://localhost:8080/rendering?fps=15" \
-H "Authorization: Bearer $API_KEY"
# Disable rendering
curl -X POST "http://localhost:8080/rendering?fps=0" \
-H "Authorization: Bearer $API_KEY"POST /time
Set the game time of day.
# Set time to noon (1200)
curl -X POST "http://localhost:8080/time?value=1200" \
-H "Authorization: Bearer $API_KEY"
# Set time to 6 PM (1800)
curl -X POST "http://localhost:8080/time?value=1800" \
-H "Authorization: Bearer $API_KEY"Valid range: 600 (6 AM) to 2600 (2 AM next day).
POST /roles/admin
Grant admin role to a player. Accepts exactly one of name (player name) or playerId (UniqueMultiplayerID). Providing both, or neither, returns a 400.
# By name (ergonomic for manual/CLI use)
curl -X POST "http://localhost:8080/roles/admin?name=PlayerName" \
-H "Authorization: Bearer $API_KEY"
# By player ID (stable for automation/tooling — name sync can lag behind player joins)
curl -X POST "http://localhost:8080/roles/admin?playerId=620826087702429092" \
-H "Authorization: Bearer $API_KEY"DELETE /farmhands
Delete a farmhand. The farmhand must be offline. Accepts exactly one of name or playerId. Providing both, or neither, returns a 400.
# By name
curl -X DELETE "http://localhost:8080/farmhands?name=FarmhandName" \
-H "Authorization: Bearer $API_KEY"
# By player ID
curl -X DELETE "http://localhost:8080/farmhands?playerId=620826087702429092" \
-H "Authorization: Bearer $API_KEY"Use Cases
- Discord bots (chat relay, server status)
- Monitoring tools
- Web dashboards
- Automation scripts