Files
novacpx/docs/api-reference.md
myron 1675de36eb docs(#23): install guide, admin guide, reseller guide, user guide, API reference
Five markdown documents covering the full panel:
- docs/README.md: index with links to all guides
- docs/install.md: requirements, one-liner install, file layout, config.ini, auto-deploy, upgrade
- docs/admin-guide.md: all admin panel sections (accounts, DNS, mail, security, Docker, notifications, WHMCS)
- docs/reseller-guide.md: account management, white-label branding, Docker quotas
- docs/user-guide.md: files, email, databases, FTP, DNS, SSL, cron, Docker, settings
- docs/api-reference.md: all 25+ endpoints with request/response shapes, auth, rate limits, role access

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 10:57:03 +00:00

726 lines
13 KiB
Markdown

# NovaCPX — API Reference
## Overview
All API endpoints are served under `/api/<resource>/<action>`.
**Base URL pattern:** `https://<server>:<port>/api/<resource>/<action>`
The same API is available on all three panel ports (8880, 8881, 8882). Which actions succeed depends on the role of the authenticated session.
### Authentication
All endpoints (except `auth/login`) require an active session cookie `ncpx_session`. Obtain it by calling `auth/login`.
```http
POST /api/auth/login
Content-Type: application/json
{"username": "admin", "password": "Nova2026!!"}
```
The response sets the `ncpx_session` cookie. Include it in all subsequent requests (`credentials: 'include'` in fetch, or `-b cookies.txt` in curl).
### Response format
Every response is JSON:
```json
{
"success": true,
"message": "OK",
"data": { ... }
}
```
On error:
```json
{
"success": false,
"message": "Reason",
"errors": []
}
```
Paginated responses include a `meta` block:
```json
{
"success": true,
"data": { "items": [...], "meta": { "total": 100, "page": 1, "per_page": 25, "pages": 4 } }
}
```
### Role access
| Role | Panels | Access |
|------|--------|--------|
| `admin` | 8882 | Everything |
| `reseller` | 8881 | Own accounts + reseller features |
| `user` | 8880 | Own account only |
### Rate limiting
| Scope | Limit |
|-------|-------|
| Login (`auth/login`) | 10 requests / minute |
| All other endpoints | 120 requests / minute |
Exceeded limits return HTTP 429 with `Retry-After` and `X-RateLimit-*` headers.
---
## auth
### `POST /api/auth/login`
Authenticate and create a session.
**Body:** `{username, password}`
**Returns:** `{user: {id, username, role}, portal_url}`
**Access:** Public
### `GET /api/auth/me`
Return the current session's user object.
**Returns:** `{id, username, email, role}`
**Access:** Any authenticated user
### `POST /api/auth/logout`
Destroy the current session.
**Access:** Any authenticated user
### `POST /api/auth/change-password`
Change the current user's own password.
**Body:** `{current_password, new_password, confirm_password}`
**Access:** Any authenticated user
---
## accounts
### `GET /api/accounts/list`
List hosting accounts.
**Query params:** `page`, `per_page`, `search`, `status`
**Returns:** Paginated list with domain_count, email_count, db_count per account
**Access:** Admin (all accounts), Reseller (own accounts)
### `GET /api/accounts/get?id=<id>`
Get a single account with its domains and disk usage.
**Access:** Admin, Reseller (own accounts)
### `POST /api/accounts/create`
Create a hosting account. Creates Linux user, home directory, vhost, DNS zone, and optionally sends a welcome email.
**Body:**
```json
{
"username": "john",
"domain": "example.com",
"email": "john@example.com",
"password": "secret",
"package_id": 1,
"php_version": "8.3"
}
```
**Access:** Admin, Reseller
### `POST /api/accounts/suspend`
Suspend an account (disables vhost, notifies user).
**Body:** `{id, reason?}`
**Access:** Admin, Reseller (own accounts)
### `POST /api/accounts/unsuspend`
Re-enable a suspended account.
**Body:** `{id}`
**Access:** Admin, Reseller (own accounts)
### `POST /api/accounts/terminate`
Permanently delete an account and all its data.
**Body:** `{id}`
**Access:** Admin only
### `POST /api/accounts/change-password`
Reset an account's panel and system password.
**Body:** `{account_id, password}`
**Access:** Admin only
### `GET /api/accounts/usage?id=<id>`
Return disk, email, database, domain, and FTP usage vs. package limits.
**Access:** Admin, Reseller (own accounts)
---
## domains
### `GET /api/domains/list?account_id=<id>`
List domains for an account.
**Access:** Admin, Reseller (own accounts), User (own account)
### `POST /api/domains/add`
Add a domain, subdomain, or redirect to an account.
**Body:**
```json
{
"account_id": 1,
"domain": "example.com",
"type": "addon",
"document_root": "/home/user/public_html/example",
"php_version": "8.3"
}
```
`type` values: `addon`, `subdomain`, `redirect`
For redirects, include `redirect_to` (URL) and `redirect_code` (301 or 302).
**Access:** Admin, Reseller, User
### `POST /api/domains/remove`
Remove a domain (cannot remove the primary domain).
**Body:** `{account_id, domain_id}`
**Access:** Admin, Reseller, User
---
## email
### `GET /api/email/list?account_id=<id>`
List email accounts for an account.
**Access:** Admin, Reseller, User
### `POST /api/email/create`
Create a mailbox.
**Body:** `{account_id, email, password, quota_mb?}`
**Access:** Admin, Reseller, User (subject to `max_email` package limit)
### `DELETE /api/email/delete`
Delete a mailbox.
**Body:** `{id}`
**Access:** Admin, Reseller, User
### `POST /api/email/suspend`
Suspend a mailbox.
**Body:** `{id}`
**Access:** Admin, Reseller, User
### `GET /api/webmail/login-url?account_id=<id>&email=<email>`
Generate a single-sign-on webmail URL (valid 5 minutes).
**Access:** Admin, Reseller, User
---
## dns
### `GET /api/dns/list?account_id=<id>`
List DNS zones for an account.
**Access:** Admin, Reseller, User
### `GET /api/dns/records?zone_id=<id>`
List records in a zone.
### `POST /api/dns/add-record`
Add a DNS record.
**Body:**
```json
{
"zone_id": 1,
"type": "A",
"name": "www",
"value": "1.2.3.4",
"ttl": 3600
}
```
**Access:** Admin, Reseller, User
### `POST /api/dns/update-record`
Update an existing record.
**Body:** `{record_id, name, value, ttl}`
### `POST /api/dns/delete-record`
Delete a record.
**Body:** `{record_id}`
### `POST /api/dkim/generate`
Generate DKIM key pair for a domain.
**Body:** `{account_id, domain}`
---
## databases
### `GET /api/databases/list?account_id=<id>`
List MySQL databases for an account.
**Access:** Admin, Reseller, User
### `POST /api/databases/create`
Create a database and MySQL user.
**Body:** `{account_id, db_name, db_user, db_pass}`
**Subject to `max_databases` package limit.**
### `DELETE /api/databases/delete`
Drop a database.
**Body:** `{id}`
---
## ftp
### `GET /api/ftp/list?account_id=<id>`
List FTP accounts.
### `POST /api/ftp/create`
Create an FTP account.
**Body:** `{account_id, username, password, home_dir}`
**Subject to `max_ftp` package limit.**
### `DELETE /api/ftp/delete`
Delete an FTP account.
**Body:** `{id}`
---
## ssl
### `GET /api/ssl/list?account_id=<id>`
List SSL certificates for an account.
### `POST /api/ssl/issue`
Issue a Let's Encrypt certificate. The domain must resolve publicly.
**Body:** `{account_id, domain}`
### `POST /api/ssl/delete`
Remove an SSL certificate record.
**Body:** `{id}`
---
## files
The file manager API mirrors the user-facing file manager. All paths are validated against the account's home directory; paths outside it are rejected.
### `GET /api/files/list?account_id=<id>&path=<path>`
List directory contents.
### `GET /api/files/read?account_id=<id>&path=<path>`
Read a text file (max 1 MB).
### `POST /api/files/write`
Write/create a file.
**Body:** `{account_id, path, content}`
### `POST /api/files/mkdir`
Create a directory.
**Body:** `{account_id, path}`
### `DELETE /api/files/delete`
Delete a file or directory.
**Body:** `{account_id, path}`
### `POST /api/files/rename`
Rename or move a file.
**Body:** `{account_id, from, to}`
### `POST /api/files/chmod`
Change file permissions (clamped to 0777 max).
**Body:** `{account_id, path, mode}` (e.g. `"mode": "0755"`)
### `POST /api/files/upload`
Upload a file. Multipart form data: `account_id`, `path`, `file`.
---
## cron
### `GET /api/cron/list?account_id=<id>`
List cron jobs for an account.
### `POST /api/cron/save`
Create or update a cron job.
**Body:** `{account_id, id?, schedule, command, enabled}`
### `DELETE /api/cron/delete`
Delete a cron job.
**Body:** `{id}`
---
## packages
### `GET /api/packages/list`
List all hosting packages.
**Access:** Admin, Reseller
### `POST /api/packages/create`
Create a package.
**Body:**
```json
{
"name": "Starter",
"disk_mb": 5120,
"max_email": 10,
"max_databases": 5,
"max_ftp": 5,
"max_domains": 10,
"max_subdomains": 20
}
```
### `POST /api/packages/update`
Update a package.
**Body:** `{id, ...same fields as create}`
### `DELETE /api/packages/delete`
Delete a package (accounts using it are unaffected).
**Body:** `{id}`
---
## stats
### `GET /api/stats/account?account_id=<id>`
Return usage stats for an account. For user role, `account_id` is inferred automatically.
### `GET /api/stats/server`
Return historical server stats (CPU, RAM, disk) from the last 24 hours. Populated by the `collect-stats.php` cron every 5 minutes.
**Access:** Admin only
---
## sessions
### `GET /api/sessions/list`
List all active sessions (admin sees all, users see their own).
### `DELETE /api/sessions/revoke`
Revoke a specific session.
**Body:** `{session_id}`
**Access:** Admin
### `DELETE /api/sessions/revoke-user`
Revoke all sessions for a specific user.
**Body:** `{user_id}`
**Access:** Admin
### `DELETE /api/sessions/revoke-all`
Revoke all active sessions on the panel.
**Access:** Admin
---
## system
All system actions require Admin unless noted.
### `GET /api/system/version`
Return panel version, git commit, PHP version, OS. No auth required.
### `GET /api/system/stats`
Return live CPU, RAM, disk, uptime, and service status.
### `GET /api/system/check-update`
Check GitHub for newer NovaCPX commits.
### `POST /api/system/apply-update`
Pull the latest code and trigger a deploy.
### `GET /api/system/check-os-update`
List available apt package upgrades.
### `POST /api/system/apply-os-update`
Run `apt-get upgrade` and restart any services that went down.
### `GET /api/system/audit-log`
Query the audit log.
**Query params:** `page`, `per_page`, `user`, `action`, `date_from`, `date_to`
### `GET /api/system/server-options`
Return current web/mail/FTP/DNS server selections and detection state.
### `POST /api/system/save-option`
Save a server option.
**Body:** `{key, value}` — allowed keys: `web_server`, `mail_server`, `ftp_server`, `dns_server`, `whmcs_api_key`, `whmcs_enabled`, `ns1_hostname`, `ns2_hostname`
### `GET /api/system/notify-settings`
Return notification settings (API key masked).
### `POST /api/system/save-notify-settings`
Save notification settings.
**Body:** `{cybermail_api_key?, notify_from_email?, notify_from_name?, notify_admin_email?, notifications_enabled?}`
### `POST /api/system/test-notify`
Send a test email.
**Body:** `{to}`
### `POST /api/system/service-action`
Start, stop, or restart a system service.
**Body:** `{service, action}` — action: `start`, `stop`, `restart`
---
## branding
### `GET /api/branding/get`
Return the branding settings for the current reseller.
**Access:** Reseller (own branding), Admin (pass `reseller_id` param)
### `POST /api/branding/save`
Save branding settings.
**Body:** `{panel_name?, primary_color?, accent_color?, support_email?, support_url?, hide_powered_by?, custom_css?}`
### `POST /api/branding/upload-logo`
Upload a logo image. Multipart: `logo` file field.
Accepts PNG, JPG, SVG, WEBP (max 512 KB).
### `POST /api/branding/delete-logo`
Remove the current logo and revert to the default SVG.
---
## whmcs
WHMCS billing bridge. Authenticate with `X-WHMCS-Key: <key>` header (configured in Server Options).
### `POST /api/whmcs/create`
Provision a new hosting account.
**Body:** `{domain, username, password, email, package_id?}`
### `POST /api/whmcs/suspend`
Suspend an account by domain.
**Body:** `{domain, reason?}`
### `POST /api/whmcs/unsuspend`
Unsuspend an account by domain.
**Body:** `{domain}`
### `POST /api/whmcs/terminate`
Terminate an account by domain.
**Body:** `{domain}`
### `POST /api/whmcs/changepackage`
Switch an account to a different package.
**Body:** `{domain, package_id}`
### `GET /api/whmcs/info?domain=<domain>`
Return account details for a domain.
---
## docker
### `GET /api/docker/status`
Engine status and container/image counts.
### `GET /api/docker/containers?account_id=<id>`
List containers for an account (or all containers for admin with no account_id).
### `POST /api/docker/container-action`
**Body:** `{container_id, action}` — action: `start`, `stop`, `restart`, `remove`
### `GET /api/docker/logs?container_id=<id>`
Return the last 100 log lines from a container.
### `GET /api/docker/images`
List pulled images.
### `POST /api/docker/pull`
Pull an image.
**Body:** `{image}` e.g. `"image": "nginx:latest"`
### `POST /api/docker/run`
Run a new container.
**Body:** `{account_id, name, image, ports?, env?, volumes?}`
Container names are namespaced as `novacpx-<username>-<name>`.
### `GET /api/docker/catalog`
Return the one-click app catalog (9 apps: WordPress, Ghost, Nextcloud, Gitea, Matomo, Vaultwarden, Node.js, Flask, static).
### `POST /api/docker/launch-app`
Deploy an app from the catalog.
**Body:** `{account_id, app_id, ...app-specific config}`
---
## firewall
### `GET /api/firewall/rules`
List UFW rules.
**Access:** Admin
### `POST /api/firewall/add-rule`
Add a UFW rule.
**Body:** `{port, protocol, action, from_ip?}`
### `POST /api/firewall/delete-rule`
Remove a rule by number.
**Body:** `{rule_number}`
### `GET /api/firewall/fail2ban`
Return Fail2Ban jail status and banned IPs.
### `POST /api/firewall/unban`
Unban an IP from a jail.
**Body:** `{jail, ip}`