HTTP API
Portoser's web backend exposes a REST API used by the web UI and the CLI's history commands. Every endpoint lives under /api/.
The backend is FastAPI. Auto-generated OpenAPI docs are available at /docs and /redoc on a running instance.
Authentication
When KEYCLOAK_ENABLED=true, the backend's KeycloakAuthMiddleware requires a bearer token on every protected route. When disabled (the default for ./compose.sh up), endpoints are open and a synthetic dev user is injected.
For first-party tools (the CLI, the web UI) the bearer token comes from the Keycloak login flow. For your own scripts, get a token from the Keycloak /realms/<realm>/protocol/openid-connect/token endpoint.
Core routers
/api/services
| Method |
Path |
Purpose |
| GET |
/api/services |
List all services from the registry |
| GET |
/api/services/{name} |
Single service detail |
/api/machines
| Method |
Path |
Purpose |
| GET |
/api/machines |
List machines |
| GET |
/api/machines/{name} |
Single machine detail |
| POST |
/api/v1/devices |
Register a new device (note: /api/v1/ legacy path) |
/api/deployment
| Method |
Path |
Purpose |
| POST |
/api/deployment/execute |
Execute pending moves from the cluster view |
| GET |
/api/deployment/state |
Current pending state |
/api/health
| Method |
Path |
Purpose |
| GET |
/api/health/dashboard |
Aggregated health for the whole cluster |
| GET |
/api/diagnostics/health/all |
Full diagnostic snapshot |
| POST |
/api/diagnostics/run |
Run the diagnose phase on demand |
/api/dependencies
| Method |
Path |
Purpose |
| GET |
/api/dependencies/graph |
Dependency graph for ReactFlow |
/api/history
| Method |
Path |
Purpose |
| GET |
/api/history/deployments |
List deployments (filterable by service / machine / status) |
| GET |
/api/history/deployments/{id} |
One deployment with config snapshot |
| GET |
/api/history/stats |
Aggregate stats |
| GET |
/api/history/rollback/{id}/preview |
Preview the changes a rollback would make |
| POST |
/api/history/rollback/{id}/execute |
Execute the rollback |
/api/vault
| Method |
Path |
Purpose |
| GET |
/api/vault/status |
Vault health, sealed state, address |
| GET |
/api/vault/services |
List services with declared Vault secrets |
| GET |
/api/vault/services/{service} |
Secrets declared for one service (values masked) |
| POST |
/api/vault/services/{service}/secrets |
Add or update a secret |
| POST |
/api/vault/migrate |
Migrate a service's .env into Vault |
| POST |
/api/vault/migrate-all |
Migrate every service with a .env |
/api/certificates
| Method |
Path |
Purpose |
| GET |
/api/certificates |
List managed certs |
| POST |
/api/certificates/generate/{service} |
Generate a new cert |
| POST |
/api/certificates/renew/{service} |
Force renewal |
| GET |
/api/certificates/keycloak-ca |
Download Keycloak CA bundle |
| POST |
/api/certificates/keycloak-ca/copy/{service} |
Distribute the CA to a service's host |
/api/knowledge
| Method |
Path |
Purpose |
| GET |
/api/knowledge/playbooks |
List recorded playbooks |
| GET |
/api/knowledge/insights/{service} |
Per-service insights |
/api/mcp
| Method |
Path |
Purpose |
| GET |
/api/mcp/status |
FastMCP server status + base URL |
| GET |
/api/mcp/config |
SSE config for MCP clients |
| GET |
/api/mcp/tools |
List registered MCP tools |
| POST |
/api/mcp/tools |
Create a tool (code + metadata) |
| GET |
/api/mcp/tools/{name} |
Tool definition |
| PUT |
/api/mcp/tools/{name} |
Update tool |
| DELETE |
/api/mcp/tools/{name} |
Delete tool |
| GET |
/api/mcp/audit/logs |
Audit log of tool operations |
See MCP Tools for the FastMCP-side surface.
/api/metrics
| Method |
Path |
Purpose |
| GET |
/api/metrics/all |
Snapshot of all device metrics |
| GET |
/api/metrics?format=prometheus |
Prometheus-format scrape |
WebSocket endpoints
| Path |
What it streams |
/api/metrics/ws |
Per-device CPU / memory / disk metrics, subscription-based |
/api/uptime/ws |
Service start / stop / failure events (live event stream) |
/ws |
Deployment events (logs from in-flight deploys) |
See Health Monitoring for the message shapes.
Stability
The API is in alpha. Until v1.0, paths and shapes can change between releases. Subscribe to the changelog for breaking changes.
What's not exposed via HTTP
A few subsystems are CLI-only today:
- The full
observe / diagnose / solve / standardize cycle (the web UI exposes diagnostics/run only)
- Cluster compose orchestration (
portoser cluster compose up)
- Registry edits (use
$EDITOR registry.yml and reload)
These are likely to gain HTTP surface, but only if there's a clear use case for it from the UI or MCP.