BS9 API Documentation
Overview
BS9 provides two distinct API interfaces:
- REST Management API: HTTP endpoints for remote service administration, dashboard metrics, and automation pipelines.
- Typed Runtime SDK (
bs9/runtime): In-process TypeScript/JavaScript client for shared state (State), distributed leases (Lease), and durable message queues (Queue) backed by the high-performance local IPC State Hub. See Typed Runtime API and the High-Availability Runtime Guide.
๐ Base URL
http://localhost:3000/api/v1
๐ Authentication
Session Token Authentication
# Get session token
curl -X POST http://localhost:3000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "password"}'
# Use token in requests
curl -X GET http://localhost:3000/api/v1/services \
-H "Authorization: Bearer <session-token>"
API Key Authentication
# Use API key
curl -X GET http://localhost:3000/api/v1/services \
-H "X-API-Key: <api-key>"
๐ Endpoints
Authentication
POST /api/v1/auth/login
Authenticate and get session token.
Request:
{
"username": "admin",
"password": "password"
}
Response:
{
"success": true,
"token": "REDACTED",
"expiresIn": 3600,
"user": {
"id": "admin",
"role": "administrator"
}
}
POST /api/v1/auth/logout
Invalidate session token.
Headers:
Authorization: Bearer <token>
Response:
{
"success": true,
"message": "Logged out successfully"
}
Services
GET /api/v1/services
List all services.
Response:
{
"services": [
{
"name": "my-app",
"status": "running",
"pid": 12345,
"uptime": 3600,
"memory": 52428800,
"cpu": 0.05,
"port": 3000,
"restarts": 0,
"lastRestart": "2024-01-01T12:00:00Z",
"health": "healthy"
}
],
"total": 1,
"running": 1,
"failed": 0
}
GET /api/v1/services/{name}
Get specific service details.
Response:
{
"name": "my-app",
"status": "running",
"pid": 12345,
"uptime": 3600,
"memory": 52428800,
"cpu": 0.05,
"port": 3000,
"restarts": 0,
"lastRestart": "2024-01-01T12:00:00Z",
"health": "healthy",
"config": {
"file": "/path/to/app.js",
"instances": 1,
"env": {
"NODE_ENV": "production"
},
"restart": "always"
},
"metrics": {
"requests": 1000,
"errors": 5,
"responseTime": 150
}
}
POST /api/v1/services/{name}/start
Start a service.
Request:
{
"file": "/path/to/app.js",
"instances": 2,
"env": {
"NODE_ENV": "production",
"PORT": "3000"
},
"restart": "always"
}
Response:
{
"success": true,
"message": "Service started successfully",
"service": {
"name": "my-app",
"status": "starting",
"pid": null
}
}
POST /api/v1/services/{name}/stop
Stop a service.
Request:
{
"force": false,
"timeout": 30
}
Response:
{
"success": true,
"message": "Service stopped successfully"
}
POST /api/v1/services/{name}/restart
Restart a service.
Request:
{
"zeroDowntime": false,
"force": false
}
Response:
{
"success": true,
"message": "Service restarted successfully"
}
DELETE /api/v1/services/{name}
Delete a service.
Response:
{
"success": true,
"message": "Service deleted successfully"
}
Metrics
GET /api/v1/metrics
Get system metrics.
Query Parameters:
service: Filter by service namefrom: Start time (ISO 8601)to: End time (ISO 8601)interval: Data interval (1m, 5m, 1h, 1d)
Response:
{
"metrics": {
"cpu": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 0.05
}
],
"memory": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 52428800
}
],
"requests": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 100
}
],
"errors": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 5
}
]
},
"summary": {
"avgCpu": 0.05,
"avgMemory": 52428800,
"totalRequests": 1000,
"totalErrors": 5
}
}
GET /api/v1/metrics/{service}
Get metrics for specific service.
Response:
{
"service": "my-app",
"metrics": {
"cpu": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 0.05
}
],
"memory": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 52428800
}
],
"responseTime": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 150
}
],
"throughput": [
{
"timestamp": "2024-01-01T12:00:00Z",
"value": 100
}
]
}
}
Logs
GET /api/v1/logs
Get service logs.
Query Parameters:
service: Filter by service namelevel: Filter by log level (debug, info, warn, error)from: Start time (ISO 8601)to: End time (ISO 8601)limit: Number of log entriessearch: Search term
Response:
{
"logs": [
{
"timestamp": "2024-01-01T12:00:00Z",
"level": "info",
"service": "my-app",
"message": "Server started on port 3000",
"pid": 12345,
"metadata": {
"port": 3000,
"host": "localhost"
}
}
],
"total": 100,
"hasMore": true
}
GET /api/v1/logs/{service}
Get logs for specific service.
Response:
{
"service": "my-app",
"logs": [
{
"timestamp": "2024-01-01T12:00:00Z",
"level": "info",
"message": "Server started on port 3000",
"pid": 12345
}
]
}
Alerts
GET /api/v1/alerts
Get alerts.
Query Parameters:
active: Filter by active status (true/false)severity: Filter by severity (low, medium, high, critical)from: Start time (ISO 8601)to: End time (ISO 8601)
Response:
{
"alerts": [
{
"id": "alert-123",
"name": "High CPU Usage",
"severity": "high",
"service": "my-app",
"condition": "cpu > 80",
"status": "active",
"createdAt": "2024-01-01T12:00:00Z",
"updatedAt": "2024-01-01T12:05:00Z",
"message": "CPU usage is above 80%",
"actions": ["notify"]
}
],
"total": 1,
"active": 1
}
POST /api/v1/alerts
Create alert rule.
Request:
{
"name": "High CPU Usage",
"condition": "cpu > 80",
"severity": "high",
"service": "my-app",
"actions": ["notify"],
"enabled": true,
"description": "Alert when CPU usage exceeds 80%"
}
Response:
{
"success": true,
"alert": {
"id": "alert-123",
"name": "High CPU Usage",
"condition": "cpu > 80",
"severity": "high",
"service": "my-app",
"actions": ["notify"],
"enabled": true,
"createdAt": "2024-01-01T12:00:00Z"
}
}
PUT /api/v1/alerts/{id}
Update alert rule.
Request:
{
"enabled": false,
"condition": "cpu > 90"
}
Response:
{
"success": true,
"message": "Alert updated successfully"
}
DELETE /api/v1/alerts/{id}
Delete alert rule.
Response:
{
"success": true,
"message": "Alert deleted successfully"
}
Configuration
GET /api/v1/config
Get BS9 configuration.
Response:
{
"version": "1.6.7",
"environment": "production",
"logLevel": "info",
"metrics": {
"enabled": true,
"interval": 30
},
"alerts": {
"enabled": true,
"channels": ["slack", "email"]
},
"security": {
"authentication": true,
"authorization": true
}
}
PUT /api/v1/config
Update BS9 configuration.
Request:
{
"logLevel": "debug",
"metrics": {
"interval": 15
}
}
Response:
{
"success": true,
"message": "Configuration updated successfully"
}
Health
GET /api/v1/health
Get system health status.
Response:
{
"status": "healthy",
"timestamp": "2024-01-01T12:00:00Z",
"version": "1.6.7",
"uptime": 86400,
"checks": {
"database": "healthy",
"filesystem": "healthy",
"network": "healthy",
"memory": "healthy"
},
"metrics": {
"cpu": 0.05,
"memory": 52428800,
"disk": 1073741824
}
}
GET /api/v1/health/{service}
Get service health status.
Response:
{
"service": "my-app",
"status": "healthy",
"timestamp": "2024-01-01T12:00:00Z",
"uptime": 3600,
"checks": {
"process": "healthy",
"port": "healthy",
"memory": "healthy"
},
"metrics": {
"cpu": 0.05,
"memory": 52428800,
"responseTime": 150
}
}
๐ Response Format
Success Response
{
"success": true,
"data": { ... },
"message": "Operation completed successfully"
}
Error Response
{
"success": false,
"error": {
"code": "SERVICE_NOT_FOUND",
"message": "Service not found",
"details": "Service 'my-app' does not exist"
}
}
๐จ Error Codes
| Code | Description |
|---|---|
UNAUTHORIZED |
Authentication required |
FORBIDDEN |
Insufficient permissions |
SERVICE_NOT_FOUND |
Service does not exist |
INVALID_REQUEST |
Invalid request parameters |
INTERNAL_ERROR |
Internal server error |
SERVICE_UNAVAILABLE |
Service temporarily unavailable |
๐ Rate Limiting
API requests are rate-limited to prevent abuse:
- 100 requests per minute per IP address
- 1000 requests per hour per authenticated user
Rate limit headers are included in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
๐ SDK Examples
JavaScript/Node.js
const BS9API = require('bs9-api');
const client = new BS9API({
baseURL: 'http://localhost:3000/api/v1',
token: 'your-session-token'
});
// Get all services
const services = await client.services.list();
// Start a service
await client.services.start('my-app', {
file: '/path/to/app.js',
instances: 2
});
// Get metrics
const metrics = await client.metrics.get({
service: 'my-app',
from: '2024-01-01T00:00:00Z',
to: '2024-01-01T23:59:59Z'
});
Python
import requests
class BS9Client:
def __init__(self, base_url, token=None):
self.base_url = base_url
self.token = token
self.headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}' if token else None
}
def get_services(self):
response = requests.get(
f'{self.base_url}/services',
headers=self.headers
)
return response.json()
def start_service(self, name, config):
response = requests.post(
f'{self.base_url}/services/{name}/start',
json=config,
headers=self.headers
)
return response.json()
# Usage
client = BS9Client('http://localhost:3000/api/v1', 'your-token')
services = client.get_services()
cURL
# Get services
curl -X GET http://localhost:3000/api/v1/services \
-H "Authorization: Bearer <token>"
# Start service
curl -X POST http://localhost:3000/api/v1/services/my-app/start \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"file": "/path/to/app.js", "instances": 2}'
# Get metrics
curl -X GET "http://localhost:3000/api/v1/metrics?service=my-app&from=2024-01-01T00:00:00Z" \
-H "Authorization: Bearer <token>"
๐ Webhooks
BS9 can send webhook notifications for various events:
Configure Webhook
curl -X POST http://localhost:3000/api/v1/webhooks \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-webhook-endpoint.com/bs9",
"events": ["service.started", "service.stopped", "alert.triggered"],
"secret": "your-webhook-secret"
}'
Webhook Payload
{
"event": "service.started",
"timestamp": "2024-01-01T12:00:00Z",
"service": {
"name": "my-app",
"status": "running",
"pid": 12345
},
"signature": "sha256=..."
}
Typed Runtime API (bs9/runtime)
The runtime client provides process-safe state, lease, and queue access to the same-host State Hub:
import { state, events, lease, queue, configureRuntime } from "bs9/runtime";
await state.set("key", { value: 1 }, { ttlMs: 60_000 });
const value = await state.get("key");
const count = await state.incr("counter");
const acquired = await lease.acquire("leader", { ttlMs: 15_000 });
const jobId = await queue.push("jobs", { kind: "email" });
const job = await queue.pop("jobs", { timeoutMs: 5_000 });
await events.emit("job.created", { jobId });
Available classes and singletons are State/state, Events/events, Lease/lease, and Queue/queue. Configuration helpers are configureRuntime, getRuntimeConfig, resetRuntime, and isBs9Environment. The current Events implementation dispatches to subscribers inside the same process; it is not a cross-process event bus.
Outside BS9, the default backend is process-local memory. Inside a BS9 cluster, connection failure is fatal by default. allowDegradedLocal or BS9_ALLOW_DEGRADED_LOCAL=true explicitly permits local fallback and should not be used for correctness-critical production data.
See High-Availability Runtime Guide for lifecycle guarantees and deployment boundaries.
๐งช Testing
Test Environment
BS9 provides a test environment for API testing:
# Start test server
bs9 web --test-mode --port 3001
# Use test API
curl -X GET http://localhost:3001/api/v1/test/services \
-H "X-API-Key: test-key"
Postman Collection
Import the BS9 API Postman collection from:
https://github.com/xarhang/bs9/blob/main/docs/postman-collection.json
๐ Related Documentation
Last Updated: September 17, 2026 BS9 Version: 1.6.7