Skip to content

API Reference

Super exposes a RESTful API on port 9002 (default). All responses are in JSON format.

Authentication

Without security plugin loaded (OSS only): No API authentication. The API is open on the bind address. OSS ships with host = "127.0.0.1" and allow_insecure_public_bind = false; superd refuses startup on a non-loopback bind unless you set that flag to true. See Configuration — OSS security defaults.

Licensed ([license].key valid): security is bundled with every subscription and must load — otherwise superd refuses startup. API auth is always active when licensed. See Authentication — Licensed deployments require security.

With security plugin loaded: All API requests require Authorization: Bearer <token> (except /health, /metrics, and docs whitelist). Public bind is allowed because auth middleware is active. Config auth_secret bootstraps Access Tokens and stays usable until an Admin explicitly disables it. See Authentication.

Health & docs

  • GET /health — liveness (no auth)
  • GET /api/docs — Swagger UI when enable_docs = true (docs feature build)
  • GET /api/v1/openapi.json — OpenAPI catalog (same docs gate / whitelist)

Programs

List Programs

Get a summary of all managed processes.

  • GET /api/v1/programs

Response:

[
  {
    "id": "a1b2c3d4-...",
    "name": "api-server",
    "status": "Running",
    "pid": 12345,
    "cpu_usage": 2.5,
    "mem_usage": 10485760
  }
]

Create Program

Register a new process dynamically.

  • POST /api/v1/programs

Body:

{
  "name": "worker-1",
  "command": "./worker",
  "autostart": true,
  "autorestart": "unexpected",
  "exitcodes": [0],
  "startsecs": 10,
  "retry_limit": 3
}
FieldDefaultDescription
autorestartunexpectedunexpected, true, or false (Supervisor-compatible)
exitcodes[0]Exit codes treated as success when autorestart=unexpected
startsecs10Seconds of stable run before exit resets retry counter

Migration note: autostart controls boot-time start only. To disable crash auto-restart, set "autorestart": "false".

Get Details

Get full configuration and state for a specific program.

  • GET /api/v1/programs/{id}

{id} is the program UUID (not the name). Resolve it from GET /api/v1/programs.

Update Program

Partially update an existing program. Only fields present in the body are changed; omitted fields are left unchanged.

  • PUT /api/v1/programs/{id}

Body (all fields optional):

{
  "command": "/usr/local/bin/my-app",
  "env": { "LOG_LEVEL": "debug" },
  "autorestart": "unexpected",
  "health_check": { "type": "http", "url": "http://127.0.0.1:8080/health" }
}
FieldDescription
name, command, args, cwd, user, groupProgram identity and execution
env, env_fileEnvironment (env_file = "" clears)
autostart, retry_limit, autorestart, exitcodes, startsecs, stopsecs, priorityRestart / stop behaviour
depends_on, health_check, hooksOrchestration
stdout_logfile, stderr_logfileCustom log paths (must resolve under storage.log_dir)
artifactOTA binary update — see below
cronCron expression — see Scheduled Tasks.
resource_limits💎 Requires isolation plugin on Linux — stored in config always; enforced only when plugin is loaded

Restart semantics: Updating command, env, etc. persists config only — it does not restart a running process. Call POST /api/v1/programs/{id}/restart explicitly, or change artifact.checksum to trigger an automatic OTA restart.

OTA update via API

When artifact.checksum differs from the stored value, Super starts the transactional OTA flow (download → verify → backup → swap → restart → health validate / rollback). See Atomic OTA Updates.

Step 1 — resolve UUID:

curl -s http://127.0.0.1:9002/api/v1/programs \
  | jq -r '.[] | select(.name=="my-app") | .id'

Step 2 — trigger update:

curl -X PUT "http://127.0.0.1:9002/api/v1/programs/${PROGRAM_ID}" \
  -H "Content-Type: application/json" \
  -d '{
    "artifact": {
      "source": "https://example.com/builds/v2.0.0/app-linux-amd64",
      "checksum": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789",
      "destination": "/usr/local/bin/my-app",
      "extract": false,
      "restart_policy": "immediate"
    }
  }'
artifact fieldDescription
sourceDownload URL
checksumExpected SHA256 hex digest
destinationPath of the binary on disk
extracttrue if the download is an archive to extract
restart_policy"immediate" (swap then restart) — primary supported policy

With security plugin: add -H "Authorization: Bearer <token>".

Response: 200 OK on success; 400 if the program is not found or validation fails.

Control Actions

Perform lifecycle actions.

  • POST /api/v1/programs/{id}/start
  • POST /api/v1/programs/{id}/stop (Query param: ?force=true)
  • POST /api/v1/programs/{id}/restart

Historical Logs

Read the last N lines from on-disk log files ({uuid}.out / {uuid}.err).

  • GET /api/v1/programs/{id}/logs

Query parameters:

ParamDefaultDescription
tail200Lines from end of file (max 5000)
sourcebothstdout or stderr

Response:

{
  "id": "a1b2c3d4-...",
  "logs": [
    { "source": "stdout", "content": "line-1\nline-2\n" },
    { "source": "stderr", "content": "error line\n" }
  ]
}

Send Signal

  • POST /api/v1/programs/{id}/signal

Body:

{
  "signal": "hup"
}

System & Stack

Apply Stack (Declarative)

Update the entire system state to match a JSON definition.

  • PUT /api/v1/stack

Body:

{
  "prune": true,
  "services": [ ... list of program configs ... ]
}

Shutdown

Gracefully stop the daemon (same for foreground and superd --daemon instances).

  • POST /api/v1/system/shutdown

System Stats

Host-level CPU and memory snapshot (refreshed every ~3s by the monitor thread).

  • GET /api/v1/system/stats

Response:

{
  "cpu_percent": 12.4,
  "memory_used_bytes": 4294967296,
  "memory_total_bytes": 17179869184,
  "timestamp": 1719820800
}

Observability

Prometheus Metrics

Export metrics in Prometheus text format.

  • GET /metrics

Log Stream (WebSocket)

Stream stdout/stderr.

  • WS /ws?id={program_id}

Batch Operations

Perform actions on multiple programs simultaneously.

  • POST /api/v1/programs/batch

Body:

{
  "target_ids": ["uuid-1", "uuid-2"], // Or omit and use "group_name": "backend"
  "select_all": false,
  "action": {
    "type": "Restart" // Or "Start", "Stop", "Remove", "Signal"
  }
}

Security & Authentication (security plugin 💎)

Without the plugin: These routes are not registered. Requests return 404 Not Found.

Manage access tokens for API authorization. Bootstrap with config auth_secret; Admins may optionally disable it after creating an Admin token. See Authentication.

Login

  • POST /api/v1/auth/login

Logout

  • POST /api/v1/auth/logout

Auth status

  • GET /api/v1/auth/status

Disable auth_secret

  • POST /api/v1/auth/secret/disable

List Tokens

  • GET /api/v1/auth/tokens

Create Token

  • POST /api/v1/auth/tokens

Renew Token

  • POST /api/v1/auth/tokens/{id}/renew

Create Token body

{
  "name": "ci-deploy-bot",
  "role": "operator"
}

Revoke Token

  • DELETE /api/v1/auth/tokens/{id}

System Configuration (licensed plugins 💎)

License route is served by OSS core when a valid [license].key is configured at startup.
Notify routes require the notify plugin; without it they return 404 Not Found.

Authentication: When the security plugin is loaded, protected routes (including license) require a valid Bearer token — same as other authenticated API calls.

Get License Info

  • GET /api/v1/system/license

Returns verified subscription metadata plus runtime plugin versions (versions are not part of the signed license claims).

Auth: Required when security plugin is active (Authorization: Bearer <token>).

Response 200:

{
  "issued_to": "Customer Name",
  "issued_at": 1710000000,
  "major_version": 1,
  "grants": ["security", "notify", "ui"],
  "expires_at": 1741536000,
  "license_id": "550e8400-e29b-41d4-a716-446655440000",
  "features": ["auth", "notify", "dashboard"],
  "plugin_versions": {
    "security": "0.1.0",
    "ui": "0.1.0"
  }
}
FieldNotes
expires_atOmitted when license is perpetual (no expiry in claims)
featuresUI feature codes derived from authorized grants[]
plugin_versionsLoaded plugin crate versions at runtime

Errors: 404 if no license configured; 401 if auth required and missing/invalid token.

Manage Notifications

View or hot-reload webhook channels.

  • GET /api/v1/system/notify
  • PUT /api/v1/system/notify
  • POST /api/v1/system/notify/test