Complete guide to the REST API for remote Minecraft server management.
The REST API provides HTTP endpoints for:
- Server control (start, stop, restart, commands)
- Server status and metrics
- Player management
- Backup operations
- World management
- Plugin management
- Configuration file management
- Log access
- User authentication and authorization
- API key management
- Dynamic DNS management
-
Configure API:
# Edit config/api.conf API_ENABLED=true API_HOST=127.0.0.1 API_PORT=8080 -
Create API Key:
./scripts/api-key-manager.sh create webhook "Webhook integration" -
Start API Server:
./scripts/api-server.sh start
-
Test API:
curl -H "X-API-Key: YOUR_API_KEY" http://localhost:8080/api/health
- Local:
http://localhost:8080 - Raspberry Pi:
http://minecraft-server.local:8080 - Production:
https://your-domain.com:8080
The API supports three authentication methods. All endpoints (except /api/health) require authentication.
Header Method (Recommended):
curl -H "X-API-Key: YOUR_API_KEY" http://localhost:8080/api/statusQuery Parameter Method:
curl http://localhost:8080/api/status?api_key=YOUR_API_KEY# Login to get token
TOKEN=$(curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}' \
| jq -r '.token')
# Use token
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/status# Login (creates session)
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}' \
-c cookies.txt
# Use session
curl -b cookies.txt http://localhost:8080/api/statusCreate API Key:
./scripts/api-key-manager.sh create <name> [description]List API Keys:
./scripts/api-key-manager.sh listDisable API Key:
./scripts/api-key-manager.sh disable <key-preview>Enable API Key:
./scripts/api-key-manager.sh enable <key-preview>Delete API Key:
./scripts/api-key-manager.sh delete <key-preview>For more details, see API Keys Guide.
The API is documented using OpenAPI 3.0 specification:
- File:
api/openapi.yaml - Format: YAML
- Version: 3.0.3
- Go to Swagger Editor
- Copy contents of
api/openapi.yaml - Paste into editor
- View interactive documentation
# Serve with Docker
docker run -d \
--name swagger-ui \
-p 8081:8080 \
-e SWAGGER_JSON=/openapi.yaml \
-v $(pwd)/api/openapi.yaml:/openapi.yaml:ro \
swaggerapi/swagger-ui
# Open in browser
open http://localhost:8081# Serve API docs
./scripts/serve-api-docs.sh
# Or with custom port
PORT=9000 ./scripts/serve-api-docs.sh# Serve with Redoc
docker run -d \
--name redoc \
-p 8081:80 \
-v $(pwd)/api/openapi.yaml:/usr/share/nginx/html/openapi.yaml:ro \
redocly/redoc
# Open in browser
open http://localhost:8081GET /api/health
Check if API is running (no authentication required).
Response:
{
"status": "healthy",
"timestamp": "2025-01-15T10:30:00.000000",
"version": "1.0.0"
}POST /api/auth/register- Register new userPOST /api/auth/login- Login userPOST /api/auth/logout- Logout userGET /api/auth/me- Get current user
GET /api/status
Get server status.
Response:
{
"running": true,
"status": "Up 2 hours",
"timestamp": "2025-01-15T10:30:00.000000"
}POST /api/server/start
Start the server.
Response:
{
"success": true,
"message": "Server starting",
"output": "..."
}POST /api/server/stop
Stop the server.
Response:
{
"success": true,
"message": "Server stopping",
"output": "..."
}POST /api/server/restart
Restart the server.
Response:
{
"success": true,
"message": "Server restarting",
"output": "..."
}POST /api/server/command
Send a command to the server via RCON.
Request Body:
{
"command": "list"
}Response:
{
"success": true,
"response": "There are 2 of a max of 10 players online: Player1, Player2",
"command": "list"
}Example Commands:
"list"- List online players"say Hello World"- Send message"whitelist add PlayerName"- Add to whitelist"op PlayerName"- Grant operator status"save-all"- Save world
POST /api/backup
Create a server backup.
Response:
{
"success": true,
"message": "Backup created",
"output": "..."
}GET /api/backups
List all backups.
Response:
{
"backups": [
{
"name": "minecraft_backup_20250115_103000.tar.gz",
"size": 104857600,
"created": "2025-01-15T10:30:00"
}
],
"count": 1
}POST /api/backups/{filename}/restore - Restore backup
DELETE /api/backups/{filename} - Delete backup
GET /api/players
Get list of online players.
Response:
{
"players": ["Player1", "Player2"],
"count": 2
}GET /api/worlds
List all worlds.
Response:
{
"worlds": ["world", "survival", "creative"],
"count": 3
}GET /api/plugins
List installed plugins.
Response:
{
"plugins": ["EssentialsX", "WorldEdit"],
"count": 2
}GET /api/config/files- List configuration filesGET /api/config/files/{filename}- Get configuration filePOST /api/config/files/{filename}- Update configuration filePOST /api/config/files/{filename}/validate- Validate configuration file
GET /api/logs?lines=100
Get server logs.
Query Parameters:
lines- Number of lines to retrieve (default: 100)
Response:
{
"logs": [
"[10:30:00] [Server thread/INFO] Starting minecraft server",
"[10:30:01] [Server thread/INFO] Done!"
],
"lines": 2
}GET /api/metrics
Get server metrics.
Response:
{
"metrics": {
"cpu_percent": "45.2",
"memory_usage": "1.2GiB / 2.0GiB",
"memory_percent": "60.0"
},
"timestamp": "2025-01-15T10:30:00.000000"
}GET /api/keys- List API keysPOST /api/keys- Create API keyDELETE /api/keys/{key_id}- Delete API keyPUT /api/keys/{key_id}/enable- Enable API keyPUT /api/keys/{key_id}/disable- Disable API key
GET /api/users- List usersPUT /api/users/{username}/role- Update user roleDELETE /api/users/{username}- Delete userPUT /api/users/{username}/enable- Enable userPUT /api/users/{username}/disable- Disable user
For more details, see RBAC Guide.
GET /api/ddns/status- Get DDNS statusPOST /api/ddns/update- Update DDNSGET /api/ddns/config- Get DDNS configurationPOST /api/ddns/config- Update DDNS configuration
For more details, see Dynamic DNS Guide.
import requests
API_URL = "http://localhost:8080/api"
API_KEY = "your-api-key"
headers = {"X-API-Key": API_KEY}
# Get server status
response = requests.get(f"{API_URL}/status", headers=headers)
status = response.json()
print(f"Server running: {status['running']}")
# Send command
response = requests.post(
f"{API_URL}/server/command",
headers=headers,
json={"command": "list"}
)
result = response.json()
print(result['response'])
# Start server
response = requests.post(f"{API_URL}/server/start", headers=headers)
print(response.json())# Set API key
API_KEY="your-api-key"
API_URL="http://localhost:8080/api"
# Get status
curl -H "X-API-Key: $API_KEY" "$API_URL/status"
# Send command
curl -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"command":"list"}' \
"$API_URL/server/command"
# Create backup
curl -X POST \
-H "X-API-Key: $API_KEY" \
"$API_URL/backup"const axios = require('axios');
const API_URL = 'http://localhost:8080/api';
const API_KEY = 'your-api-key';
const api = axios.create({
baseURL: API_URL,
headers: {
'X-API-Key': API_KEY,
},
});
// Get server status
async function getStatus() {
const response = await api.get('/status');
console.log(response.data);
}
// Send command
async function sendCommand(command) {
const response = await api.post('/server/command', { command });
console.log(response.data.response);
}
// Start server
async function startServer() {
const response = await api.post('/server/start');
console.log(response.data);
}{
"success": true,
"message": "Operation completed",
"data": { ... }
}All endpoints return standard HTTP status codes:
200 OK- Request successful201 Created- Resource created400 Bad Request- Invalid request401 Unauthorized- Missing or invalid API key403 Forbidden- Insufficient permissions404 Not Found- Endpoint not found500 Internal Server Error- Server error
Error Response Format:
{
"error": "Error message",
"code": "ERROR_CODE"
}./scripts/api-server.sh start./scripts/api-server.sh stop./scripts/api-server.sh restart./scripts/api-server.sh status./scripts/api-server.sh logs./scripts/api-server.sh install-depsEdit config/api.conf:
# Enable/disable API
API_ENABLED=true
# API host (127.0.0.1 for localhost only, 0.0.0.0 for all interfaces)
API_HOST=127.0.0.1
# API port
API_PORT=8080
# Enable CORS
CORS_ENABLED=true- Use Strong API Keys: Let the system generate keys
- Restrict Access: Use
127.0.0.1for localhost-only access - HTTPS: Use reverse proxy (nginx) with SSL for production
- Firewall: Don't expose API port to internet
- Key Rotation: Regularly rotate API keys
- Disable Unused Keys: Disable keys that are no longer needed
Localhost Only (Recommended):
API_HOST=127.0.0.1Local Network:
API_HOST=0.0.0.0
# Use firewall to restrict accessWith Reverse Proxy:
# nginx configuration
location /api {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}Currently, the API does not implement rate limiting. For production use:
- Implement rate limiting in reverse proxy
- Monitor API usage
- Set appropriate limits per API key
CORS is enabled for all origins by default. Configure in config/api.conf for production to restrict origins.
import requests
import discord
API_URL = "http://localhost:8080/api"
API_KEY = "your-api-key"
@bot.command()
async def server_status(ctx):
response = requests.get(
f"{API_URL}/status",
headers={"X-API-Key": API_KEY}
)
status = response.json()
await ctx.send(f"Server: {'Online' if status['running'] else 'Offline'}")#!/bin/bash
# monitor-api.sh
API_URL="http://localhost:8080/api"
API_KEY="your-api-key"
# Check server status
STATUS=$(curl -s -H "X-API-Key: $API_KEY" "$API_URL/status" | jq -r '.running')
if [ "$STATUS" = "false" ]; then
echo "Server is down! Starting..."
curl -X POST -H "X-API-Key: $API_KEY" "$API_URL/server/start"
fi#!/bin/bash
# webhook-example.sh
API_URL="http://localhost:8080/api"
API_KEY="your-api-key"
# Player joined webhook
curl -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"command":"say New player joined!"}' \
"$API_URL/server/command"Use OpenAPI Generator:
# Generate Python client
openapi-generator generate \
-i api/openapi.yaml \
-g python \
-o clients/python
# Generate JavaScript client
openapi-generator generate \
-i api/openapi.yaml \
-g javascript \
-o clients/javascript# Install swagger-cli
npm install -g @apidevtools/swagger-cli
# Validate
swagger-cli validate api/openapi.yamlWhen adding new endpoints:
- Update
api/openapi.yamlwith new endpoint - Add request/response schemas
- Update this documentation
- Test with Swagger UI
Check Python:
python3 --versionInstall Dependencies:
./scripts/api-server.sh install-depsCheck Logs:
./scripts/api-server.sh logs
cat logs/api-server.logVerify API Key:
./scripts/api-key-manager.sh listCheck Key is Enabled:
./scripts/api-key-manager.sh enable <key-preview>Check API is Running:
./scripts/api-server.sh statusCheck Port:
netstat -tlnp | grep 8080Check Configuration:
cat config/api.conf- QUICK_REFERENCE.md - Command reference
- API_KEYS.md - API key management
- RBAC.md - Role-based access control
- RCON.md - RCON guide
- DYNAMIC_DNS.md - Dynamic DNS integration
- TROUBLESHOOTING.md - Troubleshooting guide