Panel HTTP API#
The panel's browser uses a same-origin, cookie-authenticated HTTP API on the panel URL (default
http://127.0.0.1:20772). This is the panel's internal application API and can change between panel releases.
There is no panel API-key authentication.
The source of truth is
src/Web/Program.cs and
BundleToolsEndpoints.cs.
Request records live in those files and
src/Shared.
Match the source revision in sources.json when developing an integration.
Sessions, CSRF and response shapes#
GET /api/session returns {authenticated, username, permissions, csrf} and issues the CSRF cookie.
Every POST, including login and setup, requires the returned token in X-CSRF together with its cookie.
POST /api/login takes {username, password, remember} and creates the replay-panel-session HttpOnly cookie.
POST /api/logout ends it. A normal session expires after four hours without sliding renewal; remember-me uses a
30-day persistent authentication ticket. Account changes can revoke a session through its security stamp.
Most mutations return a Reply: {ok, error?, status?, lines?}. Some data routes unwrap JSON from lines[0] and
return that data directly. GET /api/status returns a Reply containing status; do not assume every GET has that shape.
| Status | Meaning |
|---|---|
| 200 | Success; inspect ok and any asynchronous job state |
| 400 | Invalid host, CSRF or malformed input |
| 401 | Login failed or session missing/expired |
| 403 | Required account permission is missing |
| 404 | Requested file/resource does not exist |
| 409 | Application conflict, disabled feature, refused operation or update applying |
| 429 | Login/setup/provider discovery rate limit |
Errors use localization keys such as csrf.invalid, update.busy or bundleTools.disabled; display them through the
panel's translation layer. HTTPS remote access requires the proxy configuration. Do not expose
the loopback service by changing a bind address without configuring trusted proxies and allowed hosts.
Browser example#
Run this from a same-origin panel integration. The user supplies their own credentials through its login UI.
async function session() {
const response = await fetch('/api/session', { credentials: 'same-origin' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
async function post(path, body) {
const { csrf } = await session();
const response = await fetch(path, {
method: 'POST', credentials: 'same-origin',
headers: { 'Content-Type': 'application/json', 'X-CSRF': csrf },
body: JSON.stringify(body)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
return response.json();
}
// After the user logs in:
const state = await (await fetch('/api/status')).json();
console.log(state.status);
// With console.write permission, a read-only game console command:
// await post('/api/command', { text: 'bundles' });
Core route reference#
| Method and path | Input / output | Permission |
|---|---|---|
GET /api/session |
Session state and CSRF token | Public |
GET /api/bootstrap |
Setup/bootstrap data | Public |
POST /api/login |
{username,password,remember} |
Public, rate limited |
POST /api/logout |
Empty JSON | Authenticated |
GET /api/status |
Reply with server state/PID/configured root | Authenticated |
POST /api/server/{action} |
start, stop, restart, force-stop |
Matching server.<action> |
POST /api/command |
{text} console command |
console.write |
GET /api/bundles |
Bundle list | bundles.read |
POST /api/bundles/{name}/{action} |
start, stop, restart |
bundles.read and matching bundles.<action> |
GET /api/logs |
Recent console/log reply | logs.read |
GET /api/log-files |
{name,size,modified,started} array |
logs.read |
GET /api/log-files-current |
Current log text download | logs.read |
GET /api/log-files/{name} |
Last 2 MiB of one log | logs.read |
GET /api/log-files.zip |
Streaming ZIP archive | logs.read |
GET /api/diagnostics |
Query cursor, source, module, search, limit, history |
console.read and/or logs.read according to source |
GET /api/events |
Server-Sent Events; status, console and permissions | Authenticated; console requires console.read |
GET /api/bridge |
LAN bridge status | Authenticated |
POST /api/bridge/settings |
{enabled,port,retentionDays,maxMegabytes} |
settings.write |
POST /api/settings |
{shutdownMode,autoStartServer,locale,autoUpdateChecks,updateChannel} |
Authenticated; any field other than locale requires settings.write |
GET /api/server-name |
{name} |
Authenticated |
GET /api/server-config |
Editable server configuration | settings.write |
POST /api/server-config |
Server configuration document | settings.write |
POST /api/server-path |
{serverRoot}; server must be stopped |
settings.write |
GET /api/users |
Account views | users.manage |
POST /api/users/save |
{username,password,permissions,enabled,create} |
users.manage |
POST /api/users/delete |
{username} |
users.manage |
Use users and permissions for the complete permission model and administrator safeguards. Read the exact route handler before implementing a mutating integration; server configuration, path validation and permission rules include checks beyond HTTP authorization.
Updates and asynchronous jobs#
Panel update routes are GET /api/updates and POST /api/updates/{check,download,cancel,apply}.
Server updates use GET /api/server-updates and POST /api/server-updates/{check,download,apply,cancel} with an optional
{target}. They require settings.write; download/apply also require users.manage.
Inspect returned job status rather than treating acceptance as completion. While a panel update is applying,
authenticated POST operations are refused with 409 update.busy.
See updates and server updates for backups and rollback.
Experimental bundle tools#
These routes require the feature master switch and individual permissions. Source builds execute trusted project code on the host. See Bundle Tools before enabling them.
| Prefix / route | Actions and request notes | Permission |
|---|---|---|
GET /api/bundle-tools |
Status, redacted accounts and authorized jobs | Relevant bundle permission |
POST /api/bundle-tools/settings |
BundleTools settings document | bundles.settings |
POST /api/bundle-tools/upload |
Multipart ZIP; X-CSRF required, omit JSON content type |
bundles.upload |
POST /api/bundle-tools/upload/exists |
{name} |
bundles.upload |
POST /api/bundle-tools/upload/install |
Inspected upload/install document | bundles.upload |
/api/bundle-tools/tools |
POST install, remove; GET latest |
bundles.tools |
GET /api/bundle-tools/projects |
Source projects | bundles.build |
POST /api/bundle-tools/projects/{action} |
create, import, pull, checkout, check, refs, build, rollback, remove |
bundles.build; removal also bundles.sources.delete; remote credentials need account permission |
POST /api/bundle-tools/accounts/{action} |
save settings/token; delete or test with {name} |
bundles.accounts.manage |
POST /api/bundle-tools/remote/{action} |
owners, repositories |
bundles.accounts.use, rate limited |
POST /api/bundle-tools/projects/workflow |
Review/direct workflow configuration | bundles.settings |
POST /api/bundle-tools/projects/compare |
Repository comparison document | bundles.build, bundles.accounts.use |
POST /api/bundle-tools/projects/{merge,review} |
Review/merge document | Build, git-write, account-use and matching merge/review permission |
POST /api/bundle-tools/packages/info |
Package metadata query | bundles.build |
POST /api/bundle-tools/packages/review |
Package-change review document | Build, git-write, accounts, packages, review |
GET /api/bundle-tools/jobs/{id} |
Job and outcome | Permission for that job's kind |
GET /api/bundles/metadata |
Tags and autostart metadata | bundles.read |
POST /api/bundles/{tags,autostart} |
Metadata change document | bundles.read plus matching permission |
POST /api/bundles/delete-info |
{name} deletion preview |
bundles.read, bundles.delete |
POST /api/bundles/delete |
Confirmed deletion document | Read/delete/stop plus permissions for selected data/source flags |
projects/delivery and packages/set currently return 409 bundleTools.workflow; use the configured review workflow.
The detailed JSON payloads are defined by the supervisor's BundleTools handlers and the panel UI at the recorded source
commit. Account tokens are encrypted on the supervisor and never returned to the browser.
Setup routes#
First-time setup uses the local setup key and is rate limited. POST routes:
/api/setup/validate, /install, /finish, /pick, /pick-status, /job, /cancel.
The setup document contains {key,dashboardName,username,password,confirmation,locale,serverRoot,backend};
job/pick-status/cancel use {key}. The directory picker is available only for a direct loopback request.
GET /api/setup/console reports setup-console availability; it does not replace the key requirement.
Follow the setup UI and installation guide for supported ordering and validation.