{% extends "base.html" %} {# --- Page Title --- #} {% block title %}API Documentation - {{ super() }}{% endblock %} {# --- Specific Styles for API Docs --- #} {% block head_styles %} {# Add specific styles for API docs elements on top of base CSS #} {% endblock %} {# --- Main Content Area --- #} {% block content %}
This document outlines the available HTTP API endpoints for interacting with the Bedrock Server Manager.
{# --- Introduction Section (copied from MD) --- #}All endpoint paths are relative to the base URL where the manager's web server is running. Replace http://<your-manager-host>:<port>
with the actual address. The default port is 11325
(configurable via the WEB_PORT
setting).
Most API endpoints require authentication. This is done by providing a JSON Web Token (JWT) obtained from the /api/login
endpoint. Include the token in the Authorization
header as a Bearer token:
Authorization: Bearer YOUR_JWT_TOKEN
The token expiration duration is configurable via the TOKEN_EXPIRES_WEEKS
setting, defaulting to 4 weeks.
For requests that include data in the body (POST, PUT), the Content-Type
header should be set to application/json
. Responses from the API will typically have a Content-Type
of application/json
.
200 OK
, 201 Created
with a JSON body like:
{
"status": "success",
"message": "Operation completed successfully.",
"data_key": "optional_data"
}
(Specific data_key
names vary by endpoint)
4xx
(Client Error) or 5xx
(Server Error) with a JSON body like:
{
"status": "error",
"message": "A description of the error.",
"errors": { // Optional: Field-specific validation errors
"field_name": "Specific error for this field."
}
}
Common error codes:
400 Bad Request
: Invalid input, missing parameters, validation failed, invalid format (e.g., not JSON).401 Unauthorized
: Authentication token missing or invalid (for JWT protected routes).403 Forbidden
: Authenticated user lacks permission (or OS mismatch for platform-specific endpoints like scheduling).404 Not Found
: Server, task, file, or endpoint not found.500 Internal Server Error
: An unexpected error occurred on the server during processing (e.g., file operation failure, configuration issue).501 Not Implemented
: Feature not supported on the current OS (e.g., sending commands on Windows).To enhance robustness and provide immediate feedback, the application implements a global pre-request validation check. This check runs before the actual route handler for most requests involving a specific server instance.
@app.before_request
decorator./server/<server_name>/
, where <server_name>
is a segment in the path./server/MyServer/status_info
, /api/server/AnotherServer/stop
, /server/MyServer/backups/prune
./server/install
/api/server/install
<server_name>
segment is extracted.validate_server_exist
(which checks for the existence of the server's directory and executable) is called with the extracted server_name
.validate_server_exist
determines the outcome.validate_server_exist
confirms the server exists ({"status": "success", ...}
), the before_request
handler does nothing, and the request proceeds normally to its intended route handler.validate_server_exist
indicates the server does not exist ({"status": "error", "message": "..."}
):
/api/
): The request is aborted, and a 404 Not Found
response is immediately returned with a JSON body:
{
"status": "error",
"message": "Server '<server_name>' not found." // Or more specific message from validator
}
302 Found
) to the main dashboard page (/
). A flash message containing the error (e.g., "Server '<server_name>' not found.") is typically displayed on the dashboard.500 Internal Server Error
response is returned with a JSON body:
{
"status": "error",
"message": "Internal server error during server validation." // Or similar generic message
}
/api/server/<server_name>/...
for a server name that does not actually exist will result in an immediate 404 Not Found
response from this pre-validation step, rather than potentially reaching the endpoint handler and returning a different error.server_name
used in API calls corresponds to a valid, existing server instance./api/login
- API LoginAuthenticates using username and password provided in the JSON body and returns a JWT access token upon success. Credentials must match the BEDROCK_SERVER_MANAGER_USERNAME
and BEDROCK_SERVER_MANAGER_PASSWORD
environment variables (password must be the hashed value).
This endpoint is exempt from CSRF protection.
None required for this endpoint.
application/json
):{
"username": "your_web_ui_username",
"password": "your_web_ui_password"
}
username
(string)(Required): The username configured via the BEDROCK_SERVER_MANAGER_USERNAME
environment variable.password
(string)(Required): The plain-text password corresponding to the hashed password configured via the BEDROCK_SERVER_MANAGER_PASSWORD
environment variable.Returns a JSON object containing the JWT access token.
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
400 Bad Request
:
{"message": "Request must be JSON"}
username
or password
field is missing: {"message": "Missing username or password parameter"}
401 Unauthorized
:
{"message": "Bad username or password"}
500 Internal Server Error
:
{"message": "Server configuration error prevents login."}
curl
Example (Bash):curl -X POST -H "Content-Type: application/json" \
-d '{"username": "your_username", "password": "your_password"}' \
http://<your-manager-host>:<port>/api/login
$body = @{ username = 'your_username'; password = 'your_password' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/login" -Body $body -ContentType 'application/json'
/api/server/{server_name}/world_name
- Get World NameGets the configured world name (level-name
property) from the server.properties
file for the specified server.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT via Authorization: Bearer <token>
header, or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returns the world name if found successfully.
{
"status": "success",
"world_name": "Bedrock level"
}
status
: Always "success".world_name
: The value of the level-name
property from the server's server.properties
file.400 Bad Request
:
server_name
is invalid (e.g., empty). Message comes from the exception (e.g., {"status": "error", "message": "Server name cannot be empty."}
).401 Unauthorized
:
{"error": "Unauthorized", "message": "Authentication required."}
).500 Internal Server Error
:
server.properties
not found/readable or level-name
missing: {
"status": "error",
"message": "Failed to get world name: File not found: /path/to/servers/MyServer/server.properties"
}
or {
"status": "error",
"message": "Failed to get world name: Property 'level-name' not found in /path/to/servers/MyServer/server.properties"
}
{
"status": "error",
"message": "Failed to get world name: Base directory '/invalid/path' not found or accessible."
}
{"status": "error", "message": "Unexpected error getting world name."}
curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/world_name
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/world_name" -Headers $headers
/api/server/{server_name}/running_status
- Get Running StatusChecks if the Bedrock server process for the specified server instance is currently running.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT via Authorization: Bearer <token>
header, or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returns the running status of the server.
{
"status": "success",
"is_running": true
}
or
{
"status": "success",
"is_running": false
}
status
: Always "success".is_running
: Boolean indicating whether the server process was found.400 Bad Request
:
server_name
is invalid (e.g., empty): {"status": "error", "message": "Server name cannot be empty."}
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
): {"status": "error", "message": "Configuration error: Base directory '/invalid/path' not found or accessible."}
.{"status": "error", "message": "Unexpected error checking running status."}
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/running_status
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/running_status" -Headers $headers
/api/server/{server_name}/config_status
- Get Config StatusGets the status string stored within the server's specific configuration file (config/{server_name}.json
). Reflects the server's intended or last known state (e.g., "Installed", "Stopped").
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returns the status string from the configuration file.
{
"status": "success",
"config_status": "Installed"
}
status
: Always "success".config_status
: The string value from the server's JSON configuration file (might be "UNKNOWN" if missing).400 Bad Request
:
server_name
is invalid: {"status": "error", "message": "Server name cannot be empty."}
.401 Unauthorized
:
500 Internal Server Error
:
{"status": "error", "message": "Error retrieving config status: File not found: /path/to/config/MyServer.json"}
or {"status": "error", "message": "Error retrieving config status: Permission denied accessing /path/to/config/MyServer.json"}
.{"status": "error", "message": "Unexpected error getting config status."}
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/config_status
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/config_status" -Headers $headers
/api/server/{server_name}/version
- Get Installed VersionGets the installed Bedrock server version string stored within the server's specific configuration file (config/{server_name}.json
).
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returns the installed version string from the configuration file.
{
"status": "success",
"installed_version": "1.20.81.01"
}
status
: Always "success".installed_version
: The string value from the server's JSON configuration file (might be "UNKNOWN").400 Bad Request
:
server_name
is invalid: {"status": "error", "message": "Server name cannot be empty."}
.401 Unauthorized
:
500 Internal Server Error
:
{"status": "error", "message": "Error retrieving installed version: File not found: /path/to/config/MyServer.json"}
or {"status": "error", "message": "Error retrieving installed version: Permission denied accessing /path/to/config/MyServer.json"}
.{"status": "error", "message": "Unexpected error getting installed version."}
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/version
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/version" -Headers $headers
/api/server/{server_name}/validate
- Validate Server ExistenceValidates if the server directory and the main executable (bedrock_server
) exist for the specified server name within the configured BASE_DIR
.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to validate.None.
Returned when both the server directory and the executable are found.
{
"status": "success",
"message": "Server '<server_name>' exists and is valid."
}
400 Bad Request
:
server_name
is invalid: {"status": "error", "message": "Server name cannot be empty."}
.401 Unauthorized
:
404 Not Found
:
{"status": "error", "message": "Server directory '/path/to/servers/MyServer' not found."}
or {"status": "error", "message": "Server executable '/path/to/servers/MyServer/bedrock_server' not found."}
.500 Internal Server Error
:
BASE_DIR
): {"status": "error", "message": "Configuration error: Base directory '/invalid/path' not found or accessible."}
.{"status": "error", "message": "Unexpected error validating server."}
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/validate
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/validate" -Headers $headers
/api/server/{server_name}/status_info
- Get Server Status InfoRetrieves runtime status information for a specific server process, including running state and basic resource usage (PID, CPU, Memory, Uptime) if the process is active and accessible.
Note on CPU Usage: CPU percentage is calculated based on the change in CPU time since the last request to this endpoint for any server. The first request after the manager starts or after a period of inactivity will report 0.0% CPU. Subsequent calls provide a more accurate reading. Accuracy might be limited on Linux when using screen
.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returned regardless of whether the server is running or not.
{
"status": "success",
"process_info": {
"pid": 12345,
"cpu_percent": 10.5,
"memory_mb": 512.5,
"uptime": "1:00:00"
}
}
status
: "success"process_info
(*object*): Details of the running process (PID, CPU%, Memory MB, Uptime string).{
"status": "success",
"process_info": null,
"message": "Server '<server_name>' is not running."
}
status
: "success"process_info
: `null`message
: Indicates server not running.400 Bad Request
:
server_name
is invalid: {"status": "error", "message": "Invalid input: Server name cannot be empty."}
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
): {"status": "error", "message": "Server configuration error: BASE_DIR setting is missing or empty in configuration."}
.{"status": "error", "message": "Error getting process info: 'psutil' is required for process monitoring."}
.{"status": "error", "message": "Error getting process info: Error getting process details for '<server_name>': ..."}
.{"status": "error", "message": "An unexpected error occurred: <original error message>"}
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/status_info
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/status_info" -Headers $headers
/api/server/{server_name}/start
- Start ServerStarts the specified Bedrock server instance process. Uses systemd (with screen fallback) on Linux or direct process creation on Windows. Waits for confirmation that the server process is running.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to start.None.
Returned when the server process is successfully initiated and confirmed running.
{
"status": "success",
"message": "Server '<server_name>' started successfully."
}
400 Bad Request
:
server_name
: {"status": "error", "message": "Invalid input: Server name cannot be empty."}
.401 Unauthorized
:
404 Not Found
:
{"status": "error", "message": "Server not found: Server executable 'bedrock_server.exe' not found in C:\\path\\to\\servers\\MyServer"}
.500 Internal Server Error
:
BASE_DIR
): {"status": "error", "message": "Server configuration error: BASE_DIR setting is missing or empty in configuration."}
.{"status": "error", "message": "Failed to start server '<server_name>': Server '<server_name>' is already running."}
.{"status": "error", "message": "Failed to start server '<server_name>': Unsupported operating system: Darwin"}
or {"status": "error", "message": "Failed to start server '<server_name>': Failed to start server executable 'C:\\path\\to\\bedrock_server.exe': [WinError 5] Access is denied"}
or {"status": "error", "message": "Failed to start server '<server_name>': Failed to start server '<server_name>' using screen. Error: Must be connected to a terminal."}
.systemctl
, screen
): {"status": "error", "message": "Failed to start server '<server_name>': Command 'screen' not found in system PATH."}
.{"status": "error", "message": "Failed to start server '<server_name>': Server '<server_name>' failed to start within the timeout."}
.{"status": "error", "message": "An unexpected error occurred: <original error message>"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/start
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/start" -Headers $headers
/api/server/{server_name}/stop
- Stop ServerStops the specified running Bedrock server instance. Attempts graceful shutdown (Linux) or terminates (Windows). Waits for termination.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to stop.None.
Returned if server stops successfully or was already stopped.
{
"status": "success",
"message": "Server '<server_name>' stopped successfully."
}
or
{
"status": "success",
"message": "Server '<server_name>' was already stopped."
}
400 Bad Request
:
server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
).{"status": "error", "message": "Failed to stop server '<server_name>': Error sending command: Failed to find screen session 'bedrock-<server_name>' to send command to."}
.{"status": "error", "message": "Server '<server_name>' process found but executable missing. Stop failed."}
.{"status": "error", "message": "Failed to stop server '<server_name>': Server '<server_name>' failed to stop within the timeout. Manual intervention may be required."}
.{"status": "error", "message": "Failed to stop server '<server_name>': Stopping via systemctl failed (maybe service wasn't running under systemd?): ..."}
or {"status": "error", "message": "Failed to stop server '<server_name>': Unexpected error stopping server '<server_name>': ..."}
.systemctl
, screen
): {"status": "error", "message": "Failed to stop server '<server_name>': Command 'screen' not found in system PATH."}
.501 Not Implemented
:
{"status": "error", "message": "Failed to stop server '<server_name>': Unsupported operating system: Darwin"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/stop
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/stop" -Headers $headers
/api/server/{server_name}/restart
- Restart ServerRestarts the specified Bedrock server instance. If running, sends warning (Linux), stops, then starts. If stopped, just starts.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to restart.None.
Returned when the restart sequence completes successfully.
{
"status": "success",
"message": "Server '<server_name>' restarted successfully."
}
or if initially stopped:
{
"status": "success",
"message": "Server '<server_name>' was not running and was started."
}
400 Bad Request
:
server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
).{"status": "error", "message": "Restart failed during stop phase: Failed to stop server '<server_name>': Server '<server_name>' failed to stop within the timeout. Manual intervention may be required."}
or {"status": "error", "message": "Restart failed during stop phase: Failed to stop server '<server_name>': Error sending command: Failed to find screen session 'bedrock-<server_name>' to send command to."}
.{"status": "error", "message": "Restart failed during start phase: Failed to start server '<server_name>': Server executable 'bedrock_server' not found in /path/to/servers/<server_name>"}
or {"status": "error", "message": "Restart failed during start phase: Failed to start server '<server_name>': Server '<server_name>' failed to start within the timeout."}
.501 Not Implemented
:
{"status": "error", "message": "Restart failed during stop phase: Failed to stop server '<server_name>': Unsupported operating system: Darwin"}
or start phase equivalent.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/restart
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/restart" -Headers $headers
/api/server/{server_name}/send_command
- Send CommandSends a command string to the specified running Bedrock server instance's console input (uses screen
on Linux, Named Pipes on Windows).
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the target server instance.application/json
):{
"command": "your server command here"
}
command
(string)(Required): Command string to send. Must not be empty/whitespace.Returned when command sent successfully (doesn't confirm server processed it).
{
"status": "success",
"message": "Command '<command>' sent successfully."
}
400 Bad Request
:
command
field: {"status": "error", "message": "Request body must contain a non-empty string 'command' field."}
.server_name
.401 Unauthorized
:
404 Not Found
:
{"status": "error", "message": "Server not found: Server executable 'bedrock_server' not found in /path/to/servers/MyServer"}
.500 Internal Server Error
:
BASE_DIR
).{"status": "error", "message": "Failed to send command: Server 'MyServer' is not running."}
or {"status": "error", "message": "Failed to send command: Screen session 'bedrock-MyServer' not found."}
or {"status": "error", "message": "Failed to send command: Pipe '\\\\.\\pipe\\BedrockServerMyServer' does not exist. Server likely not running."}
.{"status": "error", "message": "Failed to send command: Failed to send command via screen: Command '['/usr/bin/screen', '-S', 'bedrock-MyServer', '-X', 'stuff', 'list\\n']' returned non-zero exit status 1."}
or {"status": "error", "message": "Failed to send command: Windows error sending command: (109, 'CreateFile', 'The pipe has been ended.')"}
.screen
): {"status": "error", "message": "Failed to send command: Command 'screen' not found. Is it installed?"}
.501 Not Implemented
:
{"status": "error", "message": "Failed to send command: Sending commands not supported on Darwin"}
.pywin32
): {"status": "error", "message": "Failed to send command: Cannot send command on Windows: 'pywin32' module not found."}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"command": "say Hello from API!"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/send_command
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ command = 'say Hello from API!' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/send_command" -Headers $headers -Body $body
/api/server/{server_name}/update
- Update ServerChecks for the latest Bedrock Dedicated Server version and updates the server instance if a newer version is available or if the installed version is unknown. Handles download, backup, extraction, and optionally in-game notification.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to update.None.
Returned when the update check/process completes.
{
"status": "success",
"updated": true,
"new_version": "1.20.81.01",
"message": "Server '<server_name>' update process completed. New version: 1.20.81.01."
}
{
"status": "success",
"updated": false,
"new_version": "1.20.73.02",
"message": "Server is already up-to-date."
}
status
: Always "success".updated
(*boolean*): `true` if a new version was installed.new_version
(*string | null*): Version string now installed (or current if no update).message
(*string*): Descriptive outcome message.400 Bad Request
:
server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, DOWNLOAD_DIR
, BACKUP_DIR
).{"status": "error", "message": "Server Update failed: Failed to verify internet connectivity: No internet connection detected."}
.{"status": "error", "message": "Server Update failed: Failed to fetch download page 'https://www.minecraft.net/en-us/download/server/bedrock': ..."}
or {"status": "error", "message": "Server Update failed: Could not find a download URL matching OS 'Linux' and version type 'LATEST' on page ..."}
.{"status": "error", "message": "Server Update failed: Download failed for '<download_url>': 404 Client Error: Not Found for url: <download_url>"}
.{"status": "error", "message": "Server Update failed: Invalid ZIP file: '/path/to/downloads/stable/bedrock-server-1.20.xx.xx.zip'. Bad magic number for file header"}
or {"status": "error", "message": "Server Update failed: Error during file extraction: [Errno 13] Permission denied: '/path/to/servers/<server_name>/bedrock_server'"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/update
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/update" -Headers $headers
/api/server/{server_name}/delete
- Delete ServerPermanently deletes all data associated with the specified server instance (installation, config, backups). Irreversible action. Stops the server if running.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance to delete.None.
Returned when all associated data has been removed.
{
"status": "success",
"message": "All data for server '<server_name>' deleted successfully."
}
400 Bad Request
:
server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
, config path).{"status": "error", "message": "Failed to stop server '<server_name>' before deletion: Failed to stop server '<server_name>': Server '<server_name>' failed to stop within the timeout. Manual intervention may be required.. Deletion aborted."}
.{"status": "error", "message": "Error deleting server directories: Failed to completely delete server '<server_name>'. Failed items: installation directory '/path/to/servers/<server_name>' ([Errno 13] Permission denied)"}
.curl
Example (Bash):curl -X DELETE -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/delete
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Delete -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/delete" -Headers $headers
/api/server/{server_name}/export_world
- Export WorldTriggers an export of the server's currently configured world into a .mcworld
archive file saved in the configured BACKUP_DIR
.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returned when the world is successfully archived.
{
"status": "success",
"export_file": "/path/to/configured/backups/MyServer/Bedrock_level_export_20240115_103000.mcworld",
"message": "World exported successfully."
}
status
: Always "success".export_file
: Full path to the created .mcworld
file.message
: Confirmation message.400 Bad Request
:
server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
).server.properties
or find level-name
.{"status": "error", "message": "Failed to export world: World directory 'Bedrock level' not found at expected location: /path/to/servers/MyServer/worlds/Bedrock level"}
.{"status": "error", "message": "Failed to export world: Failed to create world backup archive: [Errno 28] No space left on device"}
or {"status": "error", "message": "Failed to export world: Cannot create target directory '/path/to/backups/MyServer': [Errno 13] Permission denied"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/export_world
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/export_world" -Headers $headers
/api/server/{server_name}/backups/prune
- Prune Server BackupsDeletes older backups (world, properties, json) for a specific server, keeping a specified number of newest files for each type.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server.None.
application/json
, optional):{
"keep": 10
}
keep
(integer)(Optional): Number of backups of *each type* to keep. Defaults to BACKUP_KEEP
setting (or 3).Returned when pruning completes or if no backups found.
{"status": "success", "message": "Backup pruning completed for server '<server_name>'."}
{"status": "success", "message": "No backup directory found, nothing to prune."}
400 Bad Request
:
server_name
.keep
value (not integer).401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
).{"status": "error", "message": "Pruning failed for some backup types: World backups (Failed to delete all required old backups (1 deletion(s) failed). Check logs.); JSON backups (Error pruning backups in '/path/to/backups/MyServer': [Errno 13] Permission denied)"}
.curl
Example (Bash):# Using default keep count
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/backups/prune
# Specifying keep count
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"keep": 5}' \
http://<your-manager-host>:<port>/api/server/<server_name>/backups/prune
# Using default keep count
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/backups/prune" -Headers $headers
# Specifying keep count
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ keep = 5 } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/backups/prune" -Headers $headers -Body $body
/api/server/{server_name}/backup/action
- Trigger BackupTriggers a backup operation (world, specific config, or all) for the specified server. Optionally stops/starts the server if running.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.application/json
):{"backup_type": "world"}
{"backup_type": "config", "file_to_backup": "server.properties"}
(Use relative path within server dir).{"backup_type": "all"}
backup_type
(string)(Required): `"world"`, `"config"`, or `"all"`.file_to_backup
(string)(Required if `backup_type` is `"config"`): Relative path of config file.Returned when the specified backup completes.
{
"status": "success",
"message": "World backup completed successfully for server '<server_name>'."
}
(Message varies by type. May indicate restart error if applicable.)
400 Bad Request
:
backup_type
.file_to_backup
for config type.file_to_backup
does not exist.server_name
).401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
).{"status": "error", "message": "World backup failed: World backup failed for 'MyServer': Could not determine world name for server 'MyServer'. Cannot perform world backup."}
or {"status": "error", "message": "World backup failed: World backup failed for 'MyServer': Failed to create world backup archive: [Errno 13] Permission denied: '/path/to/backups/MyServer/world_backup_...mcworld.zip'"}
.{"status": "error", "message": "Config file backup for 'server.properties' failed: Failed to copy config file 'server.properties': [Errno 13] Permission denied"}
.{"status": "error", "message": "Full backup failed: World backup failed during full backup of 'MyServer'."}
or {"status": "error", "message": "Full backup failed: Full backup completed with errors. Failed to back up config file(s): permissions.json."}
.curl
Example (Bash - World Backup):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"backup_type": "world"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/backup/action
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ backup_type = 'config'; file_to_backup = 'server.properties' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/backup/action" -Headers $headers -Body $body
/api/server/{server_name}/restore/action
- Trigger RestoreRestores a server's world or a specific config file from a backup. Warning: Overwrites current files. Recommended to stop server first (API handles by default).
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.application/json
):{
"restore_type": "world", // or "config"
"backup_file": "/full/path/to/backups/MyServer/backup_file.mcworld" // or ...properties, etc.
}
restore_type
(string)(Required): `"world"` or `"config"`.backup_file
(string)(Required): Full, absolute path to backup file (must be within configured BACKUP_DIR
).Returned when restore completes.
{
"status": "success",
"message": "Restoration from 'world_backup_xyz.mcworld' (type: world) completed successfully."
}
(May indicate restart error if applicable.)
400 Bad Request
:
restore_type
or backup_file
.backup_file
path outside BACKUP_DIR
.server_name
).{"status": "error", "message": "Config restore failed: Could not determine original filename from backup file format: 'bad_backup_name.properties'"}
.401 Unauthorized
:
404 Not Found
:
backup_file
does not exist: {"status": "error", "message": "Backup file not found."}
.500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
).{"status": "error", "message": "World restore failed: World import failed for server 'MyServer': Failed to extract archive: Error extracting zip file /path/to/backups/MyServer/world_backup_xyz.mcworld: Bad magic number for file header"}
.{"status": "error", "message": "Config file restore failed: Failed to restore config file 'server.properties': [Errno 13] Permission denied"}
.curl
Example (Bash - World Restore):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"restore_type": "world", "backup_file": "/full/path/to/backups/MyServer/world_backup_xyz.mcworld"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/restore/action
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ restore_type = 'config'; backup_file = 'C:\full\path\to\backups\MyServer\server_backup_abc.properties' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/restore/action" -Headers $headers -Body $body
/api/server/{server_name}/restore/all
- Trigger Restore AllRestores server world AND standard config files from their *latest* available backups. Warning: Overwrites current files. Recommended to stop server first (API handles by default).
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The unique name of the server instance.None.
Returned when restore for all components completes.
{
"status": "success",
"message": "Restore all completed successfully for server '<server_name>'."
}
(May indicate restart error if applicable.)
401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, BACKUP_DIR
).{"status": "error", "message": "Restore all failed: Restore failed for server 'MyServer'. Failed components: World (World import failed for server 'MyServer': Failed to extract archive: ...), server.properties (Failed to restore config file 'server.properties': [Errno 13] Permission denied)"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/restore/all
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/restore/all" -Headers $headers
/api/server/{server_name}/world/install
- Install WorldInstalls a world from a .mcworld
file into the specified server, replacing the existing world files. File must exist in configured content/worlds
directory. Warning: Overwrites current world. Stops/starts server if needed.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):{
"filename": "MyCoolWorld.mcworld"
}
or (with subdirectories):
{
"filename": "user_uploads/MyCoolWorld.mcworld"
}
filename
(string)(Required): Path to .mcworld
file *relative* to configured content/worlds
directory. Path traversal blocked.Returned when world file found, validated, and extracted.
{
"status": "success",
"message": "World 'MyCoolWorld.mcworld' installed successfully for server '<server_name>'."
}
(May indicate restart error if applicable.)
400 Bad Request
:
filename
.filename
path traversal attempt: {"status": "error", "message": "Invalid filename: Filename must be within the allowed content directory."}
.server_name
).401 Unauthorized
:
404 Not Found
:
.mcworld
file not found in content/worlds
: {"status": "error", "message": "Selected world file not found: /path/to/content/worlds/nonexistent.mcworld"}
.500 Internal Server Error
:
BASE_DIR
, CONTENT_DIR
).server.properties
: {"status": "error", "message": "World installation error: World import failed: Cannot import world: Failed to get world name for server '<server_name>'."}
.{"status": "error", "message": "World installation error: World import failed: Error extracting archive '/path/to/content/worlds/MyCoolWorld.mcworld': File is not a zip file"}
or {"status": "error", "message": "World installation error: World import failed: Failed to remove existing world directory '/path/to/servers/MyServer/worlds/Bedrock level': [Errno 13] Permission denied"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"filename": "MyDownloadedWorld.mcworld"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/world/install
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ filename = 'MyDownloadedWorld.mcworld' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/world/install" -Headers $headers -Body $body
/api/server/{server_name}/addon/install
- Install AddonInstalls addon pack (.mcaddon
/.mcpack
) into the server. File must exist in configured content/addons
directory. Extracts packs and updates world manifests. Stops/starts server if needed.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):{
"filename": "CoolBehaviorPack.mcpack"
}
or
{
"filename": "collections/AwesomeAddonCollection.mcaddon"
}
filename
(string)(Required): Path to addon file *relative* to configured content/addons
directory. Path traversal blocked.Returned when addon found, validated, processed, and installed.
{
"status": "success",
"message": "Addon 'AwesomeAddonCollection.mcaddon' installed successfully for server '<server_name>'."
}
(May indicate restart error if applicable.)
400 Bad Request
:
filename
.filename
path traversal attempt..mcaddon
or .mcpack
): {"status": "error", "message": "Addon installation error: Unsupported addon file type: 'MyAddon.zip'. Only .mcaddon and .mcpack are supported."}
.manifest.json
in addon: {"status": "error", "message": "Addon installation error: Invalid manifest structure in /path/to/temp/..../manifest.json. Missing fields: ['uuid']"}
or {"status": "error", "message": "Addon installation error: Manifest not found in pack: /path/to/temp/..."}
.server_name
).401 Unauthorized
:
404 Not Found
:
content/addons
: {"status": "error", "message": "Selected addon file not found: /path/to/content/addons/nonexistent.mcpack"}
.500 Internal Server Error
:
BASE_DIR
, CONTENT_DIR
).server.properties
: {"status": "error", "message": "Addon installation error: Failed to determine world name or paths for server '<server_name>': Could not determine world name for server '<server_name>'."}
.{"status": "error", "message": "Addon installation error: Invalid .mcpack file (not a zip): CoolBehaviorPack.mcpack"}
.{"status": "error", "message": "Addon installation error: Failed to copy behavior pack files: [Errno 13] Permission denied: '/path/to/servers/MyServer/worlds/Bedrock level/behavior_packs/CoolPack_1.0.0/script.js'"}
or {"status": "error", "message": "Addon installation error: Failed to update world activation JSON 'world_resource_packs.json': Failed to write world pack JSON: world_resource_packs.json"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"filename": "AwesomeAddonCollection.mcaddon"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/addon/install
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ filename = 'AwesomeAddonCollection.mcaddon' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/addon/install" -Headers $headers -Body $body
/api/players/scan
- Scan Player LogsTriggers a scan of all server log files (server_output.txt
) to find player connection entries (Name, XUID) and update the central players.json
file.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
None.
None.
None.
Indicates scan completion.
{
"status": "success", "players_found": true, "message": "Player scan completed and data saved."
}
{
"status": "success", "players_found": false, "message": "Player scan completed, no new player data found."
}
{
"status": "success", "players_found": false, "message": "No server directories found."
}
401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, config dir).{"status": "error", "message": "Scan completed with errors for server(s): ServerA, ServerC. Player data found in other logs was saved."}
.players.json
(write permissions, disk full): {"status": "error", "message": "Error saving player data to JSON: Failed to write players data to '/path/to/config/players.json': [Errno 13] Permission denied"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/players/scan
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/players/scan" -Headers $headers
/api/server/{server_name}/allowlist
- Get AllowlistRetrieves the current list of players from the server's allowlist.json
file.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.None.
None.
Returns the list of players currently in allowlist.json
.
{
"status": "success",
"existing_players": [
{
"ignoresPlayerLimit": false,
"name": "PlayerOne"
},
{
"ignoresPlayerLimit": false,
"name": "PlayerTwoXUID"
}
],
"message": "Successfully retrieved 2 players from allowlist."
}
or if empty/not found:
{
"status": "success",
"existing_players": [],
"message": "Successfully retrieved 0 players from allowlist."
}
status
: Always "success".existing_players
(*list[object]*): List of player objects (containing ignoresPlayerLimit
and name
).message
(*string*): Indicates number retrieved.401 Unauthorized
:
500 Internal Server Error
:
server_name
.BASE_DIR
, server dir not found).allowlist.json
(permissions, OS error).allowlist.json
: { "status": "error", "message": "Error retrieving allowlist: Invalid JSON in allowlist file: /path/to/servers/<server_name>/allowlist.json" }
.curl
Example (Bash):curl -X GET -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://<your-manager-host>:<port>/api/server/<server_name>/allowlist
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
Invoke-RestMethod -Method Get -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/allowlist" -Headers $headers
/api/server/{server_name}/allowlist/add
- Add Players to AllowlistAdds players to the server's allowlist.json
file. Appends players from request if not already present (case-insensitive name check).
Note: This is an ADD operation, not replace.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):{
"players": ["NewPlayer1", "AnotherPlayer"],
"ignoresPlayerLimit": false
}
players
(list[string])(Required): List of player names (Gamertags) to add. Empty/invalid names ignored.ignoresPlayerLimit
(boolean)(Optional, default: false): Sets this flag for all players added in this request.Returned on completion, even if no new players added.
{"status": "success", "message": "Allowlist saved successfully with X player(s)."}
{"status": "success", "message": "No new players provided or all provided players were duplicates/invalid."}
400 Bad Request
:
players
key.ignoresPlayerLimit
key.server_name
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, server dir not found).allowlist.json
(permissions, invalid JSON).allowlist.json
(permissions, disk full).curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"players": ["AdminUser", "VIP_Player"], "ignoresPlayerLimit": false}' \
http://<your-manager-host>:<port>/api/server/<server_name>/allowlist/add
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ players = @('AdminUser', 'VIP_Player'); ignoresPlayerLimit = $false } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/allowlist/add" -Headers $headers -Body $body
/api/server/{server_name}/permissions
- Update Player PermissionsUpdates permission levels for players in permissions.json
. Takes map of XUIDs to permission levels.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):{
"permissions": {
"2535416409681153": "operator",
"2535457894355891": "member",
"2535400000000000": "visitor"
}
}
permissions
(object)(Required): Object mapping player XUIDs (strings) to level strings.
Returned if all valid changes applied or no valid changes submitted.
{"status": "success", "message": "Permissions updated successfully for 2 player(s) on server '<server_name>'."}
{"status": "success", "message": "No valid permission changes submitted."}
400 Bad Request
:
permissions
key.permissions
value is not an object.{
"status": "error",
"message": "Validation failed for one or more permission levels.",
"errors": {
"2535411111111111": "Invalid level 'guest'. Must be one of ('visitor', 'member', 'operator')."
}
}
401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, server dir not found).permissions.json
for any player (permissions, invalid JSON, disk full). Response includes details: {
"status": "error",
"message": "One or more errors occurred while setting permissions for '<server_name>'.",
"errors": {
"2535457894355891": "Failed to configure permission: Failed to write permissions file: /path/to/servers/<server_name>/permissions.json"
}
}
curl
Example (Bash):curl -X PUT -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"permissions": {"2535416409681153": "operator", "2535457894355891": "member"}}' \
http://<your-manager-host>:<port>/api/server/<server_name>/permissions
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$permBody = @{
permissions = @{
'2535416409681153' = 'operator'
'2535457894355891' = 'member'
}
}
$bodyJson = $permBody | ConvertTo-Json -Depth 3
Invoke-RestMethod -Method Put -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/permissions" -Headers $headers -Body $bodyJson
/api/server/{server_name}/properties
- Update Server PropertiesUpdates specified key-value pairs in the server.properties
file. Only allowed keys are modified. Values undergo basic validation. level-name
is automatically cleaned.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):JSON object mapping property keys to new values.
{
"level-name": "Updated World Name",
"max-players": "20",
"difficulty": "hard",
"server-port": 19133
// Only include keys you want to change
}
Allowed Keys: server-name
, level-name
, gamemode
, difficulty
, allow-cheats
, max-players
, server-port
, server-portv6
, enable-lan-visibility
, allow-list
, default-player-permission-level
, view-distance
, tick-distance
, level-seed
, online-mode
, texturepack-required
. (Other keys ignored).
Returned when properties successfully validated/written or if no valid/allowed changes provided.
{
"status": "success",
"message": "Server properties for '<server_name>' updated successfully."
}
or if no valid changes:
{
"status": "success",
"message": "No valid properties provided or no changes needed."
}
400 Bad Request
:
errors
object: {
"status": "error",
"message": "Validation failed for one or more properties.",
"errors": {
"server-port": "Invalid value for 'server-port'. Must be a number between 1024 and 65535.",
"difficulty": "Invalid value for 'difficulty'. Must be one of peaceful, easy, normal, hard."
}
}
server.properties
file not found.server_name
.401 Unauthorized
:
500 Internal Server Error
:
server.properties
failed (permissions, disk full): {"status": "error", "message": "Error updating properties: Failed to modify server.properties: [Errno 13] Permission denied: '/path/to/servers/<server_name>/server.properties'"}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"max-players": "12", "allow-list": "true"}' \
http://<your-manager-host>:<port>/api/server/<server_name>/properties
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
# Note: Quotes may be needed around keys with hyphens depending on PowerShell version/parsing
$body = @{ 'max-players' = '12'; 'allow-list' = 'true' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/properties" -Headers $headers -Body $body
/api/server/{server_name}/service
- Configure OS Service SettingsConfigures OS-specific service settings (Linux: systemd service/timer; Windows: autoupdate
flag in config). Behavior depends on host OS.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
server_name
(string)(Required): The name of the server instance.application/json
):{
"autoupdate": true,
"autostart": true
}
autoupdate
(boolean)(Required): Configure systemd service ExecStartPre
for update check.autostart
(boolean)(Required): Enable/disable the systemd service (systemctl --user enable/disable
).{
"autoupdate": true
}
autoupdate
(boolean)(Required): Value for autoupdate
setting in server's JSON config file.Returned when OS-specific configuration applied.
{"status": "success", "message": "Systemd service created and enabled successfully."}
(Message varies){"status": "success", "message": "Autoupdate setting for '<server_name>' updated to true."}
(Message varies)400 Bad Request
:
server_name
.401 Unauthorized
:
403 Forbidden
/ 500 Internal Server Error
(OS Mismatch):
{ "status": "error", "message": "Service configuration is not supported on this operating system (Darwin)." }
.500 Internal Server Error
:
BASE_DIR
).systemctl
command not found.systemctl
failed.autoupdate
flag to config JSON failed.curl
Example (Bash - Linux):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"autoupdate": true, "autostart": true}' \
http://<your-manager-host>:<port>/api/server/<server_name>/service
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ autoupdate = $true } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/<server_name>/service" -Headers $headers -Body $body
/api/downloads/prune
- Prune Download CacheDeletes older downloaded server archives (e.g., bedrock-server-*.zip
) from a specified directory, keeping a defined number of newest files.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
None.
None.
application/json
):{
"directory": "/path/to/your/download/cache",
"keep": 5
}
directory
(string)(Required): Absolute path to directory containing downloads to prune.keep
(integer)(Optional): Number of newest files to retain. Defaults to DOWNLOAD_KEEP
setting (or 3).Indicates pruning completed successfully.
{
"status": "success",
"message": "Download cache pruned successfully for '/path/to/your/download/cache'."
}
(Message doesn't detail counts currently.)
400 Bad Request
:
directory
field.keep
value is not an integer.directory
value is empty string.401 Unauthorized
:
500 Internal Server Error
:
{"status": "error", "message": "Failed to prune downloads: Failed to delete old server download '/path/to/cache/bedrock-server-old.zip': [Errno 13] Permission denied"}
or {"status": "error", "message": "Failed to prune downloads: Failed to delete all required old downloads (1 failed). Check logs."}
.curl
Example (Bash):curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"directory": "/opt/bedrock-server-manager/.downloads/stable", "keep": 3}' \
http://<your-manager-host>:<port>/api/downloads/prune
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ directory = 'C:\bedrock-server-manager\.downloads\stable'; keep = 3 } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/downloads/prune" -Headers $headers -Body $body
/api/server/install
- Install New ServerCreates and installs a new Bedrock server instance. Validates name/version, handles optional overwrite, downloads, extracts, and sets up initial config.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
None.
None.
application/json
):{
"server_name": "UniqueServerName",
"server_version": "LATEST",
"overwrite": false
}
server_name
(string)(Required): Desired unique name (valid directory name, no spaces/special chars except -
_
).server_version
(string)(Required): Version to install ("LATEST"
, "PREVIEW"
, or specific version "1.20.81.01"
).overwrite
(boolean)(Optional, default: false): If `true`, deletes existing server data first.{
"status": "success",
"server_name": "UniqueServerName",
"version": "1.20.81.01", // Actual version installed
"message": "Server 'UniqueServerName' installed successfully (Version: 1.20.81.01).",
"next_step_url": "/server/UniqueServerName/configure_properties?new_install=true" // For UI flow
}
(Message might indicate final status config write failure even on success.)
{
"status": "confirm_needed",
"message": "Server 'UniqueServerName' already exists. Overwrite existing data and reinstall?",
"server_name": "UniqueServerName",
"server_version": "LATEST" // Original requested version
}
400 Bad Request
:
server_name
or server_version
.overwrite
field not boolean.server_name
format: {"status": "error", "message": "Server name format is invalid: Cannot contain spaces."}
.401 Unauthorized
:
500 Internal Server Error
:
BASE_DIR
, DOWNLOAD_DIR
, BACKUP_DIR
, config path).{"status": "error", "message": "Server Installation failed: Failed to fetch download page ..."}
or {"status": "error", "message": "Server Installation failed: Failed to extract server files ..."}
.curl
Example (Bash):# Install new server (will fail if exists unless overwrite: true)
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"server_name": "MySurvivalServer", "server_version": "LATEST", "overwrite": false}' \
http://<your-manager-host>:<port>/api/server/install
# Force overwrite existing server
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"server_name": "MySurvivalServer", "server_version": "LATEST", "overwrite": true}' \
http://<your-manager-host>:<port>/api/server/install
# Install new server
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ server_name = 'MySurvivalServer'; server_version = 'LATEST'; overwrite = $false } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/install" -Headers $headers -Body $body
# Force overwrite existing server
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$body = @{ server_name = 'MySurvivalServer'; server_version = 'LATEST'; overwrite = $true } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/install" -Headers $headers -Body $body
Note: These endpoints interact with Linux cron
or Windows Task Scheduler based on the host OS.
/api/server/{server_name}/cron_scheduler/add
- Add Cron Job (Linux Only)Adds a new cron job entry to the crontab of the user running the manager. Linux only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Linux Only.
server_name
(string)(Required): Server context (logging/auth), not usually part of the cron command itself.application/json
):{
"new_cron_job": "0 3 * * * /path/to/bedrock-server-manager backup-all --server MyServer"
}
new_cron_job
(string)(Required): Complete, raw cron job line string. Must not be empty/whitespace.Returned when cron job line successfully added.
{
"status": "success",
"message": "Cron job added successfully."
}
400 Bad Request
:
new_cron_job
field.server_name
.401 Unauthorized
:
403 Forbidden
:
500 Internal Server Error
:
crontab
command not found.curl
Example (Bash):# Note: Ensure command path/server name in cron string are correct
CRON_LINE="0 4 * * * /usr/local/bin/bedrock-server-manager restart-server --server MyProdServer"
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d "{\"new_cron_job\": \"$CRON_LINE\"}" \
"http://<your-manager-host>:<port>/api/server/MyProdServer/cron_scheduler/add"
# Note: Linux-only endpoint. Sends request assuming target is Linux.
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$cronLine = "0 4 * * * /usr/local/bin/bedrock-server-manager restart-server --server MyProdServer"
$body = @{ new_cron_job = $cronLine } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/MyProdServer/cron_scheduler/add" -Headers $headers -Body $body
/api/server/{server_name}/cron_scheduler/modify
- Modify Cron Job (Linux Only)Modifies an existing cron job by replacing the exact line matching old_cron_job
with new_cron_job
. Linux only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Linux Only.
server_name
(string)(Required): Server context.application/json
):{
"old_cron_job": "0 3 * * * /path/to/old_command --args",
"new_cron_job": "0 4 * * * /path/to/new_command --newargs"
}
old_cron_job
(string)(Required): Exact, complete, existing cron line to find/replace.new_cron_job
(string)(Required): New, complete cron line to replace with.Returned when replacement successful or if old/new identical.
{
"status": "success",
"message": "Cron job modified successfully."
}
or if no change:
{
"status": "success",
"message": "No modification needed, jobs are identical."
}
400 Bad Request
:
old_cron_job
or new_cron_job
.server_name
.401 Unauthorized
:
403 Forbidden
:
404 Not Found
:
old_cron_job
string not found in crontab.500 Internal Server Error
:
crontab
command not found.curl
Example (Bash):OLD_CRON="0 3 * * * /path/to/cmd --old"
NEW_CRON="0 4 * * * /path/to/cmd --new"
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d "{\"old_cron_job\": \"$OLD_CRON\", \"new_cron_job\": \"$NEW_CRON\"}" \
"http://<your-manager-host>:<port>/api/server/MyServer/cron_scheduler/modify"
# Note: Linux-only endpoint.
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$oldCron = "0 3 * * * /path/to/cmd --old"
$newCron = "0 4 * * * /path/to/cmd --new"
$body = @{ old_cron_job = $oldCron; new_cron_job = $newCron } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/MyServer/cron_scheduler/modify" -Headers $headers -Body $body
/api/server/{server_name}/cron_scheduler/delete
- Delete Cron Job (Linux Only)Deletes a specific cron job line from the user's crontab by exact string match. Linux only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Linux Only.
server_name
(string)(Required): Server context.cron_string
(string)(Required): Exact, complete cron line to delete (URL-encoded).None.
Returned on completion, even if string wasn't found (idempotent).
{
"status": "success",
"message": "Cron job deleted successfully (if it existed)."
}
400 Bad Request
:
cron_string
query parameter.server_name
.401 Unauthorized
:
403 Forbidden
:
500 Internal Server Error
:
crontab
command not found.curl
Example (Bash):# URL Encode the cron string (example using Python)
CRON_STRING_URLENCODED=$(python3 -c 'import urllib.parse; print(urllib.parse.quote_plus("0 4 * * * /path/to/bedrock-server-manager backup-all --server MyProdServer"))')
curl -X DELETE -H "Authorization: Bearer YOUR_JWT_TOKEN" \
"http://<your-manager-host>:<port>/api/server/MyServer/cron_scheduler/delete?cron_string=${CRON_STRING_URLENCODED}"
# Note: Linux-only endpoint.
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
$cronString = "0 4 * * * /path/to/bedrock-server-manager backup-all --server MyProdServer"
# Use appropriate URL encoding method
$encodedCronString = [System.Web.HttpUtility]::UrlEncode($cronString) # .NET Framework example
# $encodedCronString = [uri]::EscapeDataString($cronString) # PowerShell Core example
$uri = "http://<your-manager-host>:<port>/api/server/MyServer/cron_scheduler/delete?cron_string=$encodedCronString"
Invoke-RestMethod -Method Delete -Uri $uri -Headers $headers
/api/server/{server_name}/task_scheduler/add
- Add Windows Task (Windows Only)Creates a new scheduled task in Windows Task Scheduler to run a manager command. Generates/imports task XML. Windows only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Windows Only.
server_name
(string)(Required): Server context for the task (used in command args and XML path).application/json
):{
"command": "backup-all",
"triggers": [
{
"type": "Daily",
"start": "2024-01-16T03:00:00",
"interval": 1
},
{
"type": "Weekly",
"start": "2024-01-20T05:00:00",
"interval": 2,
"days": ["Saturday", "Sunday"]
}
]
}
command
(string)(Required): Manager command ("update-server"
, "backup-all"
, "start-server"
, "stop-server"
, "restart-server"
, "scan-players"
).triggers
(list[object])(Required): Non-empty list of trigger definitions. Each needs:
type
(string)(Required): Supported types (e.g., "Daily"
, "Weekly"
, "Monthly"
, "TimeTrigger"
, "LogonTrigger"
).start
(string)(Required for time-based): ISO 8601 format (e.g., YYYY-MM-DDTHH:MM:SS
).interval
(integer)(Optional, default: 1): For Daily
/Weekly
.days
(list[string|integer])(Required for `Weekly`): Days ("Monday"
, "Mon"
, `1`).months
(list[string|integer])(Required for `Monthly`): Months ("January"
, "Jan"
, `1`).days_of_month
(list[string|integer])(Required for `Monthly`): Day numbers (1-31).Returned when task XML generated and imported successfully. Includes task name.
{
"status": "success",
"message": "Windows task '<generated_task_name>' created successfully.",
"created_task_name": "bedrock_MyWinServer_backup-all_20240115_103000"
}
400 Bad Request
:
command
.triggers
list or objects (type, start, days, etc.).server_name
.401 Unauthorized
:
403 Forbidden
:
500 Internal Server Error
:
EXPATH
).schtasks
command not found.schtasks /Create
failed (access denied, invalid XML).curl
Example (Bash):# Note: Windows-only endpoint.
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"command": "backup-all", "triggers": [{"type": "Daily", "start": "2024-01-16T02:30:00", "interval": 1}]}' \
"http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/add"
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$taskBody = @{
command = 'backup-all'
triggers = @(
@{ type = 'Daily'; start = '2024-01-16T02:30:00'; interval = 1 }
)
}
$bodyJson = $taskBody | ConvertTo-Json -Depth 3
# Expect error if manager host is not Windows
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/add" -Headers $headers -Body $bodyJson
/api/server/{server_name}/task_scheduler/details
- Get Windows Task Details (Windows Only)Retrieves details (command, triggers) by parsing the task's associated XML config file. Windows only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Windows Only.
server_name
(string)(Required): Server context to locate task XML.application/json
):{
"task_name": "bedrock_MyWinServer_backup-all_..."
}
task_name
(string)(Required): Full name of the task whose details to retrieve.Returned when task XML found and parsed successfully.
{
"status": "success",
"task_details": {
"command_path": "C:\\path\\to\\manager.exe",
"command_args": "backup-all --server MyWinServer",
"base_command": "backup-all",
"triggers": [
{
"type": "Daily",
"start": "2024-01-16T02:30:00",
"interval": 1
}
]
}
}
status
: "success"task_details
(*object*): Parsed details (command path, args, base command, triggers list).400 Bad Request
:
task_name
.401 Unauthorized
:
403 Forbidden
:
404 Not Found
:
500 Internal Server Error
:
curl
Example (Bash):# Note: Windows-only endpoint.
TASK_NAME="bedrock_MyWinServer_backup-all_20240115103000"
curl -X POST -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d "{\"task_name\": \"$TASK_NAME\"}" \
"http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/details"
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$taskName = "bedrock_MyWinServer_backup-all_20240115103000"
$body = @{ task_name = $taskName } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/details" -Headers $headers -Body $body
/api/server/{server_name}/task_scheduler/task/{task_name}
- Modify Windows Task (Windows Only)Modifies an existing Windows task by deleting the old task (task_name
) and creating a new one with details from the request body. The new task gets a new timestamped name. Windows only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Windows Only.
server_name
(string)(Required): Server context.task_name
(string)(Required): Current full name of the task to replace (URL encode if needed).application/json
):Same structure as "Add Windows Task", defining the new command and triggers.
{
"command": "restart-server",
"triggers": [ { "type": "Weekly", "start": "...", "days": ["Saturday"] } ]
}
Returned when old task deleted (or not found) and new task created successfully. Includes the new task name.
{
"status": "success",
"message": "Windows task modified successfully.", // Simple message from API
"new_task_name": "bedrock_MyWinServer_restart-server_20240116_090000" // Added by route handler
}
400 Bad Request
:
task_name
in URL path (Flask 404).401 Unauthorized
:
403 Forbidden
:
500 Internal Server Error
:
schtasks
errors - see Add Task errors).curl
Example (Bash):# Note: Windows-only endpoint.
OLD_TASK_NAME="bedrock_MyWinServer_backup-all_..."
# URL Encode if needed
ENCODED_OLD_TASK_NAME=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("'$OLD_TASK_NAME'"))')
curl -X PUT -H "Authorization: Bearer YOUR_JWT_TOKEN" -H "Content-Type: application/json" \
-d '{"command": "restart-server", "triggers": [{"type": "Weekly", "start": "2024-01-20T05:00:00", "days": ["Saturday"]}]}' \
"http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/task/${ENCODED_OLD_TASK_NAME}"
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN'; 'Content-Type' = 'application/json' }
$oldTaskName = "bedrock_MyWinServer_backup-all_..."
# URL encode the task name for the URI
$encodedOldTaskName = [uri]::EscapeDataString($oldTaskName) # PS Core encoding
$newTaskBody = @{
command = 'restart-server'
triggers = @(
@{ type = 'Weekly'; start = '2024-01-20T05:00:00'; days = @('Saturday') }
)
}
$bodyJson = $newTaskBody | ConvertTo-Json -Depth 3
$uri = "http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/task/$encodedOldTaskName"
Invoke-RestMethod -Method Put -Uri $uri -Headers $headers -Body $bodyJson
/api/server/{server_name}/task_scheduler/task/{task_name}
- Delete Windows Task (Windows Only)Deletes an existing Windows task using schtasks.exe /Delete
and attempts to delete its XML config file. Windows only.
This endpoint is exempt from CSRF protection but requires authentication.
Required (JWT or active Web UI session).
Windows Only.
server_name
(string)(Required): Server context for locating XML file.task_name
(string)(Required): Full name of task to delete (URL encode if needed).None.
Returned when task deleted from scheduler (or already gone) and XML file deleted (or not found).
{
"status": "success",
"message": "Task '<task_name>' and its definition file deleted successfully."
}
400 Bad Request
:
task_name
in URL path (Flask 404).401 Unauthorized
:
403 Forbidden
:
500 Internal Server Error
:
schtasks /Delete
failed (access denied).schtasks
command not found.curl
Example (Bash):# Note: Windows-only endpoint.
TASK_NAME="bedrock_MyWinServer_backup-all_..."
# URL Encode if needed
ENCODED_TASK_NAME=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("'$TASK_NAME'"))')
curl -X DELETE -H "Authorization: Bearer YOUR_JWT_TOKEN" \
"http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/task/${ENCODED_TASK_NAME}"
$headers = @{ Authorization = 'Bearer YOUR_JWT_TOKEN' }
$taskName = "bedrock_MyWinServer_backup-all_..."
# URL encode the task name for the URI
$encodedTaskName = [uri]::EscapeDataString($taskName) # PS Core encoding
$uri = "http://<your-manager-host>:<port>/api/server/MyWinServer/task_scheduler/task/$encodedTaskName"
Invoke-RestMethod -Method Delete -Uri $uri -Headers $headers