API Reference

LiteSoup exposes a dashboard REST API and per-server agent endpoints. All dashboard endpoints require JWT authentication.

Authentication

Login via POST /api/auth/login. A JWT cookie is set automatically on success.

Request
POST /api/auth/login
Content-Type: application/json

{
  "email": "admin@example.com",
  "password": "your-password"
}
200 · Success
{
  "user": { "id": 1, "email": "admin@example.com", "name": "Admin" }
}
401 · Unauthorized
{
  "error": "Unauthorized",
  "message": "Invalid email or password"
}

Servers

List Servers

Request
GET /api/servers
200 · Success
{
  "servers": [{
    "id": 1, "name": "JP-1", "hostname": "jp1.codetot.org",
    "port": 22, "user": "root", "tags": ["production"],
    "os": "Ubuntu 24.04", "version": "0.9.0",
    "sites_count": 3, "last_sync": "2026-07-14T07:30:00Z"
  }]
}
401 · Unauthorized
{ "error": "Unauthorized" }

Connect a Server

Request
POST /api/servers
Content-Type: application/json

{
  "name": "SG-1", "hostname": "sg1.example.com",
  "port": 2222, "user": "root", "tags": ["staging"]
}
201 · Created
{
  "server": { "id": 2, "name": "SG-1", "status": "pending" }
}
422 · Validation Error
{
  "error": "Validation failed",
  "fields": { "hostname": ["The hostname field is required."] }
}

Get Server Details

Request
GET /api/servers/1
200 · Success
{
  "server": {
    "id": 1, "name": "JP-1", "hostname": "jp1.codetot.org",
    "port": 22, "tags": ["production"],
    "os": "Ubuntu 24.04", "version": "0.9.0", "sites_count": 3,
    "metrics": { "cpu": 23.5, "ram": { "used": 2048, "total": 8192, "unit": "MB" } }
  }
}
404 · Not Found
{
  "error": "Not found",
  "message": "Server with id 99 not found"
}

Update Server

Request
PATCH /api/servers/1
Content-Type: application/json

{ "name": "Tokyo-Prod-1", "tags": ["production"] }
200 · Updated
{
  "server": { "id": 1, "name": "Tokyo-Prod-1", "tags": ["production"] }
}
404 · Not Found
{ "error": "Not found", "message": "Server not found" }

Sites

List Sites

Request
GET /api/servers/1/sites
200 · Success
{
  "sites": [{
    "id": 1, "domain": "example.com", "user": "litesoup",
    "php": "8.2", "tier": "small", "tls": "letsencrypt", "wp_version": "6.7",
    "updates": { "plugins": 2, "themes": 1, "core": false }
  }]
}
404 · Server Not Found
{ "error": "Not found", "message": "Server not found" }

Create a Site

Request
POST /api/servers/1/sites
Content-Type: application/json

{
  "domain": "newsite.com", "php": "8.3",
  "tier": "medium", "tls": "letsencrypt",
  "email": "admin@example.com"
}
201 · Provisioning
{
  "site": { "id": 2, "domain": "newsite.com", "status": "provisioning" }
}
422 · Duplicate Domain
{
  "error": "Validation failed",
  "fields": { "domain": ["The domain has already been taken."] }
}

Get Site Detail

Request
GET /api/servers/1/sites/1
200 · Success
{
  "site": {
    "id": 1, "domain": "example.com", "user": "litesoup",
    "docroot": "/home/litesoup/webapps/example.com",
    "php": "8.2", "tier": "small", "tls": "letsencrypt",
    "framework": "wordpress", "wp_version": "6.7",
    "db_name": "wp_example_com", "created_at": "2026-07-14T07:00:00Z"
  }
}
404 · Not Found
{ "error": "Not found", "message": "Site not found on this server" }

Server Actions

Trigger Sync

Request
POST /api/servers/1/sync
200 · Sync (SSE)
event: log
data: {"message": "Syncing..."}\nevent: complete
data: {"status": "ok", "sites": 3}
503 · Agent Offline
{ "error": "Agent offline", "message": "Agent not reachable" }

WordPress Scan

Request
POST /api/servers/1/wp-scan
Content-Type: application/json
{ "site_id": 1 }
200 · Scan (SSE)
event: log
data: {"message": "Scanning..."}\nevent: complete
data: {"wp_version": "6.7", "plugins": 12}
404 · Not Found
{ "error": "Not found", "message": "Site not found" }

Apply Pool Tier

Request
POST /api/servers/1/pool-apply
Content-Type: application/json
{ "user": "litesoup", "php_version": "8.2", "tier": "medium" }
200 · Applied
{ "status": "ok", "message": "Pool updated to tier medium" }
422 · Invalid Tier
{
  "error": "Validation failed",
  "fields": { "tier": ["Tier must be: small, medium, large"] }
}

Activity & Settings

Activity Log

Request
GET /api/activity?limit=10
200 · Success
{
  "activities": [{ "id": 42, "type": "site.create", "domain": "newsite.com", "status": "success", "created_at": "2026-07-14T07:30:00Z" }],
  "total": 156
}
401 · Unauthorized
{ "error": "Unauthorized" }

Get Settings

Request
GET /api/settings
200 · Success
{
  "settings": { "default_php": "8.2", "sync_interval": 300, "email_notifications": true }
}
401 · Unauthorized
{ "error": "Unauthorized" }

Update Setting

Request
PUT /api/settings/sync_interval
Content-Type: application/json
{ "value": 600 }
200 · Updated
{ "key": "sync_interval", "value": 600, "updated": true }
422 · Validation Error
{
  "error": "Validation failed",
  "fields": { "value": ["Must be a positive integer"] }
}

Agent Endpoints

MethodPathDescription
GET/healthLiveness
GET/metricsCPU, RAM, disk
GET/servicesService statuses
GET/sitesDiscovered sites
POST/execExecute (SSE)
POST/sites/wp-scanWP scan (SSE)
POST/sites/db-passwordRead DB password

Exec Command

Request
POST /exec
Content-Type: application/json
{ "command": "site.create", "params": { "domain": "newsite.com", "php": "8.3" } }
200 · Complete (SSE)
event: log
data: {"message": "Creating..."}\nevent: complete
data: {"status": "ok", "domain": "newsite.com"}
400 · Bad Request
{ "error": "Bad request", "message": "Unknown command: site.invalid" }

DB Password

Request
POST /sites/db-password
Content-Type: application/json
{ "domain": "example.com" }
200 · Success
{ "password": "aB3x...K9m2" }
404 · Not Found
{ "error": "Not found", "message": "Site example.com not found" }