-
Notifications
You must be signed in to change notification settings - Fork 1
Reference
Complete API documentation for nself Admin, including all endpoints, authentication, and examples.
- Overview
- Authentication
- Base URL
- Response Format
- Error Handling
- Rate Limiting
- API Endpoints
- Auth
- Project
- Services
- Docker
- System
- Database
- Files
- Monitoring
nself Admin provides a RESTful API for managing your development stack. All API operations that the UI performs are available for programmatic access.
- RESTful Design: Standard HTTP methods and status codes
- JSON Format: All requests and responses use JSON
- Token Authentication: Secure JWT-based authentication
- Real-time Updates: WebSocket support for live data
- Full Coverage: Full access to all nAdmin features
POST /api/auth/login
Content-Type: application/json
{
"password": "your-admin-password"
}Response:
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": "24h"
}Include the token in the Authorization header:
GET /api/services
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...POST /api/auth/logout
Authorization: Bearer <token>Development: http://localhost:3021/api
Production: https://your-domain.com/api
Docker: http://nself-admin:3021/api
{
"success": true,
"data": {
// Response data
},
"meta": {
"timestamp": "2024-01-12T10:30:00Z",
"version": "1.0.0"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input parameters",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}| Code | Description | Usage |
|---|---|---|
| 200 | OK | Successful GET/PUT |
| 201 | Created | Successful POST |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Missing/invalid token |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Resource already exists |
| 422 | Unprocessable | Validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal error |
| 503 | Unavailable | Service down |
const ErrorCodes = {
// Authentication
AUTH_FAILED: 'Authentication failed',
TOKEN_EXPIRED: 'Token has expired',
TOKEN_INVALID: 'Invalid token',
// Validation
VALIDATION_ERROR: 'Validation failed',
MISSING_FIELD: 'Required field missing',
INVALID_FORMAT: 'Invalid format',
// Resources
NOT_FOUND: 'Resource not found',
ALREADY_EXISTS: 'Resource already exists',
// Operations
OPERATION_FAILED: 'Operation failed',
DEPENDENCY_ERROR: 'Dependency not met',
// System
INTERNAL_ERROR: 'Internal server error',
SERVICE_UNAVAILABLE: 'Service unavailable',
}HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 98
X-RateLimit-Reset: 1642847400Default Limits:
- 100 requests per minute for authenticated users
- 20 requests per minute for unauthenticated users
- WebSocket connections: 10 per IP
POST /api/auth/setup
Content-Type: application/json
{
"password": "secure-password-123"
}Response:
{
"success": true,
"message": "Password set successfully"
}POST /api/auth/login
Content-Type: application/json
{
"password": "your-password"
}GET /api/auth/status
Authorization: Bearer <token>Response:
{
"authenticated": true,
"user": "admin",
"expiresAt": "2024-01-13T10:30:00Z"
}PUT /api/auth/password
Authorization: Bearer <token>
Content-Type: application/json
{
"currentPassword": "old-password",
"newPassword": "new-password"
}GET /api/project/info
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"name": "my_app",
"environment": "development",
"initialized": true,
"built": true,
"running": true,
"path": "/workspace",
"services": ["postgres", "hasura", "auth", "nginx", "redis", "api"]
}
}POST /api/project/init
Authorization: Bearer <token>
Content-Type: application/json
{
"projectName": "my_app",
"environment": "development",
"domain": "localhost",
"adminEmail": "admin@localhost",
"databaseName": "myapp",
"databasePassword": "secure-password"
}POST /api/project/build
Authorization: Bearer <token>Response (Streaming):
data: {"type":"log","message":"Starting build process..."}
data: {"type":"log","message":"Generating docker-compose.yml..."}
data: {"type":"log","message":"Creating service configurations..."}
data: {"type":"complete","success":true}
POST /api/project/start
Authorization: Bearer <token>POST /api/project/stop
Authorization: Bearer <token>POST /api/project/reset
Authorization: Bearer <token>
Content-Type: application/json
{
"confirm": true,
"removeVolumes": false
}GET /api/services
Authorization: Bearer <token>Response:
{
"success": true,
"data": [
{
"name": "postgres",
"status": "running",
"image": "postgres:15",
"ports": ["5432:5432"],
"health": "healthy",
"uptime": "2h 34m",
"cpu": "12%",
"memory": "256MB"
},
{
"name": "hasura",
"status": "running",
"image": "hasura/graphql-engine:latest",
"ports": ["8080:8080"],
"health": "healthy",
"uptime": "2h 33m",
"cpu": "8%",
"memory": "128MB"
}
]
}GET /api/services/{service_name}
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"name": "postgres",
"containerId": "abc123def456",
"image": "postgres:15",
"status": "running",
"created": "2024-01-12T08:00:00Z",
"started": "2024-01-12T08:00:05Z",
"ports": [
{
"container": 5432,
"host": 5432,
"protocol": "tcp"
}
],
"environment": {
"POSTGRES_DB": "myapp",
"POSTGRES_USER": "postgres"
},
"volumes": [
{
"source": "postgres_data",
"destination": "/var/lib/postgresql/data",
"mode": "rw"
}
],
"networks": ["nself_network"],
"health": {
"status": "healthy",
"checks": 5,
"lastCheck": "2024-01-12T10:30:00Z"
}
}
}POST /api/services/{service_name}/start
Authorization: Bearer <token>POST /api/services/{service_name}/stop
Authorization: Bearer <token>POST /api/services/{service_name}/restart
Authorization: Bearer <token>GET /api/services/{service_name}/logs
Authorization: Bearer <token>
Query Parameters:
- lines: Number of lines (default: 100)
- follow: Stream logs (true/false)
- timestamps: Include timestamps (true/false)Response (Streaming if follow=true):
data: 2024-01-12T10:30:00Z postgres: LOG: database system is ready
data: 2024-01-12T10:30:01Z postgres: LOG: connection received
POST /api/services/{service_name}/exec
Authorization: Bearer <token>
Content-Type: application/json
{
"command": ["psql", "-U", "postgres", "-c", "SELECT version();"]
}GET /api/docker/info
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"version": "24.0.7",
"apiVersion": "1.43",
"os": "linux",
"arch": "amd64",
"containers": {
"total": 12,
"running": 10,
"stopped": 2
},
"images": 18,
"storage": {
"driver": "overlay2",
"used": "4.2GB",
"available": "45.8GB"
}
}
}GET /api/docker/containers
Authorization: Bearer <token>
Query Parameters:
- all: Include stopped containers (true/false)
- filters: JSON filtersGET /api/docker/stats
Authorization: Bearer <token>Response:
{
"success": true,
"data": [
{
"container": "postgres",
"cpu": "12.5%",
"memory": {
"usage": "256MB",
"limit": "2GB",
"percent": "12.5%"
},
"network": {
"rx": "1.2MB",
"tx": "3.4MB"
},
"disk": {
"read": "10MB",
"write": "25MB"
}
}
]
}POST /api/docker/images/pull
Authorization: Bearer <token>
Content-Type: application/json
{
"image": "postgres:15"
}DELETE /api/docker/images/{image_id}
Authorization: Bearer <token>POST /api/docker/prune
Authorization: Bearer <token>
Content-Type: application/json
{
"containers": true,
"images": true,
"volumes": false,
"networks": true
}GET /api/system/metrics
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"cpu": {
"cores": 8,
"usage": 42.5,
"loadAverage": [2.1, 1.8, 1.5]
},
"memory": {
"total": "16GB",
"used": "6.4GB",
"free": "9.6GB",
"percent": 40
},
"disk": {
"total": "500GB",
"used": "125GB",
"free": "375GB",
"percent": 25
},
"network": {
"rx": "125MB/s",
"tx": "45MB/s"
},
"uptime": "5d 12h 34m"
}
}GET /api/system/healthResponse:
{
"status": "healthy",
"checks": {
"database": "ok",
"docker": "ok",
"disk": "ok",
"memory": "ok"
},
"version": "1.0.0",
"timestamp": "2024-01-12T10:30:00Z"
}GET /api/system/env
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"NODE_ENV": "production",
"PORT": "3021",
"NSELF_PROJECT_PATH": "/workspace",
"DATABASE_URL": "postgres://..."
}
}GET /api/database/info
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"name": "myapp",
"size": "124MB",
"tables": 18,
"connections": {
"active": 5,
"idle": 10,
"max": 100
},
"version": "PostgreSQL 15.2"
}
}GET /api/database/tables
Authorization: Bearer <token>Response:
{
"success": true,
"data": [
{
"schema": "public",
"name": "users",
"rows": 1234,
"size": "5.2MB"
},
{
"schema": "public",
"name": "posts",
"rows": 5678,
"size": "12.4MB"
}
]
}POST /api/database/query
Authorization: Bearer <token>
Content-Type: application/json
{
"query": "SELECT * FROM users LIMIT 10",
"database": "myapp"
}Response:
{
"success": true,
"data": {
"rows": [
{
"id": 1,
"email": "user@example.com",
"name": "John Doe"
}
],
"rowCount": 10,
"fields": [
{ "name": "id", "type": "integer" },
{ "name": "email", "type": "varchar" },
{ "name": "name", "type": "varchar" }
]
}
}POST /api/database/backup
Authorization: Bearer <token>
Content-Type: application/json
{
"database": "myapp",
"format": "sql",
"compress": true
}Response:
{
"success": true,
"data": {
"file": "backup-myapp-20240112-103000.sql.gz",
"size": "45MB",
"path": "/backups/backup-myapp-20240112-103000.sql.gz"
}
}POST /api/database/restore
Authorization: Bearer <token>
Content-Type: application/json
{
"file": "backup-myapp-20240112-103000.sql.gz",
"database": "myapp",
"dropExisting": true
}POST /api/database/migrations/apply
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"applied": ["001_initial_schema.sql", "002_add_users_table.sql"],
"skipped": ["003_already_applied.sql"]
}
}GET /api/files
Authorization: Bearer <token>
Query Parameters:
- path: Directory path (default: /workspace)
- recursive: Include subdirectories (true/false)Response:
{
"success": true,
"data": [
{
"name": "docker-compose.yml",
"type": "file",
"size": 2048,
"modified": "2024-01-12T10:00:00Z",
"permissions": "rw-r--r--"
},
{
"name": "services",
"type": "directory",
"modified": "2024-01-12T09:00:00Z",
"permissions": "rwxr-xr-x"
}
]
}GET /api/files/read
Authorization: Bearer <token>
Query Parameters:
- path: File pathResponse:
{
"success": true,
"data": {
"content": "version: '3.8'\n\nservices:\n postgres:\n image: postgres:15\n",
"encoding": "utf-8",
"size": 2048
}
}POST /api/files/write
Authorization: Bearer <token>
Content-Type: application/json
{
"path": "/workspace/.env",
"content": "DATABASE_URL=postgres://localhost:5432/myapp\n"
}DELETE /api/files
Authorization: Bearer <token>
Query Parameters:
- path: File pathPOST /api/files/upload
Authorization: Bearer <token>
Content-Type: multipart/form-data
- file: Binary file data
- path: Destination pathGET /api/monitoring/metrics
Authorization: Bearer <token>
Query Parameters:
- service: Service name (optional)
- metric: Metric type (cpu|memory|network|disk)
- period: Time period (1h|6h|24h|7d)Response:
{
"success": true,
"data": {
"service": "postgres",
"metric": "cpu",
"period": "1h",
"datapoints": [
{
"timestamp": "2024-01-12T09:30:00Z",
"value": 12.5
},
{
"timestamp": "2024-01-12T09:35:00Z",
"value": 13.2
}
],
"summary": {
"min": 8.1,
"max": 25.3,
"avg": 12.7,
"current": 12.5
}
}
}GET /api/monitoring/alerts
Authorization: Bearer <token>Response:
{
"success": true,
"data": [
{
"id": "alert-123",
"severity": "warning",
"service": "postgres",
"metric": "memory",
"message": "Memory usage above 80%",
"value": 82.5,
"threshold": 80,
"triggered": "2024-01-12T10:15:00Z",
"resolved": null
}
]
}POST /api/monitoring/alerts/rules
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "High CPU Usage",
"service": "api",
"metric": "cpu",
"condition": ">",
"threshold": 80,
"duration": "5m",
"severity": "warning",
"actions": [
{
"type": "email",
"to": "admin@example.com"
}
]
}const ws = new WebSocket('ws://localhost:3021/ws')
ws.onopen = () => {
// Authenticate
ws.send(
JSON.stringify({
type: 'auth',
token: 'your-jwt-token',
})
)
}// Subscribe to service logs
ws.send(
JSON.stringify({
type: 'subscribe',
channel: 'logs',
service: 'postgres',
})
)
// Subscribe to metrics
ws.send(
JSON.stringify({
type: 'subscribe',
channel: 'metrics',
services: ['postgres', 'api'],
})
)
// Subscribe to alerts
ws.send(
JSON.stringify({
type: 'subscribe',
channel: 'alerts',
})
)ws.onmessage = (event) => {
const data = JSON.parse(event.data)
switch (data.type) {
case 'log':
console.log(`[${data.service}] ${data.message}`)
break
case 'metric':
console.log(`${data.service}: ${data.metric}=${data.value}`)
break
case 'alert':
console.log(`Alert: ${data.message}`)
break
}
}import { NselfAdminClient } from '@nself/admin-client'
const client = new NselfAdminClient({
baseUrl: 'http://localhost:3021',
token: 'your-jwt-token',
})
// Get services
const services = await client.services.list()
// Start a service
await client.services.start('postgres')
// Execute query
const result = await client.database.query('SELECT * FROM users LIMIT 10')from nself_admin import Client
client = Client(
base_url="http://localhost:3021",
token="your-jwt-token"
)
# Get services
services = client.services.list()
# Start a service
client.services.start("postgres")
# Execute query
result = client.database.query(
"SELECT * FROM users LIMIT 10"
)# Login
curl -X POST http://localhost:3021/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"your-password"}'
# Get services
curl http://localhost:3021/api/services \
-H "Authorization: Bearer <token>"
# Start all services
curl -X POST http://localhost:3021/api/project/start \
-H "Authorization: Bearer <token>"
# Get logs
curl http://localhost:3021/api/services/postgres/logs?lines=50 \
-H "Authorization: Bearer <token>"For endpoints that return lists:
GET /api/database/tables?page=2&limit=20
Authorization: Bearer <token>Response:
{
"success": true,
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8,
"hasNext": true,
"hasPrev": true
}
}GET /api/services?status=running&sort=name:asc
GET /api/database/tables?schema=public&sort=rows:desc
GET /api/files?type=file&name=*.ymlPOST /api/batch
Authorization: Bearer <token>
Content-Type: application/json
{
"operations": [
{
"method": "POST",
"path": "/api/services/postgres/start"
},
{
"method": "POST",
"path": "/api/services/hasura/start"
},
{
"method": "GET",
"path": "/api/services"
}
]
}Response:
{
"success": true,
"results": [
{"success": true, "data": {"started": true}},
{"success": true, "data": {"started": true}},
{"success": true, "data": [...]}
]
}The API version is included in the response headers:
HTTP/1.1 200 OK
X-API-Version: 1.0.0Future versions will use URL versioning:
/api/v2/services
// Allowed origins
const corsOptions = {
origin: ['http://localhost:3000', 'http://localhost:3001', 'https://your-domain.com'],
credentials: true,
}// Per-endpoint limits
const rateLimits = {
'/api/auth/login': '5 per minute',
'/api/database/query': '30 per minute',
'/api/services/*/exec': '10 per minute',
default: '100 per minute',
}All inputs are validated using JSON schemas:
{
"type": "object",
"properties": {
"password": {
"type": "string",
"minLength": 12,
"pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])"
}
},
"required": ["password"]
}- Import the Postman Collection
- Set environment variables:
-
baseUrl: http://localhost:3021 -
token: Your JWT token
- Run requests
- Import the Insomnia Workspace
- Configure environment
- Execute requests
// Jest example
describe('API Tests', () => {
let token
beforeAll(async () => {
const response = await fetch('/api/auth/login', {
method: 'POST',
body: JSON.stringify({ password: 'test-password' }),
})
const data = await response.json()
token = data.token
})
test('Get services', async () => {
const response = await fetch('/api/services', {
headers: { Authorization: `Bearer ${token}` },
})
expect(response.status).toBe(200)
const data = await response.json()
expect(data.success).toBe(true)
expect(Array.isArray(data.data)).toBe(true)
})
})- Authentication Guide - Detailed auth documentation
- WebSocket Guide - Real-time communication
- Error Reference - Complete error code reference
- SDK Documentation - Client library guides
Related Documentation:
Version: 1.0.0 | Updated: 2026-05-18 05:44 UTC | GitHub