Skip to content

VeloPanel API Reference

VeloPanel exposes a comprehensive REST API on port 7070 that powers both the web UI and external automation. Every response uses the same JSON envelope:

// Success
{ "ok": true,  "data": { ... } }

// Error
{ "ok": false, "error": "Human-readable error message" }

Authentication

All endpoints (except login, logout, and initial setup) require a JWT token. Pass it as either:

  • Bearer token: Authorization: Bearer <token>
  • Cookie: velopanel_token=<token> (set automatically by the login endpoint)

Get a token

# First-time setup — create the admin account (only works once)
curl -s -X POST http://localhost:7070/api/auth/setup \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"MySecurePass123"}'

# Login
TOKEN=$(curl -s -X POST http://localhost:7070/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"MySecurePass123"}' \
  | jq -r '.data.token')

# Use on all subsequent requests
AUTH="Authorization: Bearer $TOKEN"

Tokens expire after 24 hours.

Auth endpoints

Method Endpoint Auth Description
POST /api/auth/setup No Create first admin — disabled after first use
POST /api/auth/login No Login, returns JWT + sets velopanel_token cookie
POST /api/auth/logout No Clears session cookie
GET /api/auth/me Yes Returns current user's username and role

Accounts

Hosting accounts map 1:1 to Linux system users. Creating an account also creates the primary domain, generates a VeloServe vhost, and reloads the web server.

Create an account

curl -s -X POST http://localhost:7070/api/accounts \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
    "username": "johndoe",
    "domain": "example.com",
    "email": "john@example.com",
    "password": "UserPass123",
    "plan": "free"
  }'

Request body:

Field Type Required Description
username string Yes 3–16 alphanumeric characters
domain string Yes Primary domain name
email string Yes Contact email
password string Yes Min 8 characters
plan string Yes free, pro, or business

Response:

{
  "ok": true,
  "data": {
    "id": 1,
    "username": "johndoe",
    "primary_domain": "example.com",
    "email": "john@example.com",
    "plan": "free",
    "status": "active",
    "disk_quota_mb": 500,
    "bandwidth_quota_mb": 10000,
    "disk_used_mb": 0,
    "created_at": "2026-02-28 15:44:05",
    "updated_at": "2026-02-28 15:44:05"
  }
}

License Limits

On the Community tier, account creation is capped at 5 accounts. Attempting to create a 6th returns: {"ok":false,"error":"Account limit reached (5/5). Upgrade your license for more."}

All account endpoints

Method Endpoint Description
GET /api/accounts List all accounts
POST /api/accounts Create account
GET /api/accounts/:id Get account by ID
DELETE /api/accounts/:id Delete account (removes system user, vhosts, reloads VeloServe)
POST /api/accounts/:id/suspend Suspend account
POST /api/accounts/:id/unsuspend Re-activate account

Examples

# List all accounts
curl -s http://localhost:7070/api/accounts -H "$AUTH"

# Get account #1
curl -s http://localhost:7070/api/accounts/1 -H "$AUTH"

# Suspend
curl -s -X POST http://localhost:7070/api/accounts/1/suspend -H "$AUTH"

# Unsuspend
curl -s -X POST http://localhost:7070/api/accounts/1/unsuspend -H "$AUTH"

# Delete (cascades to all domains, vhosts, system user)
curl -s -X DELETE http://localhost:7070/api/accounts/1 -H "$AUTH"

Domains

Each account can have a primary domain (created with the account) plus addon domains, subdomains, and aliases. Every domain gets a VeloServe vhost config auto-generated.

Create a domain

curl -s -X POST http://localhost:7070/api/domains \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
    "account_id": 1,
    "domain_name": "blog.example.com",
    "domain_type": "addon",
    "document_root": "/home/johndoe/blog"
  }'

Request body:

Field Type Required Description
account_id integer Yes Parent account ID
domain_name string Yes Fully qualified domain name
domain_type string Yes primary, addon, subdomain, or alias
document_root string Yes Absolute path to document root

License Limits

Community tier is limited to 10 total domains across all accounts.

All domain endpoints

Method Endpoint Description
GET /api/domains List all domains
POST /api/domains Create domain
GET /api/domains/account/:id List domains for a specific account
DELETE /api/domains/:id Delete domain (removes vhost, reloads VeloServe)

SSL / Let's Encrypt

VeloPanel includes a built-in ACME client for Let's Encrypt. Certificates are provisioned via HTTP-01 challenge and stored in /etc/veloserve/ssl/.

Prerequisites

  • Set acme_email in your config
  • The domain must resolve to this server on port 80

Provision a certificate

curl -s -X POST http://localhost:7070/api/ssl/provision \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"domain":"example.com"}'

Request body:

Field Type Required Description
domain string Yes Domain to provision
webroot string No Custom webroot for challenge files

All SSL endpoints

Method Endpoint Description
GET /api/ssl/certificates List all certificates with issuer, expiry, and file info
POST /api/ssl/provision Provision Let's Encrypt certificate for a domain
GET /api/ssl/certificate/:domain Detailed cert info (subject, issuer, dates, serial, renewal status)
GET /api/ssl/renew/:domain Renew certificate for a specific domain
POST /api/ssl/auto-renew Bulk renew all certificates expiring within 30 days

Auto-renewal response

{
  "ok": true,
  "data": {
    "renewed": ["example.com", "blog.example.com"],
    "skipped": ["fresh-cert.com"],
    "errors": []
  }
}

Databases

Create and manage MySQL and PostgreSQL databases per hosting account. Each database gets a dedicated user with access restricted to that database only.

Create a database

curl -s -X POST http://localhost:7070/api/databases \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
    "account_id": 1,
    "db_name": "wordpress",
    "db_password": "DbSecure12345",
    "engine": "mysql"
  }'

Request body:

Field Type Required Description
account_id integer Yes Owning account ID
db_name string Yes Database name (prefixed with account username)
db_password string Yes Min 8 characters
engine string No mysql (default), mariadb, postgresql, or postgres

Response:

{
  "ok": true,
  "data": {
    "engine": "mysql",
    "database": "johndoe_wordpress",
    "user": "johndoe_wordpress",
    "host": "localhost"
  }
}

All database endpoints

Method Endpoint Description
GET /api/databases/engines List available DB engines and their versions
GET /api/databases/:account_id List all databases for an account
POST /api/databases Create database + user
DELETE /api/databases/:account_id/:db_name Drop database and user

File Manager

Browse, read, write, and manage files within account home directories. All paths are sandboxed — you cannot escape the account's home directory.

Examples

# List directory contents
curl -s "http://localhost:7070/api/files/list?account_id=1&path=/" -H "$AUTH"

# Read a file
curl -s "http://localhost:7070/api/files/read?account_id=1&path=/public_html/index.html" -H "$AUTH"

# Write a file
curl -s -X POST http://localhost:7070/api/files/write \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{
    "account_id": 1,
    "path": "/public_html/index.html",
    "content": "<html><body><h1>Hello World</h1></body></html>"
  }'

# Create directory
curl -s -X POST http://localhost:7070/api/files/mkdir \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"path":"/public_html/assets"}'

# Set permissions
curl -s -X POST http://localhost:7070/api/files/chmod \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"path":"/public_html/index.html","mode":"644"}'

# Delete
curl -s -X DELETE http://localhost:7070/api/files/delete \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"path":"/public_html/old-page.html"}'

All file endpoints

Method Endpoint Params Description
GET /api/files/list account_id, path (query) List directory entries with size, type, permissions
GET /api/files/read account_id, path (query) Read file contents
POST /api/files/write account_id, path, content (body) Create or overwrite file
POST /api/files/mkdir account_id, path (body) Create directory
POST /api/files/chmod account_id, path, mode (body) Set permissions (octal, e.g. "755")
DELETE /api/files/delete account_id, path (body) Delete file or directory

PHP Management

Detect and manage PHP versions installed on the server. Set per-account PHP version and execution mode.

Examples

# List installed PHP versions
curl -s http://localhost:7070/api/php/versions -H "$AUTH"

# Get PHP config for account #1
curl -s http://localhost:7070/api/php/config/1 -H "$AUTH"

# Set PHP version and mode
curl -s -X POST http://localhost:7070/api/php/version/1 \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"version":"8.3","mode":"fpm"}'

Endpoints

Method Endpoint Description
GET /api/php/versions Detected PHP versions on the server
GET /api/php/config/:account_id Current PHP version and mode for an account
POST /api/php/version/:account_id Set PHP version and mode (cgi, fpm, or lsapi)

LSAPI Mode

The lsapi mode requires a Pro or Business license.


Backups

Full account backups include the home directory (tar.gz) and MySQL database dumps. Backups can be stored locally or uploaded to S3/SFTP remote targets.

Examples

# List backups for account #1
curl -s http://localhost:7070/api/backups/accounts/1 -H "$AUTH"

# Create a full backup
curl -s -X POST http://localhost:7070/api/backups/accounts/1 -H "$AUTH"

# Restore from backup
curl -s -X POST \
  http://localhost:7070/api/backups/accounts/1/restore/johndoe-20260228-120000.tar.gz \
  -H "$AUTH"

# Delete a backup
curl -s -X DELETE \
  http://localhost:7070/api/backups/accounts/1/johndoe-20260228-120000.tar.gz \
  -H "$AUTH"

# Cleanup backups older than 30 days
curl -s -X POST http://localhost:7070/api/backups/cleanup \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"retention_days":30}'

Endpoints

Method Endpoint Description
GET /api/backups/accounts/:id List backups for account
POST /api/backups/accounts/:id Create full backup
POST /api/backups/accounts/:id/restore/:filename Restore from backup
DELETE /api/backups/accounts/:id/:filename Delete backup file
POST /api/backups/cleanup Remove backups older than retention_days (default: 30)
GET /api/backups/remote-targets List configured S3/SFTP remote targets

System & VeloServe

Monitor server resources and control the VeloServe web server.

System info

# Server details
curl -s http://localhost:7070/api/system/info -H "$AUTH"
{
  "ok": true,
  "data": {
    "hostname": "web01.example.com",
    "os": "Linux (Ubuntu 24.04)",
    "cpu_count": 4,
    "cpu_usage_percent": 12.5,
    "memory_total_mb": 8192,
    "memory_used_mb": 3200,
    "disk_total_mb": 100000,
    "disk_used_mb": 45000
  }
}

Dashboard stats

curl -s http://localhost:7070/api/system/stats -H "$AUTH"
{
  "ok": true,
  "data": {
    "accounts": { "count": 3, "limit": 5 },
    "domains": { "count": 7, "limit": 10 },
    "cpu": { "count": 4, "usage_percent": 12.5 },
    "memory": { "total_mb": 8192, "used_mb": 3200 },
    "disk": { "total_mb": 100000, "used_mb": 45000 },
    "license": { "tier": "community", "valid": true },
    "uptime_secs": 86400,
    "load_average": [0.5, 0.3, 0.2]
  }
}

VeloServe management

# Check status (installed, running, version, PID)
curl -s http://localhost:7070/api/veloserve/status -H "$AUTH"

# Get version
curl -s http://localhost:7070/api/veloserve/version -H "$AUTH"

# Regenerate ALL vhost configs from database and reload
curl -s -X POST http://localhost:7070/api/veloserve/regenerate -H "$AUTH"

# Just reload (after manual config edits)
curl -s -X POST http://localhost:7070/api/veloserve/reload -H "$AUTH"

Endpoints

Method Endpoint Description
GET /api/system/info Server hostname, OS, CPU, RAM, disk
GET /api/system/stats Dashboard stats (accounts, domains, limits, resource usage)
GET /api/veloserve/status VeloServe installed/running/version/PID/uptime
GET /api/veloserve/version VeloServe binary version string
POST /api/veloserve/regenerate Regenerate all vhost configs from DB + reload
POST /api/veloserve/reload Reload VeloServe configuration

Error Codes

HTTP Status Meaning
200 Success
400 Bad request — validation error, missing fields
401 Unauthorized — missing or invalid JWT token
403 Forbidden — license limit exceeded or feature not available
500 Internal server error

Quick-start Script

A complete example that sets up admin, creates an account, adds a domain, writes a page, creates a database, and provisions SSL:

#!/usr/bin/env bash
set -euo pipefail
PANEL="http://localhost:7070"

# 1. Setup admin (first run only)
curl -s -X POST "$PANEL/api/auth/setup" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"SecureAdmin123"}'

# 2. Login
TOKEN=$(curl -s -X POST "$PANEL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"SecureAdmin123"}' \
  | jq -r '.data.token')
AUTH="Authorization: Bearer $TOKEN"

# 3. Create a hosting account
curl -s -X POST "$PANEL/api/accounts" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"username":"johndoe","domain":"example.com","email":"john@example.com","password":"UserPass123","plan":"free"}'

# 4. Add an addon domain
curl -s -X POST "$PANEL/api/domains" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"domain_name":"blog.example.com","domain_type":"addon","document_root":"/home/johndoe/blog"}'

# 5. Write an index page
curl -s -X POST "$PANEL/api/files/write" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"path":"/public_html/index.html","content":"<h1>Welcome to example.com</h1>"}'

# 6. Create a MySQL database
curl -s -X POST "$PANEL/api/databases" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"account_id":1,"db_name":"wordpress","db_password":"DbPass12345","engine":"mysql"}'

# 7. Provision SSL (requires DNS pointing to this server)
curl -s -X POST "$PANEL/api/ssl/provision" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"domain":"example.com"}'

# 8. Check dashboard
curl -s "$PANEL/api/system/stats" -H "$AUTH" | jq .