Game host API
The part of the panel’s API that integrations use: read and write a server’s files, send commands, follow the console live, and power the server.
Every endpoint with its parameters: the API reference, generated from the panel’s OpenAPI document. Each panel also serves it at /openapi/v1.json, browsable at /api/docs.
Basics
Section titled “Basics”- Authenticate with an API token:
Authorization: Bearer …. - All server paths start with
/api/v1/tenants/{tenantId}/servers/{serverId}. - Errors are
application/problem+jsonwith a stablecode.
Endpoints
Section titled “Endpoints”| Method and path | Permission | Notes |
|---|---|---|
GET (the path itself) |
server.view |
state: installing · installFailed · offline · starting · running · stopping. allocations[] has role (game, query, rcon…), ip, port, protocol, address. stats has CPU, memory, disk, uptime. permissions[] is what the caller may do. |
POST /power { "action": "start" } |
power.<action> |
start, stop, restart, kill. 409 invalid_state while installing. |
POST /command { "command": "say hi" } |
console.write |
409 invalid_state when the server isn’t running. |
POST /rcon { "command": "list" } |
console.write |
Returns { "response": "…" }, for games with RCON. |
GET /console/stream |
console.read |
Server-Sent Events, see below. |
GET /console/log |
console.read |
The whole console log as a file. |
GET /metrics?range=1h |
monitor.view |
One-minute averages; 1h, 6h, 24h or 7d. |
GET /files?path=/config |
files.list |
Only entries the caller may access are listed. |
GET /files/content?path=whitelist.txt |
files.read |
Up to 4 MiB, for editing. ETag: "<sha256>", X-File-Size, X-File-Truncated. |
GET /files/download?path=world.zip |
files.read |
Any size, streamed. |
GET /files/archive?path=/world |
files.list |
A folder as zip, with the files the caller may read. names= (repeatable) picks entries of the folder. |
PUT /files/content?path=whitelist.txt |
files.write |
The body is the new content. Conditions below. Large files in parts: &offset=<position>&final=false, the last part with final=true. |
DELETE /files?path=… |
files.delete |
|
POST /files/delete { "paths": [] } |
files.delete per path |
Returns { "done", "failed": [{ "path", "error" }] }. |
POST /files/move { "paths": [], "to": "/old" } |
files.write on both paths |
Same answer as delete. |
POST /files/rename { "from", "to" } |
files.write on both paths |
|
POST /files/directory { "path" } |
files.write |
Errors
Section titled “Errors”| Status | code |
|---|---|
| 400 | invalid_action, variable_invalid, range_invalid |
| 401 | missing, invalid, revoked or expired token, or wrong network |
| 403 | forbidden (the server exists for you, but this action or path isn’t allowed), token_not_allowed |
| 404 | server unknown, or no permission on it at all |
| 409 | node_offline (the node’s agent isn’t connected), invalid_state |
| 412 | precondition_failed |
Safe read-modify-write
Section titled “Safe read-modify-write”For files an integration manages, such as a whitelist, so it never overwrites someone else’s edit:
1. GET …/files/content?path=whitelist.txt → body + ETag "abc…"2. compute the new content3. PUT …/files/content?path=whitelist.txt If-Match: "abc…"4. on 412: someone edited the file in between → go back to 1If-None-Match: * writes only if the file doesn’t exist yet.
Console stream (SSE)
Section titled “Console stream (SSE)”GET …/console/stream sends text/event-stream:
event: statedata: {"state":"running"}
event: consoledata: {"lines":["[12:00:01] Done (3.9s)!"],"history":true}
event: consoledata: {"lines":["<Steve> hello"]}
: keep-alive- On connect: the current state, then recent history (marked
"history": true), then live events. - Keep-alive: a comment every 15 seconds.
- Reconnect when the connection drops. History is sent again, so de-duplicate if your use case needs it.
- Behind nginx: the panel sends
X-Accel-Buffering: no.