REST API Reference

The HTTP API exposed by the Saba-chan daemon. Authentication scheme and a catalog of the major endpoints.

REST API Reference

The Saba-chan daemon exposes an HTTP REST API on 127.0.0.1:57474. The GUI, CLI, and Discord bot all merely call this API, and you can build a custom client against the same contract.

This reference is a summary extracted from the actual routes in src/api/. Field schemas may change, so consult the code for the latest.


1. Basics

  • Base URL: http://127.0.0.1:57474 (default). Can be changed via the SABA_IPC_PORT environment variable or settings.json.ipcPort.
  • Authentication: Every request needs an X-Saba-Token: <UUID> header. Token file: %APPDATA%\saba-chan\.ipc_token. During development you can disable verification with SABA_AUTH_DISABLED=1.
  • Content-Type: application/json for both requests and responses.
  • Error format: { "error": "message", "code": "ERR_CODE" }. Returned together with an HTTP status code.
  • Bind address: By default the daemon binds only to 127.0.0.1, so it's not reachable from outside. (In relay mode, the relay server proxies traffic.)

2. Health & System

GET  /health

Returns {"status":"ok","uptime_sec":12345,"version":"x.y.z"}. No authentication required.

POST /api/daemon/shutdown

Shuts the daemon down. Used by the GUI's quit button.

GET  /api/system/info
GET  /api/node-env              # portable Node runtime metadata
GET  /api/node-env/status
POST /api/node-env/reinstall

3. Server (Instance) Lifecycle

Saba-chan exposes both a server axis (keyed by module) and an instance axis (keyed by user instance ID). Most GUI operations enter through the server name.

GET    /api/servers                        # list all servers
GET    /api/servers/:name                  # server metadata + state
POST   /api/servers                        # create
DELETE /api/servers/:name                  # remove

POST   /api/server/:name/start             # start → runs pre_start hook
POST   /api/server/:name/stop              # stop (graceful 30s → force 5s)
POST   /api/server/:name/restart

GET    /api/server/:name/status            # detailed status (includes status hook output)
GET    /api/server/:name/settings
PUT    /api/server/:name/settings

Instance-ID-based access:

GET    /api/instances                      # list of IDs
GET    /api/instance/:id                   # instance details

# Console (cursor-based polling)
GET    /api/instance/:id/console?since=<line>&count=<n>
POST   /api/instance/:id/console           # body: { "command": "say hello" }

# Direct RCON call
POST   /api/instance/:id/rcon              # body: { "command": "list" }

Console polling contract: Send the last line number you received as since, and only newer lines are returned. The in-memory ring buffer is sized by settings.json.consoleBufferSize (default 10 000 lines).


4. Modules

GET    /api/modules                         # list installed modules
GET    /api/module/:name                    # module.toml + metadata
POST   /api/module/:name/install            # install based on the manifest
DELETE /api/module/:name

GET    /api/module/:name/versions           # backed by get_version_details
GET    /api/module/:name/installed-version  # invokes get_installed_version
POST   /api/module/:name/validate           # invokes validate
POST   /api/module/:name/diagnose           # invokes diagnose
POST   /api/module/:name/configure          # invokes configure
GET    /api/module/:name/credentials        # invokes get_credentials

5. Extensions

GET    /api/extensions                     # list including install/enabled state
GET    /api/extensions/:id
POST   /api/extensions/:id/install
DELETE /api/extensions/:id
POST   /api/extensions/:id/enable          # runs daemon.startup asynchronously
POST   /api/extensions/:id/disable

GET    /api/extensions/:id/config
PUT    /api/extensions/:id/config

GET    /api/extensions/:id/gui             # builtin GUI bundle (HTML)
GET    /api/extensions/:id/i18n/:locale    # ko / en / ja / ...

6. Progress Polling

Long-running work (installation, async post_create hooks, SteamCMD downloads, etc.) exposes its real-time state through the following endpoint.

GET /api/provision-progress/:tracking_name

Example response:

{
  "tracking_name": "instance_1",
  "step": 2,
  "total": 5,
  "percent": 40,
  "message": "Cloning original files",
  "done": false,
  "error": null
}

The done: true state is retained for 5 seconds after completion before the tracker is cleaned up automatically.


7. Updater

GET  /api/updates/check                    # manually trigger an update check
GET  /api/updates/status                   # current progress
POST /api/updates/apply                    # apply staged updates (will restart)
POST /api/updates/cancel

Update staging happens under %APPDATA%\saba-chan\updates\; on apply, a separate updater.exe shuts down, replaces, and relaunches the daemon.


8. Cloud Relay Pairing

For the local GUI ↔ relay server pairing flow. For the detailed flow, see Discord Bot.

POST /api/relay/pair/initiate               # issues a 32-char code + 48-char pollSecret
GET  /api/relay/pair/:code/status?secret=   # 3-second polling to receive the token (atomic swap)
POST /api/relay/pair/:code/cancel
POST /api/relay/unpair                      # delete .node_token + notify the server

Signature headers used when the client (the bot agent) connects to the relay:

Authorization:       Bearer sbn_{hostId}.{secret}
X-Request-Timestamp: <unix>
X-Request-Nonce:     <UUID>
X-Request-Signature: HMAC_SHA256(METHOD\nPATH\nTS\nNONCE\nBODY, secret)

Timestamp skew must be within ±30 seconds, and a nonce cannot be reused for 24 hours.


9. Discord Bot Management

GET  /api/bot/config
PUT  /api/bot/config                       # save prefix / aliases / cloud.* etc.
POST /api/bot/start
POST /api/bot/stop
GET  /api/bot/status

The bot token is not sent directly in this API's settings body; it's designed to be injected through a separate secure-storage path (a dedicated /api/bot/token refresh endpoint, or a GUI-only protected route). The exact field names may vary by version, so refer to src/api/bot.rs.


10. Authentication Example (curl)

TOKEN=$(cat "$APPDATA/saba-chan/.ipc_token")

curl -H "X-Saba-Token: $TOKEN" \
     http://127.0.0.1:57474/api/servers

curl -X POST \
     -H "X-Saba-Token: $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"command":"list"}' \
     http://127.0.0.1:57474/api/instance/instance_1/rcon

11. Version Compatibility

  • This API is classified as private IPC. It is not a public contract, so paths and schemas may change even within minor releases.
  • If you ship a custom client, perform conservative version checks (e.g., the version field of GET /health) against the daemon.
  • Schema changes are announced in CHANGELOG.md.

If something's wrong, head over to Troubleshooting.