OpenPanel API
OpenPanel exposes a full REST API that mirrors all web UI functionality. Every feature available in the panel can be accessed programmatically.
Authentication​
All API requests require a Bearer token obtained via the login endpoint.
Step 1 — Get a token:
curl -s -X POST https://panel.example.com/api/login \
-H "Content-Type: application/json" \
-d '{"username": "stefan", "password": "yourpassword"}'
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}
Step 2 — Use it on every request:
curl https://panel.example.com/api/account \
-H "Authorization: Bearer eyJhbGciOi..."
Tokens expire after 24 hours. Both api feature AND the specific feature must be enabled in the user's plan.
MySQL​
List databases and users​
GET /api/mysql
Authorization: Bearer <token>
{
"databases": ["mydb", "shop"],
"users": [{"username": "myuser", "host": "%"}]
}
Create a database​
POST /api/mysql
Content-Type: application/json
{"name": "newdb"}
Get database info​
GET /api/mysql/mydb
Drop a database​
DELETE /api/mysql/mydb
List users for a database​
GET /api/mysql/mydb/users
Add user to database​
POST /api/mysql/mydb/users
Content-Type: application/json
{"username": "dbuser", "password": "securepass"}
Remove user from database​
DELETE /api/mysql/mydb/users/dbuser
PostgreSQL​
List databases and users​
GET /api/postgresql
Create a database​
POST /api/postgresql
Content-Type: application/json
{"name": "pgdb"}
Drop a database​
DELETE /api/postgresql/pgdb
List all users​
GET /api/postgresql/users
Create a user​
POST /api/postgresql/users
Content-Type: application/json
{"username": "pguser", "password": "securepass"}
Drop a user​
DELETE /api/postgresql/users/pguser
Assign user to database​
POST /api/postgresql/pgdb/assign/pguser
Revoke user from database​
DELETE /api/postgresql/pgdb/revoke/pguser
Domains​
List all domains​
GET /api/domains
{
"domains": [
{"domain_id": 1, "domain_url": "example.com", "docroot": "/var/www/html"}
]
}
Add a domain​
POST /api/domains
Content-Type: application/json
{"domain": "newdomain.com"}
Remove a domain​
DELETE /api/domains/olddomain.com
Get SSL status​
GET /api/domains/example.com/ssl
Issue / renew SSL​
POST /api/domains/example.com/ssl
Email​
List mailboxes​
GET /api/emails
Create mailbox​
POST /api/emails
Content-Type: application/json
{"email": "[email protected]", "password": "mailpass123"}
Get mailbox details​
GET /api/emails/[email protected]
Change mailbox password​
PATCH /api/emails/[email protected]
Content-Type: application/json
{"password": "newpass456"}
Delete mailbox​
DELETE /api/emails/[email protected]
List aliases​
GET /api/emails/aliases
Create alias​
POST /api/emails/aliases
Content-Type: application/json
{"source": "[email protected]", "destination": "[email protected]"}
Delete alias​
DELETE /api/emails/aliases/[email protected]
Get catch-all address​
GET /api/emails/default/example.com
Set catch-all address​
PUT /api/emails/default/example.com
Content-Type: application/json
{"address": "[email protected]"}
Check deliverability (all domains)​
GET /api/emails/deliverability
Check deliverability for a domain​
GET /api/emails/deliverability/example.com
Get Sieve mail filters​
GET /api/emails/filters/[email protected]
Update Sieve filters​
PUT /api/emails/filters/[email protected]
Content-Type: application/json
{"rules": "require [\"fileinto\"];\nif header :contains \"Subject\" \"SPAM\" { fileinto \"Junk\"; }"}
FTP​
List FTP accounts​
GET /api/ftp
Create FTP account​
POST /api/ftp
Content-Type: application/json
{"username": "ftpuser", "password": "ftppass", "path": "/var/www/html"}
Delete FTP account​
DELETE /api/ftp/ftpuser
Change FTP password​
PATCH /api/ftp/ftpuser/password
Content-Type: application/json
{"password": "newftppass"}
Change FTP home path​
PATCH /api/ftp/ftpuser/path
Content-Type: application/json
{"path": "/var/www/html/subdir"}
List active FTP connections​
GET /api/ftp/connections
Cron Jobs​
List all cron jobs​
GET /api/crons
{
"jobs": [
{"schedule": "0 * * * *", "command": "/usr/bin/php /var/www/html/cron.php", "valid": true}
]
}
Create a cron job​
POST /api/crons
Content-Type: application/json
{"schedule": "*/5 * * * *", "command": "/usr/bin/php /var/www/html/run.php"}
Edit a cron job​
PATCH /api/crons
Content-Type: application/json
{
"original_schedule": "*/5 * * * *",
"original_command": "/usr/bin/php /var/www/html/run.php",
"schedule": "0 */2 * * *",
"command": "/usr/bin/php /var/www/html/run.php"
}
Delete a cron job​
DELETE /api/crons
Content-Type: application/json
{"schedule": "*/5 * * * *", "command": "/usr/bin/php /var/www/html/run.php"}
Get raw crontab​
GET /api/crons/raw
Save raw crontab​
PUT /api/crons/raw
Content-Type: application/json
{"content": "0 * * * * /usr/bin/php /var/www/html/cron.php\n"}
Tail cron log​
GET /api/crons/log?lines=50&job=cron.php
Cache Services​
Each cache service exposes two endpoints: status and action.
Redis​
GET /api/cache/redis
POST /api/cache/redis
Content-Type: application/json
{"action": "enable"} # enable | disable | restart
Valkey / Memcached / Elasticsearch / OpenSearch​
Same pattern, replace redis with the service name:
GET /api/cache/valkey
POST /api/cache/valkey {"action": "disable"}
GET /api/cache/memcached
POST /api/cache/memcached {"action": "restart"}
GET /api/cache/elasticsearch
POST /api/cache/elasticsearch {"action": "enable"}
GET /api/cache/opensearch
POST /api/cache/opensearch {"action": "enable"}
Varnish​
# Status + domain list
GET /api/cache/varnish
# Enable/disable
POST /api/cache/varnish
{"action": "enable"}
# Hit ratio and traffic stats
GET /api/cache/varnish/stats
# Per-domain Varnish status
GET /api/cache/varnish/domains
# Toggle Varnish for a specific domain
POST /api/cache/varnish/domains/example.com
{"status": "On"}
Docker / Containers​
List compose services​
GET /api/containers
List running containers​
GET /api/containers/status
Get single container state​
GET /api/containers/nginx/status
Start / stop / restart​
POST /api/containers/nginx/start
POST /api/containers/nginx/stop
POST /api/containers/nginx/restart
Start with optional pull:
POST /api/containers/nginx/start
{"pull": true}
Update CPU/RAM limits​
PATCH /api/containers/myapp/resources
Content-Type: application/json
{"cpu": "1", "ram": "512m"}
Tail container logs​
GET /api/containers/nginx/logs?lines=200
WAF (Web Application Firewall)​
Status for all domains​
GET /api/waf
Status for a domain​
GET /api/waf/example.com
Toggle WAF on/off​
POST /api/waf/example.com
Content-Type: application/json
{"status": "On"}
Update excluded rules​
PUT /api/waf/example.com/rules
Content-Type: application/json
{
"remove_by_id": ["920170", "941100"],
"remove_by_tag": ["attack-sqli"]
}
Paginated WAF log​
GET /api/waf/log/example.com?page=1&per_page=25
WAF stats​
GET /api/waf/stats/example.com?seconds=3600
List rule IDs / tags​
GET /api/waf/ids/ids
GET /api/waf/ids/tags
IP Blocker​
List blocked IPs​
GET /api/ip-blocker
Block IPs​
POST /api/ip-blocker
Content-Type: application/json
{"ips": ["1.2.3.4", "10.0.0.0/8"]}
Unblock all IPs​
DELETE /api/ip-blocker
PHP​
List installed PHP versions​
GET /api/php/versions
Get php.ini content​
GET /api/php/8.2/ini
Save php.ini​
PUT /api/php/8.2/ini
Content-Type: application/json
{"content": "memory_limit = 256M\nupload_max_filesize = 64M\n..."}
Get PHP option keys and values​
GET /api/php/8.2/options
Update specific PHP options​
PUT /api/php/8.2/options
Content-Type: application/json
{"memory_limit": "256M", "upload_max_filesize": "64M", "max_execution_time": "300"}
List extensions with state​
GET /api/php/8.2/extensions
{
"extensions": [
{"name": "imagick", "state": "active"},
{"name": "redis", "state": "disabled"},
{"name": "swoole", "state": "not_installed"}
]
}
Toggle extension​
POST /api/php/8.2/extensions
Content-Type: application/json
{"extension": "imagick", "action": "enable"}
List all supported extensions​
GET /api/php/8.2/extensions/available
Install an extension​
POST /api/php/8.2/extensions/install
Content-Type: application/json
{"extension": "swoole"}
{"install_id": "swoole_1704067200", "message": "Installation started"}
Poll install status​
GET /api/php/8.2/extensions/install/status?install_id=swoole_1704067200
Account​
Get account info​
GET /api/account
{
"username": "stefan",
"email": "[email protected]",
"plan_id": 1,
"context": "stefan"
}
Update account​
PATCH /api/account
Content-Type: application/json
{"email": "[email protected]"}
# or
{"password": "newpass"}
# or
{"username": "newname"}
List active sessions​
GET /api/account/sessions
Terminate a session​
DELETE /api/account/sessions/<token>
Resource Usage​
Latest snapshot​
GET /api/usage
{
"cpu": {"usage": {"pct": 12.5}},
"memory": {"usage_pct": 45, "used": {"human": "900MB"}, "total": {"human": "2GB"}},
"bandwidth": {"usage_pct": 5, "limit": {"human": "100GB"}}
}
Paginated history​
GET /api/usage/history?page=1&per_page=25
Disk Usage & Inodes​
Disk usage (root)​
GET /api/disk-usage
Disk usage for a path​
GET /api/disk-usage/public_html
{
"directory": "public_html",
"entries": [
{"size": "120M", "path": "wp-content"},
{"size": "3.2M", "path": "wp-includes"}
]
}
Inode count (root)​
GET /api/inodes
Inode count for a path​
GET /api/inodes/public_html
Malware Scanner​
List quarantined files​
GET /api/malware-scanner/quarantine
Run a scan​
POST /api/malware-scanner/scan
Content-Type: application/json
{"directory": "/var/www/html"}
{
"directory": "/var/www/html",
"infected_files": [],
"infected_count": 0,
"summary": ["Scanned files: 1234", "Infected files: 0"],
"return_code": 0
}
Webserver Config​
Get config​
GET /api/webserver-conf
{
"web_server": "nginx",
"label": "Nginx",
"filename": "nginx.conf",
"content": "server { ... }"
}
Save config​
PUT /api/webserver-conf
Content-Type: application/json
{"content": "server {\n listen 80;\n ...\n}"}
Process Manager​
List running processes​
GET /api/process-manager
{
"processes": [
{"container": "nginx", "pid": "1234", "cmd": "nginx: master process", "uid": "0"}
],
"count": 1
}
Kill a process​
DELETE /api/process-manager/1234
Sites & Websites​
List all websites​
GET /api/sites
Get website details​
GET /api/sites/example.com
Google Safe Browsing check​
GET /api/sites/example.com/safebrowsing
{"status": "safe", "url": "http://example.com", "threats": []}
Get PageSpeed data​
GET /api/sites/example.com/pagespeed
Trigger PageSpeed refresh​
POST /api/sites/example.com/pagespeed
Get WP vulnerability data​
GET /api/sites/example.com/wp-vulnerability
Run vulnerability scan​
POST /api/sites/example.com/wp-vulnerability
WordPress​
List all WordPress installations​
GET /api/wordpress
List backups​
GET /api/wordpress/example.com/backups
{
"backups": [
{"date": "2025-01-15_12-00-00", "hasDbBackup": true, "hasFilesBackup": true}
]
}
Create backup​
POST /api/wordpress/example.com/backups
Content-Type: application/json
{"backup_database": true, "backup_files": true}
Restore a backup​
POST /api/wordpress/example.com/restore
Content-Type: application/json
{"backup_date": "2025-01-15_12-00-00"}
List available hardening rules​
GET /api/wordpress/secure
{"rules": ["wp_manager_xmlrpc", "wp_manager_user_enum", "wp_manager_wlwmanifest"]}
Get active hardening rules​
GET /api/wordpress/example.com/secure
Apply hardening rules​
PUT /api/wordpress/example.com/secure
Content-Type: application/json
{"rules": ["wp_manager_xmlrpc", "wp_manager_wlwmanifest"], "disable_all": false}
Disable all rules:
PUT /api/wordpress/example.com/secure
{"disable_all": true}
Uninstall WordPress​
Removes files and drops the database.
DELETE /api/wordpress/sites/42
Detach from WordPress Manager​
Removes from manager, keeps files.
POST /api/wordpress/sites/42/detach
Reload WP data from filesystem​
POST /api/wordpress/reload
WP-CLI actions​
Available actions: core_update, core_update_check, plugin_update_all, theme_update_all, list_plugins, list_themes, cache_flush, cron_run
POST /api/wp-cli/plugin_update_all
Content-Type: application/json
{"domain": "example.com"}
{
"action": "plugin_update_all",
"domain": "example.com",
"stdout": "Success: Updated 3 of 3 plugins.",
"returncode": 0
}
Node.js / Python Apps (PM2)​
Tail app logs​
GET /api/pm2/example.com/logs?lines=100
Start application​
POST /api/pm2/example.com/start
Stop application​
POST /api/pm2/example.com/stop
Restart application (pull + restart)​
POST /api/pm2/example.com/restart
Update app settings​
PATCH /api/pm2/example.com
Content-Type: application/json
{
"version": "20",
"startup_file": "/var/www/html/index.js",
"cpu": "1",
"ram": "1"
}
Delete app​
Stops container, reverts webserver config, removes from docker-compose.yml, and deletes from DB.
DELETE /api/pm2/example.com
Auto Installer​
List installed apps​
GET /api/autoinstaller
{
"sites": [{"site_name": "example.com", "type": "WordPress"}],
"counts": {"wordpress": 1, "node": 0, "python": 0},
"technologies": ["wordpress", "drupal", "node", "python", "...]
}
Dynamic DNS​
List all entries​
GET /api/dynamic-dns
{
"domains": {
"example.com": [
{"subdomain": "home", "record": "1.2.3.4", "token": "abc123xyz", "last_updated": "2025-01-15T12:00:00Z"}
]
}
}
Create entry​
POST /api/dynamic-dns
Content-Type: application/json
{"domain": "example.com", "subdomain": "home", "ip": "0.0.0.0"}
{"entry": {"subdomain": "home", "record": "0.0.0.0", "type": "A", "token": "abc123xyz"}}
Update entry​
PUT /api/dynamic-dns
Content-Type: application/json
{
"domain": "example.com",
"line_number": 42,
"subdomain": "home",
"ip": "1.2.3.4",
"token": "abc123xyz"
}
Delete entry​
DELETE /api/dynamic-dns
Content-Type: application/json
{"domain": "example.com", "line_number": 42}
Auto-update IP (no auth required)​
Called by your router or DDNS client to update the record with the caller's IP:
GET /dynamic-dns/update?token=abc123xyz
DNS Zone Editor​
List domains with zone status​
GET /api/dns
Get parsed DNS records​
GET /api/dns/example.com
{
"domain": "example.com",
"serial": "2025011501",
"records": [
{"line_number": 12, "end_line_number": 12, "line": "www 3600 IN A 1.2.3.4", "multiline": false}
]
}
Get raw zone file​
GET /api/dns/example.com/raw
Save raw zone file​
PUT /api/dns/example.com/raw
Content-Type: application/json
{"content": "$ORIGIN example.com.\n$TTL 3600\n..."}
Add a DNS record​
POST /api/dns/example.com/records
Content-Type: application/json
{"name": "www", "ttl": "3600", "type": "A", "record": "1.2.3.4"}
MX example:
{"name": "example.com.", "ttl": "3600", "type": "MX", "priority": "10", "record": "mail.example.com."}
TXT / SPF example:
{"name": "example.com.", "ttl": "3600", "type": "TXT", "record": "v=spf1 include:_spf.example.com ~all"}
Update a record by line number​
PATCH /api/dns/example.com/records/12
Content-Type: application/json
{"content": "www 3600 IN A 5.6.7.8", "serial": "2025011501"}
The serial field prevents concurrent-edit conflicts — pass the serial you read when fetching the zone.
Delete a record​
DELETE /api/dns/example.com/records/12
Multi-line record (e.g. DKIM):
DELETE /api/dns/example.com/records/15
Content-Type: application/json
{"end_row_id": 18}
Reset zone to default template​
POST /api/dns/example.com/reset
Export zone file​
GET /api/dns/example.com/export
Traffic Stats (GoAccess)​
List domains with stats availability​
GET /api/stats
Get GoAccess report for a domain​
GET /api/stats/example.com
{
"domain": "example.com",
"available": true,
"html": "<!DOCTYPE html>..."
}
Stats are generated every 24 hours by the GoAccess daemon.
System Services​
List all services​
GET /api/services
{
"services": [
{"service": "nginx", "container_state": "running", "health_status": "healthy"},
{"service": "mysql", "container_state": "running", "health_status": "healthy"}
]
}
Get service status​
GET /api/services/nginx
{
"service": "nginx",
"container_state": "running",
"health_status": "healthy",
"available_actions": ["disable"]
}
Start or stop a service​
POST /api/services/nginx
Content-Type: application/json
{"action": "enable"} # enable | disable | restart
Webmail​
Get webmail info​
GET /api/webmail
{"is_running": true, "webmail_url": "https://webmail.example.com/"}
Generate auto-login token​
Creates a 30-second single-use token for automatic Roundcube login.
POST /api/webmail/[email protected]
{
"email": "[email protected]",
"token": "abc123...",
"autologin_url": "https://webmail.example.com/autologin.php?token=abc123...",
"webmail_url": "https://webmail.example.com/"
}
Website Builder​
Get HTML and CSS content​
GET /api/website-builder/example.com
{
"domain": "example.com",
"html": "<!DOCTYPE html>...",
"css": "* { box-sizing: border-box; }"
}
Save content​
PUT /api/website-builder/example.com
Content-Type: application/json
{
"html": "<!DOCTYPE html><html>...</html>",
"css": "body { margin: 0; }"
}
Create a new site​
POST /api/website-builder
Content-Type: application/json
{"domain_id": 1, "subdirectory": ""}
{"message": "Website created successfully on example.com", "site_name": "example.com"}
Remove a site (deletes files)​
DELETE /api/website-builder/sites/7
Detach a site (keeps files)​
POST /api/website-builder/sites/7/detach
Error Responses​
All endpoints return standard HTTP status codes:
| Code | Meaning |
|---|---|
200 | OK |
201 | Created |
202 | Accepted (async operation started) |
400 | Bad request / missing required field |
401 | Unauthorized (missing or invalid token) |
403 | Forbidden (feature not enabled or domain not owned) |
404 | Resource not found |
409 | Conflict (e.g. serial mismatch, resource already exists) |
500 | Internal server error |
503 | Service unavailable |
504 | Timeout |
Error responses always include an error field:
{"error": "You do not own this domain"}
- Authentication
- MySQL
- List databases and users
- Create a database
- Get database info
- Drop a database
- List users for a database
- Add user to database
- Remove user from database
- PostgreSQL
- List databases and users
- Create a database
- Drop a database
- List all users
- Create a user
- Drop a user
- Assign user to database
- Revoke user from database
- Domains
- List all domains
- Add a domain
- Remove a domain
- Get SSL status
- Issue / renew SSL
- List mailboxes
- Create mailbox
- Get mailbox details
- Change mailbox password
- Delete mailbox
- List aliases
- Create alias
- Delete alias
- Get catch-all address
- Set catch-all address
- Check deliverability (all domains)
- Check deliverability for a domain
- Get Sieve mail filters
- Update Sieve filters
- FTP
- List FTP accounts
- Create FTP account
- Delete FTP account
- Change FTP password
- Change FTP home path
- List active FTP connections
- Cron Jobs
- List all cron jobs
- Create a cron job
- Edit a cron job
- Delete a cron job
- Get raw crontab
- Save raw crontab
- Tail cron log
- Cache Services
- Redis
- Valkey / Memcached / Elasticsearch / OpenSearch
- Varnish
- Docker / Containers
- List compose services
- List running containers
- Get single container state
- Start / stop / restart
- Update CPU/RAM limits
- Tail container logs
- WAF (Web Application Firewall)
- Status for all domains
- Status for a domain
- Toggle WAF on/off
- Update excluded rules
- Paginated WAF log
- WAF stats
- List rule IDs / tags
- IP Blocker
- List blocked IPs
- Block IPs
- Unblock all IPs
- PHP
- List installed PHP versions
- Get php.ini content
- Save php.ini
- Get PHP option keys and values
- Update specific PHP options
- List extensions with state
- Toggle extension
- List all supported extensions
- Install an extension
- Poll install status
- Account
- Get account info
- Update account
- List active sessions
- Terminate a session
- Resource Usage
- Latest snapshot
- Paginated history
- Disk Usage & Inodes
- Disk usage (root)
- Disk usage for a path
- Inode count (root)
- Inode count for a path
- Malware Scanner
- List quarantined files
- Run a scan
- Webserver Config
- Get config
- Save config
- Process Manager
- List running processes
- Kill a process
- Sites & Websites
- List all websites
- Get website details
- Google Safe Browsing check
- Get PageSpeed data
- Trigger PageSpeed refresh
- Get WP vulnerability data
- Run vulnerability scan
- WordPress
- List all WordPress installations
- List backups
- Create backup
- Restore a backup
- List available hardening rules
- Get active hardening rules
- Apply hardening rules
- Uninstall WordPress
- Detach from WordPress Manager
- Reload WP data from filesystem
- WP-CLI actions
- Node.js / Python Apps (PM2)
- Tail app logs
- Start application
- Stop application
- Restart application (pull + restart)
- Update app settings
- Delete app
- Auto Installer
- List installed apps
- Dynamic DNS
- List all entries
- Create entry
- Update entry
- Delete entry
- Auto-update IP (no auth required)
- DNS Zone Editor
- List domains with zone status
- Get parsed DNS records
- Get raw zone file
- Save raw zone file
- Add a DNS record
- Update a record by line number
- Delete a record
- Reset zone to default template
- Export zone file
- Traffic Stats (GoAccess)
- List domains with stats availability
- Get GoAccess report for a domain
- System Services
- List all services
- Get service status
- Start or stop a service
- Webmail
- Get webmail info
- Generate auto-login token
- Website Builder
- Get HTML and CSS content
- Save content
- Create a new site
- Remove a site (deletes files)
- Detach a site (keeps files)
- Error Responses