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

REST API

The dedicated server exposes an HTTP REST API (port 8080 by default, see API_PORT) for monitoring and controlling your server programmatically.

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:

VariableDescriptionDefault
API_ENABLEDEnable/disable the APItrue
API_PORTPort for the API server8080
API_KEYAPI key for write endpoints(empty = no auth)

Authentication

When API_KEY is set, all endpoints require authentication via the Authorization header:

Authorization: Bearer <your-api-key>

Public Endpoints

These endpoints remain accessible without authentication:

EndpointPurpose
/healthHealth checks for monitoring tools
/docsAPI documentation UI
/swagger/v1/swagger.jsonOpenAPI specification

Example

sh
# Without auth (will fail if API_KEY is set)
curl "http://localhost:8080/status"

# With auth
curl "http://localhost:8080/status" \
  -H "Authorization: Bearer your-api-key"

Generate a Secure Key

sh
openssl rand -base64 32

WebSocket

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/ws

Authentication

When API_KEY is set, WebSocket clients must authenticate within 10 seconds of connecting:

javascript
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:

json
{
  "type": "message_type",
  "payload": { ... }
}

Message Types

Client → Server

TypeDescriptionPayload
authAuthenticate (required first if API_KEY set){ "token": "api-key" }
pingHeartbeatNone
chat_sendSend chat message to game{ "author": "Name", "message": "Hello" }

Server → Client

TypeDescriptionPayload
auth_successAuthentication successfulNone
auth_failedAuthentication failed{ "error": "reason" }
pongHeartbeat responseNone
chatPlayer chat message from game{ "playerName": "Name", "message": "Hello", "timestamp": "ISO8601" }

Example

javascript
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.

sh
# 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.

sh
# 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.

sh
# 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.

sh
# 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

Released under the MIT License.