Chuyển tới nội dung chính
Version: 4.1

API HiTechCloud

HiTechCloud cung cấp một REST API đầy đủ, phản chiếu mọi chức năng của giao diện web. Mọi tính năng có trong panel đều có thể truy cập bằng chương trình.

Cũng có sẵn một đặc tả OpenAPI 3.0 đọc được bằng máy, bao quát mọi endpoint bên dưới — hãy nhập vào Postman/Insomnia, sinh SDK máy khách, hoặc nạp vào Swagger UI/Redoc.

Xác thực​

Mọi yêu cầu, trừ endpoint đăng nhập, đều mang một Bearer token.

API là một tính năng Enterprise. Cả cờ tính năng chung api và cờ tính năng riêng của endpoint bạn gọi đều phải được gói hosting của tài khoản cấp.

POST /api/login​

Tuyến duy nhất nhận mật khẩu. Gửi JSON:

TrườngBắt buộcÝ nghĩa
usernamecóTên người dùng panel.
passwordcóMật khẩu của người dùng đó.
twofa_codechỉ khi tài khoản bật 2FAMột mã TOTP hiện hành.
curl -s -X POST https://panel.example.com/api/login \
-H "Content-Type: application/json" \
-d '{"username": "stefan", "password": "yourpassword"}'

Khi thành công — 200:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user_id": 1,
"expires_in": 3600
}

Token là một JWT HS256 có chủ thể là id người dùng dạng số, có hiệu lực một giờ (expires_in tính bằng giây). Không có refresh token; hãy đăng nhập lại.

Đăng nhập thành công là một lần đăng nhập thật: nó được ghi vào lịch sử đăng nhập và nhật ký hoạt động của tài khoản dưới dạng logged in via user API, và kích hoạt thông báo đăng nhập của tài khoản nếu tuỳ chọn đó đang bật.

Nếu tài khoản có xác thực hai yếu tố và không gửi twofa_code — 401:

{"twofa_required": true, "user_id": 1}

Hãy thử lại với twofa_code trong phần thân. Mã không hợp lệ trả về 401 kèm {"error": "invalid_2fa"}.

Thất bại. Thiếu username hoặc password trả về 400. Mọi trường hợp khác trả về 401 kèm một mã error ổn định, đọc được bằng máy:

MãÝ nghĩa
invalid_passwordMật khẩu sai.
unknown_userKhông có tài khoản như vậy.
suspendedTài khoản đang bị tạm ngưng.
db_errorPanel không kết nối được tới cơ sở dữ liệu của nó.
login_failedBất kỳ lỗi nào khác.

token_generation_failed và internal_error trả về 500.

Giới hạn tần suất. Các lần đăng nhập được đếm theo IP máy khách trong một cửa sổ cố định một phút. Giới hạn là cài đặt login_ratelimit của panel, mặc định 5 lần mỗi phút. Vượt quá, yêu cầu không bao giờ tới bước kiểm tra mật khẩu và câu trả lời là 429:

{"error":"rate_limit_exceeded","message":"Too many requests. Please try again later."}

Mỗi lần bị chặn tần suất được ghi vào /var/log/hitechcloud/user/failed_login.log và tính vào IP đó. Khi bộ đếm vượt login_blocklimit (mặc định 20), IP bị cấm tạm thời một giờ trong ConfigServer Firewall, nếu đã cài CSF. Đăng nhập thành công sẽ xoá bộ đếm của IP. Các bộ đếm nằm trong tiến trình panel, nên khởi động lại panel sẽ xoá chúng.

POST /api/auth/ticket và POST /api/auth/ticket/redeem​

Vé đăng nhập dùng một lần cho phép một ứng dụng đã đăng nhập mở một ứng dụng HiTechCloud khác mà đã ở trạng thái đăng nhập. Lệnh gọi đầu nhận Bearer token của bạn và trả về một vé sống 30 giây (tối đa 60) và chỉ dùng được một lần; lệnh gọi thứ hai nhận vé mà không cần token, và trả lời giống POST /api/login. Toàn bộ hợp đồng nằm ở Vé đăng nhập ứng dụng.

Dùng token​

curl https://panel.example.com/api/account \
-H "Authorization: Bearer eyJhbGciOi..."

MySQL​

Mọi endpoint MySQL đều phẳng — không có kiểu lồng /api/mysql/<db_name>/users. Cơ sở dữ liệu nằm dưới /api/mysql/databases, người dùng dưới /api/mysql/users, và hai thứ được gắn với nhau bằng một tài nguyên riêng /api/mysql/grants.

Liệt kê cơ sở dữ liệu​

GET /api/mysql/databases
Authorization: Bearer <token>
{
"databases": [
{"name": "mydb", "assigned_users": "myuser"}
],
"total": 1
}

Tạo cơ sở dữ liệu​

POST /api/mysql/databases
Content-Type: application/json

{"name": "newdb"}

Xoá cơ sở dữ liệu​

DELETE /api/mysql/databases/newdb

Liệt kê các bảng trong một cơ sở dữ liệu​

GET /api/mysql/databases/mydb/tables
{
"database": "mydb",
"tables": [
{"table": "wp_posts", "rows": 120, "data_length": 98304, "index_length": 32768, "data_free": 0}
]
}

Tối ưu / sửa chữa một cơ sở dữ liệu​

Chạy OPTIMIZE TABLE hoặc REPAIR TABLE trên mọi bảng trong cơ sở dữ liệu.

POST /api/mysql/databases/mydb/optimize
POST /api/mysql/databases/mydb/repair
{
"database": "mydb",
"action": "optimize",
"results": [
{"table": "wp_posts", "status": "ok", "details": [{"op": "optimize", "msg_type": "status", "msg_text": "OK"}]}
]
}

Xuất một cơ sở dữ liệu​

Truyền trực tiếp (stream) một tệp .sql hoặc .sql.gz để tải xuống.

GET /api/mysql/databases/mydb/export?format=sql

Nhập một cơ sở dữ liệu​

Tải lên dạng multipart — tên trường phải là file. Chấp nhận .sql hoặc .sql.gz.

POST /api/mysql/databases/mydb/import
Content-Type: multipart/form-data

file=@dump.sql

Lấy dung lượng đĩa của từng cơ sở dữ liệu​

Phản chiếu chế độ xem kích thước cơ sở dữ liệu của giao diện web — khác với /api/mysql/info, không có dữ liệu kích thước, và /api/mysql/databases/<db>/tables, tính theo từng bảng của một cơ sở dữ liệu.

GET /api/mysql/size?unit=mb&show_all=false
{"sizes": [{"database": "mydb", "size": 12.4}], "total": 1, "unit": "MB"}

Đặt mật khẩu root của MySQL​

Chỉ ghi — không thể lấy lại mật khẩu hiện tại. Cập nhật cả hai host % và localhost và khởi động lại dịch vụ.

PUT /api/mysql/root-password
Content-Type: application/json

{"password": "newRootPass123"}

Liệt kê người dùng cơ sở dữ liệu​

GET /api/mysql/users
{"users": ["myuser", "shopuser"], "total": 2}

Tạo người dùng cơ sở dữ liệu​

POST /api/mysql/users
Content-Type: application/json

{"username": "dbuser", "password": "securepass", "host": "%"}

host mặc định là % nếu bỏ qua.

Xoá người dùng cơ sở dữ liệu​

DELETE /api/mysql/users/dbuser?host=%

Đổi mật khẩu của người dùng cơ sở dữ liệu​

PATCH /api/mysql/users/dbuser/password
Content-Type: application/json

{"password": "newpass", "host": "%"}

Lấy quyền của một người dùng trên một cơ sở dữ liệu​

GET /api/mysql/users/dbuser/privileges/mydb?host=%
{"username": "dbuser", "host": "%", "database": "mydb", "privileges": ["ALL PRIVILEGES"]}

Cấp quyền​

POST /api/mysql/grants
Content-Type: application/json

{"username": "dbuser", "database": "mydb", "privileges": ["ALL PRIVILEGES"], "host": "%"}

Thu hồi quyền​

DELETE /api/mysql/grants
Content-Type: application/json

{"username": "dbuser", "database": "mydb", "host": "%"}

Lấy bản tóm tắt cơ sở dữ liệu/người dùng/phân quyền​

GET /api/mysql/info
{
"databases": ["mydb", "shop"],
"users": ["dbuser", "shopuser"],
"assigned_databases": [{"database": "mydb", "users": "dbuser"}]
}

Hiện danh sách tiến trình đầy đủ​

GET /api/mysql/processlist
{
"processlist": [
{"id": 42, "user": "dbuser", "host": "localhost", "db": "mydb", "command": "Query", "time": 0, "state": "", "info": "SELECT 1"}
],
"total": 1
}

Trạng thái truy cập từ xa​

GET /api/mysql/remote-access
{
"enabled": false,
"server_ip": "203.0.113.10",
"port": "3306",
"user_access": [{"username": "dbuser", "hosts": ["%"]}]
}

Bật / tắt truy cập từ xa​

POST /api/mysql/remote-access
Content-Type: application/json

{"action": "enable"}

Cấp một mục truy cập từ xa​

Tạo một user@host mới (sao chép các quyền từ một host sẵn có của người dùng đó, nếu có).

POST /api/mysql/remote-access/entries
Content-Type: application/json

{"username": "dbuser", "host": "1.2.3.4", "password": "securepass"}

Đổi host của một mục truy cập từ xa​

PATCH /api/mysql/remote-access/entries
Content-Type: application/json

{"username": "dbuser", "old_host": "1.2.3.4", "new_host": "5.6.7.8"}

Gỡ một mục truy cập từ xa​

DELETE /api/mysql/remote-access/entries
Content-Type: application/json

{"username": "dbuser", "host": "1.2.3.4"}

Lấy cấu hình máy chủ​

GET /api/mysql/configuration
{
"configuration": {"max_connections": "150"},
"available_keys": ["max_connections", "max_allowed_packet", "innodb_buffer_pool_size", "..."]
}

Cập nhật cấu hình máy chủ​

Chỉ các khoá có trong available_keys được chấp nhận. Khởi động lại MySQL/MariaDB.

PUT /api/mysql/configuration
Content-Type: application/json

{"max_connections": "200"}
{"updated": true, "restarted": true, "configuration": {"max_connections": "200"}}

PostgreSQL​

Cấu trúc phẳng giống MySQL: cơ sở dữ liệu, người dùng và phân quyền là các tài nguyên cấp cao nhất riêng biệt.

Liệt kê cơ sở dữ liệu​

GET /api/postgresql/databases
{
"databases": [{"name": "pgdb", "assigned_users": "pguser"}],
"total": 1
}

Tạo cơ sở dữ liệu​

POST /api/postgresql/databases
Content-Type: application/json

{"name": "pgdb"}

Xoá cơ sở dữ liệu​

DELETE /api/postgresql/databases/pgdb

Xuất một cơ sở dữ liệu​

Truyền trực tiếp một bản dump .sql.

GET /api/postgresql/databases/pgdb/export

Nhập một cơ sở dữ liệu​

Tải lên dạng multipart — tên trường phải là file.

POST /api/postgresql/databases/pgdb/import
Content-Type: multipart/form-data

file=@dump.sql
{"database": "pgdb", "file": "dump.sql", "imported": true}

Liệt kê người dùng​

GET /api/postgresql/users
{"users": ["pguser"], "total": 1}

Tạo người dùng​

POST /api/postgresql/users
Content-Type: application/json

{"username": "pguser", "password": "securepass"}

Xoá người dùng​

Thu hồi quyền truy cập khỏi mọi cơ sở dữ liệu trước khi xoá vai trò.

DELETE /api/postgresql/users/pguser

Đổi mật khẩu của người dùng​

PATCH /api/postgresql/users/pguser/password
Content-Type: application/json

{"password": "newpass"}

Cấp mọi quyền trên một cơ sở dữ liệu​

POST /api/postgresql/grants
Content-Type: application/json

{"username": "pguser", "database": "pgdb"}

Thu hồi quyền​

DELETE /api/postgresql/grants
Content-Type: application/json

{"username": "pguser", "database": "pgdb"}

Lấy bản tóm tắt cơ sở dữ liệu/người dùng/phân quyền​

GET /api/postgresql/info

Hiện các kết nối đang hoạt động​

GET /api/postgresql/processlist
{
"processlist": [
{"pid": 123, "user": "pguser", "application": "psql", "client_addr": "127.0.0.1",
"state": "active", "wait_event_type": "", "wait_event": "", "query": "SELECT 1",
"backend_type": "client backend", "duration": "0:00:00.001"}
],
"total": 1
}

Trạng thái truy cập từ xa​

GET /api/postgresql/remote-access
{"enabled": false, "server_ip": "203.0.113.10", "port": "5432", "postgres_port": 5432}

Bật / tắt truy cập từ xa​

POST /api/postgresql/remote-access
Content-Type: application/json

{"action": "enable"}

Lấy / cập nhật cấu hình máy chủ​

Cùng dạng với cấu hình MySQL — khởi động lại PostgreSQL khi lưu.

GET /api/postgresql/configuration
PUT /api/postgresql/configuration
Content-Type: application/json

{"max_connections": "200"}

Tên miền​

Liệt kê mọi tên miền​

GET /api/domains
{
"domains": [
{
"domain": "example.com", "docroot": "/var/www/html", "php_version": "8.2",
"site_count": 1, "redirect_url": null, "ssl": true, "status": "active",
"suspend_comment": null, "has_dns_zone": true
}
],
"total": 1
}

Thêm một tên miền​

docroot mặc định là /var/www/html/. Tên miền .onion còn yêu cầu hs_ed25519_public_key và hs_ed25519_secret_key.

POST /api/domains
Content-Type: application/json

{"domain": "newdomain.com"}

Gỡ một tên miền​

DELETE /api/domains/olddomain.com

Lấy trạng thái tên miền​

Trạng thái SSL / tạm ngưng / chuyển hướng trong một lệnh gọi.

GET /api/domains/example.com/status
{"domain": "example.com", "ssl": true, "status": "active", "suspend_comment": null, "redirect_url": null}

Tạm ngưng / bỏ tạm ngưng một tên miền​

POST /api/domains/example.com/suspend
POST /api/domains/example.com/unsuspend

Lấy / đổi thư mục gốc tài liệu​

docroot phải nằm trong /var/www/html/.

GET /api/domains/example.com/docroot

PUT /api/domains/example.com/docroot
Content-Type: application/json

{"docroot": "/var/www/html/example.com/public"}

Lấy / đặt / gỡ một chuyển hướng​

GET /api/domains/example.com/redirect

PUT /api/domains/example.com/redirect
Content-Type: application/json

{"redirect_url": "https://newsite.com"}

DELETE /api/domains/example.com/redirect

Lấy trạng thái SSL​

GET /api/domains/example.com/ssl
{"domain": "example.com", "ssl_mode": "auto", "keys": ""}

Cấp / gia hạn SSL​

action là bắt buộc — một trong autossl, generate, switch_and_generate hoặc custom (loại này còn yêu cầu public_path và private_path, cả hai nằm trong /var/www/html/).

POST /api/domains/example.com/ssl
Content-Type: application/json

{"action": "autossl"}

Chứng chỉ tuỳ chỉnh:

POST /api/domains/example.com/ssl
Content-Type: application/json

{
"action": "custom",
"public_path": "/var/www/html/certs/example.com.crt",
"private_path": "/var/www/html/certs/example.com.key"
}

Lấy / lưu cấu hình VHost​

GET /api/domains/example.com/vhost

PUT /api/domains/example.com/vhost
Content-Type: application/json

{"vhost": "...vhost content..."}

Lấy / đặt ghi đè kiểu chữ hiển thị​

Chỉ mang tính hiển thị — ví dụ hiện "MyBrand.com" thay vì "mybrand.com" trên giao diện.

GET /api/domains/example.com/capitalize
{"domain": "example.com", "capitalized_domain": "example.com"}
PUT /api/domains/example.com/capitalize
Content-Type: application/json

{"capitalized_domain": "Example.com"}

Lấy giá trị băm của bản ghi TLSA​

Dành cho các bản ghi DNS DANE/TLSA, được tính từ chứng chỉ SSL đang dùng của tên miền (Let's Encrypt hoặc tuỳ chỉnh).

GET /api/domains/example.com/tlsa-hash
{"hash_311": "a30dc1ad...", "hash_301": "05754994...", "cert_path": "/etc/hitechcloud/caddy/ssl/.../example.com.crt", "type": "letsencrypt"}

Vùng DNS (lồng dưới tên miền)​

Phần này phản chiếu Trình sửa vùng DNS độc lập bên dưới nhưng nằm dưới /api/domains/<domain>/.... Lưu ý khác biệt về tên trường: ở đây việc tạo bản ghi dùng value, còn các endpoint /api/dns độc lập dùng record.

GET /api/domains/example.com/dns
{
"domain": "example.com",
"serial": "2025011501",
"records": [
{"line_number": 12, "end_line_number": 12, "record": "www 3600 IN A 1.2.3.4"}
]
}

Lưu cả tệp vùng cùng một lúc:

PUT /api/domains/example.com/dns
Content-Type: application/json

{"zone_content": "$ORIGIN example.com.\n..."}

Thêm một bản ghi:

POST /api/domains/example.com/dns/records
Content-Type: application/json

{"name": "www", "ttl": "3600", "type": "A", "value": "1.2.3.4"}

Cập nhật / xoá một bản ghi theo số dòng (end_row_id bao quát các bản ghi nhiều dòng như DKIM):

PUT /api/domains/example.com/dns/records/12
Content-Type: application/json

{"content": "www 3600 IN A 5.6.7.8", "end_row_id": 12, "serial": "2025011501"}

DELETE /api/domains/example.com/dns/records/12
Content-Type: application/json

{"end_row_id": 12}

Đặt lại vùng về mẫu mặc định, hoặc xuất ra thành tệp:

POST /api/domains/example.com/dns/restart
GET /api/domains/example.com/dns/export

Nhật ký truy cập​

GET /api/domains/example.com/logs?page=1&show_all=false
{
"domain": "example.com",
"logs": [{"ts": "2025-01-15T12:00:00Z", "status": 200, "path": "/"}],
"total": 1,
"page": 1,
"total_pages": 1,
"items_per_page": 1000
}

Email​

Liệt kê hộp thư​

GET /api/emails
{
"emails": [
{"address": "info@example.com", "quota_limit": "1024", "quota_used": "12"}
]
}

Tạo hộp thư​

domain, username và password đều bắt buộc. gb + format tuỳ chọn đặt hạn mức riêng.

POST /api/emails
Content-Type: application/json

{"domain": "example.com", "username": "info", "password": "mailpass123"}

Lấy chi tiết hộp thư​

GET /api/emails/info@example.com
{
"address": "info@example.com",
"quota_limit": "1024",
"quota_used": "12",
"incoming": "ACCEPT",
"outgoing": "ACCEPT",
"server_ip": "203.0.113.10",
"mail_host": "mail.example.com"
}

Cập nhật hộp thư​

Cần ít nhất một trong: gb+format, incoming (suspend/allow), outgoing (suspend/allow) hoặc password.

PATCH /api/emails/info@example.com
Content-Type: application/json

{"password": "newpass456"}

Xoá hộp thư​

DELETE /api/emails/info@example.com

Mở một hộp thư trong ứng dụng Mail​

POST /api/emails/mail-ticket/user@example.com

Cấp một vé đăng nhập dùng một lần (30 giây, chỉ dùng một lần) cho một trong các hộp thư của bạn, dành cho hành động "Open in Mail" của các ứng dụng panel. Không có phần thân.

{
"ticket": "v1.dXNlckBleGFtcGxlLmNvbQ.1760000030000.nonce.hexsig",
"expires_at": 1760000030,
"expires_in": 30,
"server": "mail.example.com",
"url": "hitechcloud-mail://open?server=mail.example.com&ticket=v1....&user=user%40example.com"
}

Toàn bộ hợp đồng nằm ở Mở một hộp thư trong ứng dụng Mail.

Tải cấu hình ứng dụng thư​

config_type là một trong thunderbird, outlook, apple.

GET /api/emails/configuration/thunderbird/info@example.com?ssl=true

Liệt kê bí danh​

GET /api/emails/aliases
{
"aliases": [
{"source": "alias@example.com", "targets": ["real@example.com"]}
]
}

Tạo bí danh​

POST /api/emails/aliases
Content-Type: application/json

{"username": "alias", "domain": "example.com", "target": "real@example.com"}

Lấy các đích của một bí danh​

GET /api/emails/aliases/alias@example.com
{"source": "alias@example.com", "targets": ["real@example.com"]}

Thêm một đích vào bí danh sẵn có​

POST /api/emails/aliases/alias@example.com
Content-Type: application/json

{"target": "second@example.com"}

Xoá một đích của bí danh (hoặc cả bí danh)​

DELETE /api/emails/aliases/alias@example.com
Content-Type: application/json

{"target": "real@example.com"}

Xoá mọi đích của bí danh:

DELETE /api/emails/aliases/alias@example.com
Content-Type: application/json

{"delete_all": true}

Lấy địa chỉ catch-all​

GET /api/emails/default/example.com
{"domain": "example.com", "destination": null}

Đặt / gỡ địa chỉ catch-all​

Bỏ qua hoặc để trống destination để gỡ nó.

PUT /api/emails/default/example.com
Content-Type: application/json

{"destination": "catchall@example.com"}

Kiểm tra khả năng gửi thư (mọi tên miền)​

GET /api/emails/deliverability

Kiểm tra khả năng gửi thư của một tên miền​

So sánh DNS thực tế với những gì máy chủ thư mong đợi cho DKIM, SPF và DMARC.

GET /api/emails/deliverability/example.com
{
"domain": "example.com",
"server_ip": "203.0.113.10",
"ok": true,
"dkim": {"status": "ok", "current": "v=DKIM1; ...", "expected": "v=DKIM1; ..."},
"spf": {"status": "ok", "current": "v=spf1 ip4:203.0.113.10 ~all", "expected": "v=spf1 ip4:203.0.113.10 ~all"},
"dmarc": {"status": "ok", "current": "v=DMARC1; p=none", "expected": "v=DMARC1; p=none"}
}

Lấy bộ lọc thư Sieve​

GET /api/emails/filters/user@example.com
{
"email": "user@example.com",
"raw": "require [\"fileinto\"];\nif header :contains \"Subject\" \"SPAM\" { fileinto \"Junk\"; }",
"parsed": [{"condition": "header :contains \"Subject\" \"SPAM\"", "action": "fileinto \"Junk\""}]
}

Cập nhật bộ lọc Sieve​

PUT /api/emails/filters/user@example.com
Content-Type: application/json

{"content": "require [\"fileinto\"];\nif header :contains \"Subject\" \"SPAM\" { fileinto \"Junk\"; }"}

Xuất hộp thư​

Trả về một tệp CSV để tải xuống (email,password,quota — mật khẩu luôn để trống, vì nó không bao giờ được lưu ở dạng có thể đảo ngược).

GET /api/emails/export

Nhập hộp thư​

Hai bước: lệnh gọi đầu kiểm tra tệp CSV tải lên và trả về một import_token; lệnh gọi thứ hai xác nhận và tạo các hộp thư.

POST /api/emails/import
Content-Type: multipart/form-data

file=@mailboxes.csv
{"import_token": "...", "valid_users": [{"email": "info@example.com", "..."}], "invalid_users": []}
POST /api/emails/import/confirm
Content-Type: application/json

{"import_token": "..."}
{"message": "...", "created": 3, "results": [{"email": "info@example.com", "status": "created"}]}

FTP​

Liệt kê tài khoản FTP​

GET /api/ftp
{
"accounts": [{"username": "ftpuser@example.com", "path": "/var/www/html", "uid": "1000", "gid": "1000"}],
"server_ip": "203.0.113.10",
"ftp_host": "203.0.113.10"
}

Tạo tài khoản FTP​

domain là bắt buộc — tài khoản được tạo dưới dạng username@domain, và path phải bắt đầu bằng /var/www/html/.

POST /api/ftp
Content-Type: application/json

{"username": "ftpuser", "password": "ftppass", "domain": "example.com", "path": "/var/www/html/"}

Xoá tài khoản FTP​

DELETE /api/ftp/ftpuser@example.com

Đổi mật khẩu FTP​

PATCH /api/ftp/ftpuser@example.com/password
Content-Type: application/json

{"password": "newftppass"}

Đổi thư mục chính của FTP​

PATCH /api/ftp/ftpuser@example.com/path
Content-Type: application/json

{"path": "/var/www/html/subdir"}

Liệt kê các kết nối FTP đang hoạt động​

GET /api/ftp/connections

Tải cấu hình ứng dụng FTP​

config_type là một trong cyberduck, filezilla.

GET /api/ftp/configuration/filezilla/ftpuser@example.com

Cron Job​

Liệt kê mọi cron job​

GET /api/crons
{
"jobs": [
{"comment": "my job", "schedule": "0 * * * *", "container": "php-fpm-8.1", "command": "/usr/bin/php /var/www/html/cron.php"}
],
"containers": ["php-fpm-8.1", "nginx"],
"schedule_issues": []
}

Tạo một cron job​

schedule, command và container là bắt buộc. comment mặc định là tên container.

POST /api/crons
Content-Type: application/json

{"schedule": "*/5 * * * *", "command": "/usr/bin/php /var/www/html/run.php", "container": "php-fpm-8.1", "comment": "my job"}

Sửa một cron job​

Job được xác định bằng cách so khớp chính xác original_schedule, original_command, original_container và original_comment với mục hiện có.

PATCH /api/crons
Content-Type: application/json

{
"original_schedule": "*/5 * * * *",
"original_command": "/usr/bin/php /var/www/html/run.php",
"original_container": "php-fpm-8.1",
"original_comment": "my job",
"schedule": "0 */2 * * *",
"command": "/usr/bin/php /var/www/html/run.php",
"container": "php-fpm-8.1",
"comment": "my job"
}

Xoá một cron job​

schedule, command, container và comment đều phải khớp chính xác với job hiện có.

DELETE /api/crons
Content-Type: application/json

{"schedule": "*/5 * * * *", "command": "/usr/bin/php /var/www/html/run.php", "container": "php-fpm-8.1", "comment": "my job"}

Lấy / lưu crontab thô​

GET /api/crons/raw

PUT /api/crons/raw
Content-Type: application/json

{"content": "0 * * * * /usr/bin/php /var/www/html/cron.php\n"}

Theo dõi nhật ký cron​

GET /api/crons/log?lines=50&job=cron.php

Dịch vụ bộ nhớ đệm​

Redis, Valkey, Memcached, Elasticsearch và OpenSearch đều theo cùng một mẫu hai endpoint: một GET trạng thái và một POST hành động nhận {"action": "enable" | "disable" | "restart"}.

Redis / Valkey / Memcached / Elasticsearch / OpenSearch​

GET /api/cache/redis
POST /api/cache/redis
Content-Type: application/json

{"action": "enable"}
{
"service": "redis", "port": 6379,
"description": "In-memory key-value store used primarily as an application cache.",
"container_state": "running", "health_status": "healthy",
"actions": ["disable"]
}

Các dịch vụ còn lại theo cùng mẫu, chỉ cần thay redis bằng tên dịch vụ:

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​

Varnish có thêm thống kê và công tắc theo từng tên miền, bên cạnh cặp trạng thái/hành động chuẩn.

# Status + domain list
GET /api/cache/varnish
{
"service": "varnish", "container_state": "stopped", "health_status": "unknown",
"actions": ["enable", "restart"],
"domain_statuses": {"example.com": "Off"}
}
# Enable/disable/restart
POST /api/cache/varnish
Content-Type: application/json

{"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
Content-Type: application/json

{"status": "On"}
{
"status": "running",
"cache": {"hit_ratio": 0.92, "hits": 9200, "misses": 800, "pass": 0},
"traffic": {"requests_total": 10000, "connections": 500},
"backend": {"requests": 800, "failures": 0, "retries": 0, "health": "healthy"},
"memory": {"objects": 120, "evictions": 0},
"performance": {"efficiency_score": 92, "error_rate": 0.0}
}

Docker / Container​

Liệt kê các dịch vụ compose​

GET /api/containers

Liệt kê các container đang chạy​

GET /api/containers/status
{"running_containers": ["nginx", "mysql", "php-fpm-8.2"]}

Lấy trạng thái của một container​

GET /api/containers/nginx/status
{"service": "nginx", "state": "running", "health": "healthy"}

Khởi động / dừng / khởi động lại​

POST /api/containers/nginx/start
POST /api/containers/nginx/stop
POST /api/containers/nginx/restart

Khởi động và kéo image về trước:

POST /api/containers/nginx/start
Content-Type: application/json

{"pull": true}

Cập nhật giới hạn CPU/RAM/PID​

PATCH /api/containers/myapp/resources
Content-Type: application/json

{"cpu": "1", "ram": "512m", "pids": "512"}

Cả ba trường đều tuỳ chọn — chỉ gửi những trường bạn muốn đổi.

{"message": "Resources updated", "results": {"cpu": "...", "ram": "...", "pids": "Max PIDs for container myapp set to 512"}}

Theo dõi nhật ký container​

GET /api/containers/nginx/logs?lines=200
{"service": "nginx", "lines": 200, "entries": [{"log": "2025/01/15 12:00:00 [notice] start worker process"}]}

Thêm / sửa / gỡ một dịch vụ compose​

Đừng nhầm với PATCH /api/containers/<service>/resources (giới hạn CPU/RAM của một dịch vụ đã có, đã nêu ở trên) — các endpoint này quản lý sự hiện diện và định nghĩa của dịch vụ trong chính docker-compose.yml. volumes là một danh sách các {"name": "...", "mount": "...", "readonly": false}.

POST /api/containers
Content-Type: application/json

{
"service_name": "phpmyadmin",
"image": "phpmyadmin:latest",
"cpu": "1",
"ram": "512m",
"network": "db",
"environment": "PMA_HOST=mariadb",
"add_socket": false,
"volumes": []
}

PATCH /api/containers/myservice
Content-Type: application/json

{"cpu": "1", "ram": "512m", "environment": "..."}

DELETE /api/containers/myservice

Chuyển biến thể MySQL/MariaDB​

Xoá volume dữ liệu cũ.

POST /api/containers/mysql
Content-Type: application/json

{"new_sql": "mysql:8.0"}

Chuyển máy chủ web đang dùng​

POST /api/containers/webserver
Content-Type: application/json

{"new_ws": "nginx"}

Đổi image của một dịch vụ​

PATCH /api/containers/myservice/image
Content-Type: application/json

{"new_tag": "myimage:tag"}

WAF (Tường lửa ứng dụng web)​

Trạng thái của mọi tên miền​

GET /api/waf
{"domains": {"example.com": "On"}}

Trạng thái của một tên miền​

GET /api/waf/example.com
{"domain": "example.com", "status": "On", "removed_rules": [], "removed_tags": []}

Bật/tắt WAF​

POST /api/waf/example.com
Content-Type: application/json

{"status": "On"}

Cập nhật các quy tắc loại trừ​

Các trường trong phần thân là removed_rules (ID quy tắc dạng số) và removed_tags — không phải remove_by_id/remove_by_tag.

PUT /api/waf/example.com/rules
Content-Type: application/json

{
"removed_rules": ["920170", "941100"],
"removed_tags": ["attack-sqli"]
}

Nhật ký WAF có phân trang​

GET /api/waf/log/example.com?page=1&per_page=25

Thống kê WAF​

GET /api/waf/stats/example.com?seconds=3600
{"domain": "example.com", "seconds": 3600, "checks": 120, "blocks": 4}

Liệt kê ID / thẻ của quy tắc​

Cả hai lệnh gọi đều dùng cùng một tuyến có tham số, /api/waf/ids/<id_type>, chỉ chấp nhận ids hoặc tags làm đoạn đường dẫn:

GET /api/waf/ids/ids
GET /api/waf/ids/tags
{"ids": ["920170", "941100"]}

Chặn IP​

Liệt kê các IP bị chặn​

GET /api/ip-blocker
{"blocked_ips": ["1.2.3.4", "10.0.0.0/8"]}

Chặn IP​

Chấp nhận IP đơn lẻ và dải CIDR.

POST /api/ip-blocker
Content-Type: application/json

{"ips": ["1.2.3.4", "10.0.0.0/8"]}
{"blocked": ["1.2.3.4", "10.0.0.0/8"], "invalid": [], "message": "2 IP(s) added to blocklist"}

Bỏ chặn mọi IP​

DELETE /api/ip-blocker

PHP​

Liệt kê các phiên bản PHP đã cài​

GET /api/php/versions

Lấy nội dung php.ini​

GET /api/php/8.2/ini

Lưu php.ini​

PUT /api/php/8.2/ini
Content-Type: application/json

{"content": "memory_limit = 256M\nupload_max_filesize = 64M\n..."}

Lấy các khoá và giá trị tuỳ chọn PHP​

GET /api/php/8.2/options

Cập nhật một số tuỳ chọn PHP​

PUT /api/php/8.2/options
Content-Type: application/json

{"memory_limit": "256M", "upload_max_filesize": "64M", "max_execution_time": "300"}

Liệt kê các phần mở rộng kèm trạng thái​

GET /api/php/8.2/extensions
{
"version": "8.2",
"service": "php-fpm-8.2",
"extensions": [
{"name": "imagick", "state": "active"},
{"name": "redis", "state": "disabled"},
{"name": "swoole", "state": "not_installed"}
],
"history": []
}

Bật/tắt một phần mở rộng​

enable là một giá trị boolean, không phải chuỗi action. PHP-FPM được khởi động lại sau đó.

POST /api/php/8.2/extensions
Content-Type: application/json

{"extension": "imagick", "enable": true}

Liệt kê mọi phần mở rộng được hỗ trợ​

GET /api/php/8.2/extensions/available

Cài phần mở rộng​

extensions là một danh sách (không phải một chuỗi extension đơn lẻ) — việc cài đặt chạy bất đồng bộ.

POST /api/php/8.2/extensions/install
Content-Type: application/json

{"extensions": ["swoole"]}
{"install_id": "b3f1...-uuid", "extensions": ["swoole"], "message": "Install started"}

Hỏi trạng thái cài đặt​

GET /api/php/8.2/extensions/install/status?install_id=b3f1...-uuid

Lấy / đặt phiên bản PHP mặc định của cả máy chủ​

Dùng cho các website/tên miền mới không có ghi đè riêng. Không dùng được theo cùng cách trên LiteSpeed — xem ghi chú theo từng tên miền bên dưới.

GET /api/php/default
{"version": "7.1", "service": "php-fpm-7.1", "is_litespeed": false, "installed_versions": ["8.5", "8.4", "..."]}
PUT /api/php/default
Content-Type: application/json

{"version": "8.2"}

Liệt kê / đổi phiên bản PHP gán cho từng tên miền​

PUT nhận tên miền trong phần thân yêu cầu, không phải trong đường dẫn URL. Không dùng được trên LiteSpeed vì nó không có PHP theo từng tên miền — hãy dùng PUT /api/php/default.

GET /api/php/domains
{
"domains": [{"DomainID": 52, "DomainURL": "example.com", "PHPVersion": "8.5", "Level": "good"}],
"counts": [{"Version": "8.5", "Count": 7, "Label": "Supported (Latest)", "Level": "good"}],
"outdated_domains": [],
"available_php_versions": ["8.5", "8.4", "..."],
"php_default_version": "7.1",
"is_litespeed": false
}
PUT /api/php/domains
Content-Type: application/json

{"domain": "example.com", "version": "8.2"}

Trình quản lý ứng dụng PHP​

Cài đặt và quản lý một dự án PHP dựa trên Composer trong thư mục gốc tài liệu của một tên miền sẵn có, chạy bên trong container php-fpm-<version> dùng chung mà phiên bản PHP của tên miền đó đã trỏ tới. Khác với trình cài ứng dụng Node.js/Python bên dưới, nó không bao giờ tạo container riêng — vhost sẵn có của tên miền đã định tuyến tới đúng container php-fpm.

Cài một ứng dụng PHP​

Phần thân dạng form-encoded; phản hồi truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/php/install

Chạy lại composer install / update​

POST /api/php/apps/composer-install/example.com
POST /api/php/apps/composer-update/example.com
Content-Type: application/json

{"optimize_autoloader": "true"}

Lấy nhật ký chạy Composer​

GET /api/php/apps/logs/example.com

Phản hồi là văn bản thuần ("No Composer runs recorded yet." nếu chưa có lần chạy nào).

Gỡ một ứng dụng PHP​

Gỡ mục theo dõi của ứng dụng và các thiết lập .env — các tệp trong docroot và cơ sở dữ liệu, nếu có, được giữ nguyên.

DELETE /api/php/apps/example.com

Tài khoản​

Lấy thông tin tài khoản​

GET /api/account
{
"username": "stefan",
"email": "stefan@example.com",
"plan_id": 1,
"context": "stefan",
"permit_username_change": false
}

Cập nhật tài khoản​

PATCH /api/account
Content-Type: application/json

{"email": "new@example.com"}
# or
{"password": "newpass"}
# or (only if allowed on this server)
{"username": "newname"}

Liệt kê các phiên đang hoạt động​

GET /api/account/sessions

Chấm dứt một phiên​

DELETE /api/account/sessions/<token>

Liệt kê / thêm / gỡ mục yêu thích​

GET /api/account/favorites
{"favorites": [{"link": "dashboard", "title": "Dashboard"}]}
POST /api/account/favorites
Content-Type: application/json

{"link": "dashboard", "title": "Dashboard"}

DELETE /api/account/favorites
Content-Type: application/json

{"link": "dashboard"}

Lấy / đặt ngôn ngữ giao diện ưa thích​

GET /api/account/language
{"locales": ["en", "de", "fr", "..."], "current": "en"}
PUT /api/account/language
Content-Type: application/json

{"locale": "de"}

Lấy lịch sử đăng nhập​

GET /api/account/login-history
{
"entries": [
{"ip": "203.0.113.10", "country_code": "US", "login_time": "2026-01-15 12:00:00"}
]
}

Lấy nhật ký hoạt động​

Có phân trang, mới nhất trước. search lọc theo chuỗi con (buộc show_all); show_all=true trả về mọi dòng khớp trên một trang.

GET /api/account/activity?page=1&search=&show_all=false
{
"rows": [
{"Timestamp": "2026-01-15 12:00:00", "IP": "203.0.113.10", "User": "myuser", "Action": "logged in via user API"}
],
"page": 1, "per_page": 100, "total_pages": 3, "total_lines": 214,
"show_all": false, "search": ""
}

Xác thực hai yếu tố​

Thiết lập gồm hai lệnh gọi: POST .../setup tạo một khoá bí mật đang chờ (2FA vẫn tắt), rồi POST .../confirm kiểm tra một mã với khoá đó và bật 2FA. Việc đăng ký passkey không có sẵn qua API — hãy dùng giao diện panel tại /account/passkeys để thêm. Việc liệt kê và thu hồi các passkey sẵn có được nêu bên dưới.

GET /api/account/2fa
{"enabled": false}
POST /api/account/2fa/setup
{"secret": "AHFB5DLV55SIZASCJEKFMSUPQ2GW6ZGV", "otpauth_url": "otpauth://totp/username?secret=...&issuer=HiTechCloud"}
POST /api/account/2fa/confirm
Content-Type: application/json

{"otp_code": "123456"}
DELETE /api/account/2fa

Liệt kê / thu hồi passkey​

GET /api/account/passkeys
{"passkeys": [{"id": 1, "name": "Passkey", "created_at": "2026-01-15 12:00:00", "last_used_at": ""}]}
DELETE /api/account/passkeys/1

Liệt kê / tạo / thu hồi token MCP​

Token gốc chỉ được trả về một lần, lúc tạo.

GET /api/account/mcp
{"tokens": [{"id": 1, "name": "my token", "token_prefix": "op_mcp_abc123", "read_only": true, "created_at": "2026-01-15 12:00:00"}]}
POST /api/account/mcp
Content-Type: application/json

{"name": "my token", "read_only": true, "expires_in_days": 30}
{"token": "op_mcp_...", "name": "my token", "read_only": true, "expires_in_days": 30}
DELETE /api/account/mcp/1

Lấy / cập nhật tuỳ chọn thông báo​

PUT chỉ đổi những khoá có trong phần thân — các khoá bạn bỏ qua được giữ nguyên.

GET /api/account/notifications
{"preferences": [{"key": "notify_account_login", "value": true, "label": " account login"}]}
PUT /api/account/notifications
Content-Type: application/json

{"preferences": {"notify_account_login": false}}

Mức sử dụng tài nguyên​

Ảnh chụp mới nhất​

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"}}
}

Lịch sử có phân trang​

GET /api/usage/history?page=1&per_page=25

Thông tin hosting​

Các endpoint thông tin chỉ đọc, luôn có sẵn. Chúng mô tả những gì một tài khoản cần để dùng hosting của mình - tên máy và IP để trỏ máy khách tới, bản phân phối và phiên bản phần mềm dùng chung mà mã của nó chạy trên đó, và các phiên bản PHP có thể gán cho một website. Trạng thái của chính máy (tải, uptime, kernel, CPU) thuộc về quản trị viên và không được báo cáo ở đây.

Thông tin hosting chung​

GET /api/hosting/info
{
"node": "hitechcloud", "ip": "203.0.113.10", "os": "Ubuntu 24.04.3 LTS",
"php_versions": ["8.4", "8.3", "8.2"],
"software": [{"name": "Web Server", "version": "1.24.0"}, {"name": "Database", "version": "10.11.8"}]
}

Chi tiết gói hosting​

GET /api/hosting/plan
{
"context": "myuser", "plan_webserver": "nginx", "plan_mysql": "mariadb",
"plan_cpu_limit": "4", "plan_ram_limit": "6g", "plan_disk_limit": "50 GB",
"plan_bandwidth": "500", "plan_domains_limit": "10", "plan_websites_limit": "10",
"plan_db_limit": "20", "plan_email_limit": "500", "plan_ftp_limit": "100",
"plan_inodes_limit": "1000000", "plan_max_email_quota": "2G",
"plan_description": "A professional plan", "ns1": "", "ns2": "", "ns3": "", "ns4": ""
}

Các cổng truy cập từ xa được cấp​

GET /api/hosting/ports
{"remote_mysql_port": "32770", "remote_postgres_port": "32771"}

Thông tin máy chủ gộp​

Cùng ba payload ở trên (info/plan/ports), trong một lệnh gọi — đúng những gì trang panel /server/info tự lấy, gộp lại.

GET /api/server/info
{
"info": {"node": "hitechcloud", "ip": "203.0.113.10", "os": "Ubuntu 24.04.3 LTS", "php_versions": ["8.4", "8.3"], "software": []},
"plan": {"context": "myuser", "plan_webserver": "nginx", "plan_mysql": "mariadb", "plan_cpu_limit": "4", "plan_ram_limit": "6g"},
"ports": {"remote_mysql_port": "32770", "remote_postgres_port": "32771"}
}

Dung lượng đĩa & Inode​

Dung lượng đĩa (gốc)​

GET /api/disk-usage

Dung lượng đĩa của một đường dẫn​

GET /api/disk-usage/public_html
{
"directory": "public_html",
"entries": [
{"size": "120M", "path": "wp-content"},
{"size": "3.2M", "path": "wp-includes"}
]
}

Số inode (gốc)​

GET /api/inodes

Số inode của một đường dẫn​

GET /api/inodes/public_html
{
"directory": "public_html",
"entries": [{"folder": "wp-content", "inode_count": 4200}]
}

Trình quét mã độc​

Liệt kê các tệp bị cách ly​

GET /api/malware-scanner/quarantine
{"quarantine_files": [], "count": 0}

Liệt kê các lần quét trước​

Các lần quét bắt đầu từ trang Trình quét mã độc và qua API này, cùng lần chạy cuối của quét theo lịch, mới nhất trước. source là panel, api hoặc schedule; status là complete, stopped (trang bị đóng trong lúc quét) hoặc failed. Mỗi mục liệt kê tối đa 100 tệp bị nhiễm; infected là tổng số đầy đủ.

GET /api/malware-scanner/logs
{
"count": 1,
"logs": [
{
"source": "api",
"started_at": "2026-10-03 10:00:00",
"finished_at": "2026-10-03 10:01:12",
"directory": "/home/alice/public_html",
"scanned": 1234,
"infected": 1,
"status": "complete",
"message": "",
"files": [{"path": "wp-content/uploads/x.php", "signature": "Php.Webshell-1"}]
}
]
}

Chạy một lần quét​

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
}

Trình hướng dẫn sao lưu​

Luồng "sao lưu toàn bộ tài khoản của tôi" chỉ bằng một cú nhấp — tạo một tệp .tar.gz của volume docroot của tài khoản ở chế độ nền.

Lấy trạng thái sao lưu và các bản sao lưu sẵn có​

GET /api/backup-wizard/status
{
"in_progress": false,
"in_progress_started": "2026-01-15 12:00:00",
"in_progress_size": "45.2 MB",
"backups": [
{"name": "myuser_backup_2026-01-15_12-00-00.tar.gz", "size_raw": 47448064, "size": "45.2 MB", "mtime": "2026-01-15 12:00:00", "in_progress": false}
]
}

in_progress_started và in_progress_size chỉ có mặt khi một bản sao lưu đang chạy.

Bắt đầu một bản sao lưu​

Gửi rồi quên — trả về ngay, hỏi GET /api/backup-wizard/status để biết tiến độ. Trả về 409 nếu đã có một bản sao lưu đang chạy.

POST /api/backup-wizard/create
{"message": "Backup started. Poll GET /api/backup-wizard/status for progress."}

Tải một bản sao lưu​

Truyền trực tiếp tệp .tar.gz. Trả về 409 nếu tệp được yêu cầu vẫn là tệp đang được ghi.

GET /api/backup-wizard/download/myuser_backup_2026-01-15_12-00-00.tar.gz

Sao lưu​

Luồng đích sao lưu có thể cấu hình (S3, WebDAV, SSH, Azure, Dropbox) — tách biệt với Trình hướng dẫn sao lưu một cú nhấp ở trên. values chứa các khoá thông tin xác thực riêng của đích đang dùng (khác nhau theo từng đích); settings chứa các khoá lịch/lưu giữ/thông báo dùng chung.

Lấy bản tóm tắt trạng thái​

GET /api/backups
{"target": "s3", "service_active": true, "values": {"AWS_ACCESS_KEY_ID": "..."}, "settings": {"BACKUP_RETENTION_DAYS": "7"}}

Lấy / cập nhật cài đặt​

GET /api/backups/settings
PUT /api/backups/settings
Content-Type: application/json

{"values": {"AWS_ACCESS_KEY_ID": "AKIA..."}, "settings": {"BACKUP_RETENTION_DAYS": "7"}}

Lấy / chuyển đích đang dùng​

GET /api/backups/destination
{"active": "s3", "targets": ["s3", "webdav", "ssh", "azure", "dropbox"]}
PUT /api/backups/destination
Content-Type: application/json

{"target": "s3"}

Liệt kê các bản sao lưu tại đích​

Được phục vụ từ một chỉ mục đã lưu đệm; giao diện panel lập chỉ mục lại định kỳ với đích từ xa.

GET /api/backups/list
[{"name": "myuser-2026-01-15T12-00-00.tar.gz", "size": "45.2 MB", "mtime": "2026-01-15 12:00:00"}]

Khôi phục từ một bản sao lưu​

restore_target là all (tệp + cơ sở dữ liệu), database (một cơ sở dữ liệu — đặt database là tên của nó) hoặc files (chỉ tệp).

POST /api/backups/restore
Content-Type: application/json

{"backup_file": "myuser-2026-01-15T12-00-00.tar.gz", "restore_target": "all", "database": ""}
{"success": true, "message": "Full restore completed."}

Tải một bản sao lưu​

Truyền trực tiếp kho lưu từ đích đã cấu hình.

POST /api/backups/download
Content-Type: application/json

{"backup_file": "myuser-2026-01-15T12-00-00.tar.gz"}

Trình quản lý tệp​

Mọi đường dẫn đều tính tương đối so với /var/www/html/. Một đường dẫn thoát ra khỏi docroot của tài khoản luôn bị từ chối, dù được viết thế nào.

Liệt kê một thư mục​

Bỏ đoạn đường dẫn (GET /api/files) để liệt kê gốc docroot.

GET /api/files/subdir?hidden_files=true&page=1
{
"files_info": [{"Permissions": "-rw-r--r--", "Links": "1", "Owner": "1001", "Group": "1001", "Size": "0", "Date": "Aug 10 20:45", "Name": "hello.txt", "LinkTarget": "", "Type": "file"}],
"pagination": {"current_page": 1, "total_pages": 1, "per_page": 500, "total_files": 1},
"limits": {"edit_size_mb": 5, "view_size_mb": 5, "download_size_mb": 2000, "upload_size_mb": 2000},
"extensions": {"extensions": ".txt .md .php ...", "images": ".jpg .png ...", "archives": ".zip .tar.gz ..."}
}

Liệt kê thư mục con (cho bộ chọn đích sao chép/di chuyển)​

GET /api/folders/subdir
{"folders": [{"name": "images", "path": "subdir/images", "has_subfolders": false}]}

Tạo một tệp / thư mục​

POST /api/file-manager/new-file
Content-Type: application/json

{"path": "subdir", "filename": "notes.txt"}

POST /api/file-manager/new-directory
Content-Type: application/json

{"path": "subdir", "foldername": "images"}

Tải tệp lên​

Multipart — tên trường phải là files (có thể lặp lại), cộng với một trường path_param cho thư mục đích.

POST /api/file-manager/upload
Content-Type: multipart/form-data

files=@photo.jpg
path_param=subdir
{"uploaded": ["photo.jpg"], "errors": []}

Đổi tên​

POST /api/file-manager/rename
Content-Type: application/json

{"path": "subdir", "old_name": "old.txt", "new_name": "new.txt"}

Xoá​

mode là permanent (mặc định) hoặc trash.

DELETE /api/file-manager/delete?filename=old.txt&path_param=subdir&item_type=file&mode=trash

Đổi quyền​

Áp dụng một chế độ bát phân cho một hoặc nhiều tệp cùng lúc.

POST /api/file-manager/permissions
Content-Type: application/json

{"path": "subdir", "filenames": ["a.txt", "b.txt"], "permissions": "644"}
{"changed": ["a.txt", "b.txt"], "errored": []}

Sao chép / di chuyển​

POST /api/file-manager/copy?item_name=a.txt&item_type=file&path_param=subdir&destination_path=other/a.txt

POST /api/file-manager/move?item_name=a.txt&path_param=subdir&destination_path=other/a.txt

Lấy / lưu nội dung tệp​

GET trả về nội dung thô dưới dạng một chuỗi JSON trần (không bọc trong một đối tượng). Cả hai bị giới hạn ở các loại tệp văn bản sửa được; PUT còn chuẩn hoá ký tự xuống dòng cho các loại tệp văn bản đã biết.

GET /api/file-manager/edit-file/subdir/notes.txt
"file content here"
PUT /api/file-manager/edit-file/subdir/notes.txt
Content-Type: application/json

{"content": "new file content"}

Tải xuống / xem một tệp​

Tải xuống truyền trực tiếp application/octet-stream kèm tiêu đề Content-Disposition dạng đính kèm; xem trả về nội dung thô dưới dạng text/plain (hoặc phục vụ trực tiếp tệp với hình ảnh). Cả hai nhận path_param làm tham số truy vấn cho thư mục cha.

GET /api/file-manager/download-file/subdir/notes.txt
GET /api/file-manager/view-file/subdir/notes.txt

Giải nén / tạo một kho lưu​

Hỗ trợ zip, tar, tar.gz/tgz và gzip một tệp. extract_destination mặc định là thư mục của chính kho lưu; bỏ qua hoặc dùng / để chỉ chính docroot.

POST /api/file-manager/extract-archive
Content-Type: application/json

{"archive_name": "backup.zip", "path": "subdir", "extract_destination": "subdir/extracted"}
POST /api/file-manager/create-archive
Content-Type: application/json

{"archive_name": "backup", "extension": "zip", "path": "subdir", "selected_files": ["a.txt", "b.txt"]}

Tải một tệp từ URL​

Gửi rồi quên. Chỉ cho phép URL http/https công khai — các địa chỉ loopback, riêng tư và link-local bị từ chối. Trả về một download_id để hỏi trạng thái.

POST /api/file-manager/wget
Content-Type: multipart/form-data

url=https://example.com/file.zip
path_param=subdir
GET /api/file-manager/wget/status/<download_id>
{"progress": 100, "status": "done", "message": "File downloaded from URL successfully to /var/www/html/subdir"}

Thùng rác​

Liệt kê các mục trong thùng rác​

GET /api/trash
[{"Permissions": "-rw-r--r--", "Name": "old.txt", "Type": "file", "DeletionDate": "2026-01-15T12:00:00", "OriginalPath": "/var/www/html/subdir/old.txt"}]

Khôi phục / xoá vĩnh viễn một mục​

POST /api/trash/restore?filename=old.txt

DELETE /api/trash/delete?filename=old.txt

Khôi phục / xoá tất cả​

POST /api/trash/restore-all
{"restored": ["old.txt"], "errors": []}
POST /api/trash/delete-all

Cấu hình máy chủ web​

Lấy cấu hình​

GET /api/webserver-conf
{
"web_server": "nginx",
"label": "Nginx",
"filename": "nginx.conf",
"service": "nginx",
"content": "server { ... }"
}

Lưu cấu hình​

Được kiểm tra và khởi động lại tự động; nội dung trước đó được khôi phục nếu kiểm tra cú pháp thất bại.

PUT /api/webserver-conf
Content-Type: application/json

{"content": "server {\n listen 80;\n ...\n}"}

Trình quản lý tiến trình​

Liệt kê các tiến trình đang chạy​

GET /api/process-manager
{
"processes": [
{"container": "nginx", "uid": "0", "pid": "1234", "ppid": "1", "cpu": "0.0", "stime": "12:00", "tty": "?", "time": "00:00:01", "cmd": "nginx: master process"}
],
"count": 1
}

Kết thúc một tiến trình​

DELETE /api/process-manager/1234

Sửa quyền​

Liệt kê thư mục​

GET /api/fix-permissions
{"directories": ["/var/www/html/example.com", "/var/www/html/example.com/wp-content"]}

Sửa quyền​

Bỏ directory (hoặc truyền /) để sửa cho cả tài khoản; nếu không nó phải nằm trong /var/www/html/.

POST /api/fix-permissions
Content-Type: application/json

{"directory": "/var/www/html/example.com"}

Trang & Website​

Liệt kê mọi website​

GET /api/sites

Lấy chi tiết website​

GET /api/sites/example.com

Kiểm tra Google Safe Browsing​

GET /api/sites/example.com/safebrowsing
{"status": "safe", "url": "http://example.com", "threats": []}

Lấy / kích hoạt dữ liệu PageSpeed​

GET /api/sites/example.com/pagespeed
POST /api/sites/example.com/pagespeed

Lấy / chạy quét lỗ hổng WP​

GET /api/sites/example.com/wp-vulnerability
POST /api/sites/example.com/wp-vulnerability
GET /api/sites/example.com/temporary-link

Lấy khách truy cập gần đây​

GET /api/sites/example.com/visitors?seconds=60
{"domain": "example.com", "seconds": 60, "count": 3, "ips": ["203.0.113.10", "..."]}

Lấy favicon​

Chuyển hướng (302) tới favicon của website — dịch vụ favicon của Google, hoặc một proxy favicon đã cấu hình.

GET /api/sites/example.com/favicon

Lấy / làm mới ảnh chụp màn hình​

GET trả về một ảnh chụp đã lưu đệm (lấy và lưu đệm một ảnh trước nếu chưa có); POST buộc lấy lại.

GET /api/sites/example.com/screenshot
POST /api/sites/example.com/screenshot

Phản hồi chính là hình ảnh (image/png).

Lấy kích thước cơ sở dữ liệu​

Hoặc là kích thước trên đĩa của một bản cài WordPress (wp db size, cần domain + docroot) hoặc kích thước của một cơ sở dữ liệu thô (cần database).

GET /api/sites/database-size?domain=example.com&docroot=/var/www/html/example.com
{"size": "45.2 MB"}

Chạy lại cài đặt gói​

Chạy lại pip install/npm install/pnpm install cho một ứng dụng Node.js/Python đã tạo (khác với POST /api/nodejs/install//api/python/install, vốn tạo ứng dụng).

POST /api/sites/example.com/packages/npm
{"message": "NPM packages installed successfully.", "output": "..."}

Lấy thông tin website WordPress​

Các phiên bản PHP/MySQL/WP và thông tin xác thực cơ sở dữ liệu của một website WordPress. Hỗ trợ website trong thư mục con (ví dụ example.com/blog).

GET /api/sites/example.com/wp-info
{
"wp_version": "6.7.1",
"php_version": "8.2",
"mysql_version": "10.11.6",
"database_info": {"database_host": "mariadb", "database_name": "wp_db", "database_user": "wp_user", "database_password": "...", "database_table_prefix": "wp_"}
}

Chuyển tiếp WP-CLI của trình quản lý website​

Một bộ hành động riêng, nhỏ hơn POST /api/wp-cli/<action> bên dưới — giới hạn trong các bảng chung/gỡ lỗi/tuỳ chọn cập nhật của giao diện một trang của trình quản lý website.

GET /api/sites/wp-cli/site_info?website=example.com&docroot=/var/www/html/example.com
{"success": true, "site_url": "https://example.com", "home_url": "https://example.com", "site_name": "My Blog", "tagline": "Just another WordPress site", "admin_email": "admin@example.com"}

action: site_info, update_debug, update_site_information, update_now, update_update_preferences, debug_info, update_info. website (hoặc domain) và docroot luôn bắt buộc; update_debug/update_site_information/update_update_preferences nhận giá trị của chúng qua các tham số truy vấn bổ sung (ví dụ &WP_DEBUG=true, &siteurl=https://example.com).


Drupal​

Cố ý đơn giản hơn API WordPress bên dưới: cài đặt, nhân bản, cập nhật, dựng lại bộ nhớ đệm và gỡ cài đặt — không có endpoint liệt kê, không quét hệ thống tệp, không có quy tắc tăng cường bảo mật, không chuyển tiếp drush chung. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Drupal​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (composer create-project drupal/recommended-project, composer require drush/drush, thiết lập cơ sở dữ liệu, drush site:install).

POST /api/drupal/install
Content-Type: application/json

{
"domain_id": "42",
"site_name": "My Drupal Site",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"drupal_version": ""
}
{"status": "Creating Composer project drupal/recommended-project"}
{"status": "Requiring drush/drush"}
{"status": "Creating database drupal_a1b2c3 and user d4e5f6g7h8"}
{"status": "Running drush site:install"}
{"status": "Drupal installation completed!"}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản Drupal​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

POST /api/drupal/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"source_db": "drupal_a1b2c3",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"drupal_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "drupal_d4e5f6"}

Cập nhật Drupal​

Cập nhật Drupal lên phiên bản mới nhất qua drush. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/drupal/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Running composer update"}
{"status": "Running database updates (drush updatedb)"}
{"status": "Update completed!", "version": "11.2.5"}

Xoá bộ nhớ đệm Drupal​

Dựng lại bộ nhớ đệm Drupal qua drush cache:rebuild.

POST /api/drupal/sites/42/cache
{"message": "Cache rebuilt successfully."}

Gỡ cài đặt Drupal​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/drupal/sites/42

Flarum​

Cài đặt, nhân bản, cập nhật, xoá bộ nhớ đệm và gỡ cài đặt. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Flarum​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (composer create-project flarum/flarum, thiết lập cơ sở dữ liệu, flarum install).

POST /api/flarum/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"site_name": "My Flarum Forum",
"flarum_version": "",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"db_name": "",
"db_user": "",
"db_password": ""
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản Flarum​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

POST /api/flarum/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"source_db": "flarum_a1b2c3",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"flarum_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "flarum_d4e5f6"}

Cập nhật Flarum​

Cập nhật Flarum lên phiên bản mới nhất qua composer require + flarum migrate. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/flarum/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Running composer require (flarum/core:^2.0)"}
{"status": "Running database migrations (flarum migrate)"}
{"status": "Clearing cache"}
{"status": "Update completed!", "version": "2.1.0"}

Xoá bộ nhớ đệm Flarum​

POST /api/flarum/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt Flarum​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/flarum/sites/42

Matomo​

Cài đặt, nhân bản, cập nhật, xoá bộ nhớ đệm và gỡ cài đặt — không có endpoint liệt kê hay tăng cường bảo mật. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Matomo​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/matomo/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"matomo_version": "",
"admin_login": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"db_name": "",
"db_user": "",
"db_password": ""
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, phiên bản mới nhất).

Nhân bản Matomo​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

POST /api/matomo/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"source_db": "matomo_a1b2c3",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"matomo_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "matomo_d4e5f6"}

Cập nhật Matomo​

Cập nhật Matomo lên phiên bản mới nhất bằng cách tải kho phát hành về và chạy console core:update. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/matomo/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Downloading https://builds.matomo.org/matomo-5.3.1.zip"}
{"status": "Replacing core files (preserving config)"}
{"status": "Running database updates (console core:update)"}
{"status": "Update completed!", "version": "5.3.1"}

Xoá bộ nhớ đệm Matomo​

POST /api/matomo/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt Matomo​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/matomo/sites/42

MediaWiki​

Cài đặt, nhân bản, cập nhật và gỡ cài đặt — không có endpoint bộ nhớ đệm. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài MediaWiki​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/mediawiki/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"mediawiki_version": "",
"site_name": "My Wiki",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"db_name": "",
"db_user": "",
"db_password": ""
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, phiên bản mới nhất).

Nhân bản MediaWiki​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). source_db được suy ra tự động từ LocalSettings.php của website nguồn, nên chỉ cần target_domain.

POST /api/mediawiki/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"mediawiki_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "mediawiki_d4e5f6"}

Cập nhật MediaWiki​

Cập nhật MediaWiki lên phiên bản mới nhất và chạy maintenance/update.php. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/mediawiki/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Downloading https://releases.wikimedia.org/mediawiki/1.42/mediawiki-1.42.3.tar.gz"}
{"status": "Replacing core files (preserving LocalSettings.php and images/)"}
{"status": "Running maintenance/update.php"}
{"status": "Update completed!", "version": "1.42.3"}

Gỡ cài đặt MediaWiki​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/mediawiki/sites/42

DokuWiki​

Cài đặt, nhân bản, cập nhật và gỡ cài đặt — CMS dùng tệp phẳng, nên không có trường cơ sở dữ liệu nào và không có endpoint bộ nhớ đệm. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài DokuWiki​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải về, giải nén, thiết lập tài khoản quản trị).

POST /api/dokuwiki/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"admin_email": "admin@example.com",
"admin_user": "admin",
"admin_password": "changeme",
"admin_full_name": "Admin User",
"site_title": "My DokuWiki"
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

Nhân bản DokuWiki​

Sao chép tệp của website sang một tên miền mới (hoặc thư mục con). Không có trường cơ sở dữ liệu — chỉ cần target_domain.

POST /api/dokuwiki/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"admin_email": "admin@example.com"
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": ""}

Cập nhật DokuWiki​

Tải về và áp dụng bản phát hành DokuWiki mới nhất. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/dokuwiki/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Downloading latest DokuWiki release"}
{"status": "Applying update: 2023-04-04a -> 2024-02-16b"}
{"status": "Update completed!", "version": "2024-02-16b"}

Nếu website đã ở bản phát hành mới nhất, luồng thay vào đó phát ra {"status": "Already running the latest version (2024-02-16b)", "version": "2024-02-16b"} rồi dừng.

Gỡ cài đặt DokuWiki​

Xoá mọi tệp trong docroot và gỡ nó khỏi Trình quản lý website.

DELETE /api/dokuwiki/sites/42

Moodle​

Cài đặt, nhân bản, cập nhật, dọn bộ nhớ đệm và gỡ cài đặt. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Moodle​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/moodle/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"moodle_version": "",
"site_name": "My Moodle Site",
"site_shortname": "",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"db_name": "",
"db_user": "",
"db_password": ""
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, phiên bản mới nhất).

Nhân bản Moodle​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động. Không như hầu hết các endpoint nhân bản CMS khác, không có trường source_folder — docroot của Moodle là một liên kết tượng trưng suy ra từ slug của website.

POST /api/moodle/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"source_db": "moodle_a1b2c3",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"moodle_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "moodle_d4e5f6"}

Cập nhật Moodle​

Cập nhật Moodle lên bản dựng mới nhất của chính dòng phát hành của website (website 4.5 vẫn ở 4.5) và chạy admin/cli/upgrade.php. Thêm ?major=1 để chuyển sang dòng phát hành Moodle mới nhất (ví dụ từ 4.5 lên 5.x); một bản phát hành lớn có thể cần phiên bản PHP mới hơn. Bản phát hành được giải nén cạnh website và kiểm tra trước khi thay đổi bất cứ điều gì: nếu nó không mới hơn bản dựng đã cài, luồng kết thúc bằng Already running the latest version …, và nếu phiên bản PHP của tên miền cũ hơn mức bản phát hành yêu cầu, luồng kết thúc bằng một lỗi. Nếu upgrade.php dừng trước khi thay đổi cơ sở dữ liệu, bản phát hành trước được đặt lại. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/moodle/sites/42/update
POST /api/moodle/sites/42/update?major=1
{"status": "Checking if existing installation processes are running.."}
{"status": "Preparing PHP 8.3"}
{"status": "Moodle 5.3.0 is a major upgrade: this update stays on Moodle 4.5 (ask for the major upgrade to move to 5.3.0)"}
{"status": "Downloading https://download.moodle.org/download.php/direct/stable405/moodle-latest-405.tgz"}
{"status": "Extracting the new release beside the site"}
{"status": "Copying config.php into the new release"}
{"status": "Enabling maintenance mode"}
{"status": "Replacing core files (preserving config.php)"}
{"status": "Setting files permissions and owner to 'alice'"}
{"status": "Running admin/cli/upgrade.php"}
{"status": "Disabling maintenance mode"}
{"status": "Update completed!", "version": "4.5.15+"}

Khi website đã chạy bản dựng mới nhất của dòng phát hành của nó:

{"status": "Already running the latest version of Moodle 4.5 (4.5.15+)", "version": "4.5.15+"}

Xoá bộ nhớ đệm Moodle​

POST /api/moodle/sites/42/cache
{"message": "Caches purged successfully."}

Gỡ cài đặt Moodle​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/moodle/sites/42

Joomla​

Cố ý đơn giản hơn API WordPress bên dưới: cài đặt, nhân bản, xoá bộ nhớ đệm và gỡ cài đặt — không có endpoint liệt kê, không quét hệ thống tệp, không có quy tắc tăng cường bảo mật. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Joomla​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải kho về từ GitHub, giải nén, thiết lập cơ sở dữ liệu, trình cài CLI installation/joomla.php install của chính Joomla).

POST /api/joomla/install
Content-Type: application/json

{
"domain_id": "42",
"site_name": "My Joomla Site",
"admin_name": "Administrator",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"joomla_version": ""
}
{"status": "Downloading https://hitechcloud.org"}
{"status": "Extracting files to /var/www/html/example.com"}
{"status": "Creating database joomla_a1b2c3 and user d4e5f6g7h8"}
{"status": "Running Joomla CLI installer"}
{"status": "Joomla installation completed!"}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản một website Joomla​

POST /api/joomla/clone
Content-Type: application/json

{
"source_domain": "example.com",
"target_domain": "clone.example.com",
"source_db": "joomla_a1b2c3",
"source_folder": "",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": ""
}

Các trường để trống dùng giá trị sinh tự động, giống như khi cài đặt.

Xoá bộ nhớ đệm Joomla​

POST /api/joomla/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt Joomla​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/joomla/sites/42

OpenCart​

Cố ý đơn giản hơn API WordPress bên dưới: cài đặt, nhân bản, xoá bộ nhớ đệm và gỡ cài đặt — không có endpoint cập nhật, không có endpoint liệt kê, không quét hệ thống tệp, không có quy tắc tăng cường bảo mật. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài OpenCart​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải kho về từ GitHub, giải nén, thiết lập cơ sở dữ liệu, trình cài CLI install/cli_install.php install của chính OpenCart).

POST /api/opencart/install
Content-Type: application/json

{
"domain_id": "42",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"opencart_version": ""
}
{"status": "Downloading https://hitechcloud.org"}
{"status": "Extracting files to /var/www/html/example.com"}
{"status": "Creating database opencart_a1b2c3 and user d4e5f6g7h8"}
{"status": "Running OpenCart CLI installer"}
{"status": "OpenCart installation completed!"}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản OpenCart​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). source_db được suy ra tự động từ config.php của website nguồn, nên chỉ cần target_domain.

POST /api/opencart/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"opencart_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "opencart_d4e5f6"}

Xoá bộ nhớ đệm OpenCart​

POST /api/opencart/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt OpenCart​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/opencart/sites/42

Nextcloud​

Cố ý đơn giản hơn API WordPress bên dưới: cài đặt, nhân bản, cập nhật, xoá bộ nhớ đệm và gỡ cài đặt — không có endpoint liệt kê, không quét hệ thống tệp, không có quy tắc tăng cường bảo mật. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài Nextcloud​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải kho về từ download.nextcloud.com, giải nén, thiết lập cơ sở dữ liệu, trình cài CLI occ maintenance:install của chính Nextcloud, cấu hình tên miền tin cậy).

POST /api/nextcloud/install
Content-Type: application/json

{
"domain_id": "42",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"nextcloud_version": ""
}
{"status": "Downloading https://download.nextcloud.com/server/releases/nextcloud-34.0.3.zip"}
{"status": "Extracting files to /var/www/html/example.com"}
{"status": "Creating database nextcloud_a1b2c3 and user d4e5f6g7h8"}
{"status": "Running Nextcloud CLI installer (occ maintenance:install)"}
{"status": "Configuring trusted domain and site URL"}
{"status": "Nextcloud installation completed!"}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản Nextcloud​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

POST /api/nextcloud/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"source_db": "nextcloud_a1b2c3",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"nextcloud_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "nextcloud_d4e5f6"}

Cập nhật Nextcloud​

Cập nhật Nextcloud lên phiên bản mới nhất qua occ upgrade. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/nextcloud/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: hitechcloud_php83"}
{"status": "Downloading https://download.nextcloud.com/server/releases/nextcloud-34.0.3.zip"}
{"status": "Enabling maintenance mode"}
{"status": "Replacing core files (preserving config and data)"}
{"status": "Running occ upgrade"}
{"status": "Disabling maintenance mode"}
{"status": "Update completed!", "version": "34.0.3"}

Xoá bộ nhớ đệm Nextcloud​

POST /api/nextcloud/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt Nextcloud​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/nextcloud/sites/42

PrestaShop​

Cố ý đơn giản hơn API WordPress bên dưới: cài đặt, nhân bản, xoá bộ nhớ đệm và gỡ cài đặt — không có endpoint cập nhật, không có endpoint liệt kê, không quét hệ thống tệp, không có quy tắc tăng cường bảo mật. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài PrestaShop​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải kho về từ GitHub, giải nén, thiết lập cơ sở dữ liệu, trình cài CLI install/index_cli.php của chính PrestaShop, đổi tên thư mục quản trị).

POST /api/prestashop/install
Content-Type: application/json

{
"domain_id": "42",
"admin_firstname": "Admin",
"admin_lastname": "User",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"prestashop_version": ""
}
{"status": "Downloading https://hitechcloud.org"}
{"status": "Extracting files to /var/www/html/example.com"}
{"status": "Creating database prestashop_a1b2c3 and user d4e5f6g7h8"}
{"status": "Running PrestaShop CLI installer"}
{"status": "Securing admin directory"}
{"status": "PrestaShop installation completed!"}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên "Admin"/"User", phiên bản mới nhất có tệp phát hành tải về được).

Nhân bản PrestaShop​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). source_db được suy ra tự động từ app/config/parameters.php của website nguồn, nên chỉ cần target_domain.

POST /api/prestashop/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"prestashop_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "prestashop_d4e5f6"}

Xoá bộ nhớ đệm PrestaShop​

POST /api/prestashop/sites/42/cache
{"message": "Cache cleared successfully."}

Gỡ cài đặt PrestaShop​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/prestashop/sites/42

SofaWiki​

Chỉ cài đặt, nhân bản và gỡ cài đặt — CMS dùng tệp phẳng, nên không có trường cơ sở dữ liệu nào và không có endpoint cập nhật hay bộ nhớ đệm. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài SofaWiki​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/sofawiki/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"admin_email": "admin@example.com"
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động.

Nhân bản SofaWiki​

Sao chép tệp của website sang một tên miền mới (hoặc thư mục con). Không có trường cơ sở dữ liệu — chỉ cần target_domain.

POST /api/sofawiki/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"admin_email": "admin@example.com"
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": ""}

Gỡ cài đặt SofaWiki​

Xoá mọi tệp trong docroot và gỡ nó khỏi Trình quản lý website.

DELETE /api/sofawiki/sites/42

phpBB​

Chỉ cài đặt, nhân bản và gỡ cài đặt — không có endpoint cập nhật hay bộ nhớ đệm. Chỉ MySQL/MariaDB. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài phpBB​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải kho về, giải nén, thiết lập cơ sở dữ liệu, cài bằng CLI).

POST /api/phpbb/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"board_name": "My Board",
"board_description": "A phpBB forum",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com"
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tên người dùng admin, phiên bản mới nhất).

Nhân bản phpBB​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). source_db được suy ra tự động từ config.php của website nguồn, nên chỉ cần target_domain. Lưu ý trường phiên bản có tên version, không phải phpbb_version.

POST /api/phpbb/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "phpbb_d4e5f6"}

Gỡ cài đặt phpBB​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp trong docroot, và gỡ nó khỏi Trình quản lý website.

DELETE /api/phpbb/sites/42

TinyPhotoGallery​

Chỉ cài đặt và gỡ cài đặt — không có endpoint nhân bản, cập nhật hay bộ nhớ đệm. Không có cơ sở dữ liệu, không có tài khoản quản trị, không có phiên bản. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài TinyPhotoGallery​

Tải về một tệp index.php duy nhất và tạo một thư mục photos/ trống bên cạnh. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/tinyphotogallery/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": ""
}

domain_id là bắt buộc; subdirectory là tuỳ chọn (để trống để cài ở gốc tên miền).

{"status": "TinyPhotoGallery installation completed!"}

Gỡ cài đặt TinyPhotoGallery​

Xoá mọi tệp trong docroot và gỡ nó khỏi Trình quản lý website.

DELETE /api/tinyphotogallery/sites/42

TinyFileManager​

Chỉ cài đặt và gỡ cài đặt — không có endpoint nhân bản, cập nhật hay bộ nhớ đệm. Không có cơ sở dữ liệu, không có phiên bản. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài TinyFileManager​

Tải về một tệp tinyfilemanager.php duy nhất và ghi tên người dùng/mật khẩu quản trị đã cho (băm bcrypt, thực hiện bên trong container để khớp với bản PHP của chính container đó) thẳng vào mảng $auth_users của nó. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/tinyfilemanager/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"admin_username": "admin",
"admin_password": "changeme"
}

domain_id, admin_username và admin_password là bắt buộc.

{"status": "TinyFileManager installation completed!", "admin_user": "admin"}

Gỡ cài đặt TinyFileManager​

Xoá mọi tệp trong docroot và gỡ nó khỏi Trình quản lý website.

DELETE /api/tinyfilemanager/sites/42

OJS​

Cài đặt, nhân bản, cập nhật, bộ nhớ đệm và gỡ cài đặt. Chỉ MySQL/MariaDB, yêu cầu PHP 8.2+. Các website đã cài vẫn hiện trong Trình quản lý website chung (GET /api/sites).

Cài OJS​

Tải trực tiếp gói phát hành Open Journal Systems chính thức từ máy chủ phát hành của PKP (không phải kho GitHub — kho dùng submodule mà việc tải kho thường sẽ bỏ sót) và chạy trình cài CLI của nó ở chế độ không tương tác. Phần mở rộng PHP ftp cần thiết được tự động cài trước nếu container PHP chưa có. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy.

POST /api/ojs/install
Content-Type: application/json

{
"domain_id": "42",
"subdirectory": "",
"ojs_version": "",
"admin_username": "admin",
"admin_password": "changeme",
"admin_email": "admin@example.com",
"db_name": "",
"db_user": "",
"db_password": ""
}

domain_id là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (ojs_version để trống sẽ lấy bản phát hành mới nhất).

{"status": "Checking if existing installation processes are running.."}
{"status": "Starting PHP container: php-fpm-8.5"}
{"status": "Downloading https://pkp.sfu.ca/ojs/download/ojs-3.5.0-5.tar.gz"}
{"status": "Creating database ojs_x52piq and user avalnaow32"}
{"status": "Ensuring PHP 'ftp' extension is installed"}
{"status": "Running OJS CLI installer (tools/install.php)"}
{"status": "OJS installation completed!"}

Nhân bản OJS​

Sao chép tệp và cơ sở dữ liệu của website sang một tên miền mới (hoặc thư mục con). target_domain và source_db là bắt buộc; mọi thứ khác dùng giá trị sinh tự động. Giống Moodle, không có trường source_folder — docroot của OJS là một liên kết tượng trưng suy ra từ slug của website.

POST /api/ojs/sites/42/clone
Content-Type: application/json

{
"target_domain": "clone.example.com",
"subdirectory": "",
"source_db": "ojs_source",
"target_db": "",
"target_db_user": "",
"target_db_user_password": "",
"admin_email": "admin@example.com",
"ojs_version": ""
}
{"status": "success", "source": "example.com", "target": "clone.example.com", "source_path": "/var/www/html/example.com", "target_path": "/var/www/html/clone.example.com", "target_db": "ojs_d4e5f6"}

Cập nhật OJS​

Cập nhật OJS lên phiên bản mới nhất và chạy tools/upgrade.php upgrade của chính nó. Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới.

POST /api/ojs/sites/42/update
{"status": "Checking if existing installation processes are running.."}
{"status": "Downloading https://pkp.sfu.ca/ojs/download/ojs-3.5.0-5.tar.gz"}
{"status": "Running OJS upgrade (tools/upgrade.php upgrade)"}
{"status": "Update completed!", "version": "3.5.0-5"}

Xoá bộ nhớ đệm OJS​

Xoá thư mục cache/ của OJS.

POST /api/ojs/sites/42/cache
{"message": "Caches purged successfully!"}

Gỡ cài đặt OJS​

Xoá cơ sở dữ liệu và người dùng, xoá mọi tệp, gỡ cron job tác vụ định kỳ, và gỡ nó khỏi Trình quản lý website.

DELETE /api/ojs/sites/42

WordPress​

Liệt kê mọi bản cài WordPress​

GET /api/wordpress

Cài WordPress​

Truyền trực tiếp các sự kiện tiến trình JSON phân tách bằng dòng mới khi việc cài đặt chạy (tải về, giải nén, thiết lập cơ sở dữ liệu, wp core install, các bộ plugin/giao diện) — cùng luồng cài đặt như trang cài đặt của chính panel, chỉ khác là lấy từ phần thân JSON này thay vì một form post.

POST /api/wordpress/install
Content-Type: application/json

{
"domain_id": "42",
"admin_email": "admin@example.com",
"website_name": "My Blog",
"admin_username": "admin",
"admin_password": "changeme",
"wordpress_version": "latest",
"db_prefix": "wp_"
}
{"status": "Downloading https://wordpress.org/wordpress-latest.tar.gz"}
{"status": "Extracting files to /var/www/html/example.com"}
{"status": "Creating database wp_a1b2c3 and user wp_d4e5f6"}
{"status": "Importing WordPress tables in the database"}
{"status": "WordPress installation completed!"}

domain_id, admin_username và admin_password là bắt buộc; mọi thứ khác dùng giá trị sinh tự động (tên/người dùng/mật khẩu cơ sở dữ liệu ngẫu nhiên, tiền tố wp_, phiên bản latest).

Nhân bản một website WordPress​

POST /api/wordpress/clone
Content-Type: application/json

{
"source_domain": "example.com",
"target_domain": "clone.example.com",
"source_db": "wp_source",
"source_folder": ""
}

source_domain, target_domain, source_db và source_folder là bắt buộc; target_db/target_db_user/target_db_user_password mặc định là giá trị sinh tự động nếu bỏ qua.

Quét các bản cài chưa được theo dõi​

Tìm các bản cài WordPress trên đĩa chưa được đăng ký trong WP Manager và thêm chúng vào. Khác với POST /api/wordpress/reload bên dưới, vốn chỉ làm mới thông tin của các bản cài đã được theo dõi.

POST /api/wordpress/scan
{"message": "Scan completed", "installations": [{"config_file": "example.com/wp-config.php", "domain": "example.com", "admin_email": "admin@example.com", "version": "6.7"}], "count": 1}

Liệt kê bản sao lưu​

GET /api/wordpress/example.com/backups
{
"domain": "example.com",
"backups": [
{"date": "2025-01-15_12-00-00", "hasDbBackup": true, "hasFilesBackup": true}
]
}

Tạo bản sao lưu​

POST /api/wordpress/example.com/backups
Content-Type: application/json

{"backup_database": true, "backup_files": true}
{"message": "Backup completed successfully", "timestamp": "2025-01-15_12-00-00"}

Khôi phục một bản sao lưu​

POST /api/wordpress/example.com/restore
Content-Type: application/json

{"backup_date": "2025-01-15_12-00-00"}
{"message": "Backup restored: files and database", "restored": ["files", "database"]}

Liệt kê các quy tắc tăng cường bảo mật có sẵn​

GET /api/wordpress/secure
{"rules": ["wp_manager_xmlrpc", "wp_manager_user_enum", "wp_manager_wlwmanifest"]}

Lấy các quy tắc tăng cường bảo mật đang bật​

GET /api/wordpress/example.com/secure

Áp dụng quy tắc tăng cường bảo mật​

PUT /api/wordpress/example.com/secure
Content-Type: application/json

{"rules": ["wp_manager_xmlrpc", "wp_manager_wlwmanifest"], "disable_all": false}

Tắt mọi quy tắc:

PUT /api/wordpress/example.com/secure
Content-Type: application/json

{"disable_all": true}

Gỡ cài đặt WordPress​

Xoá tệp và xoá cơ sở dữ liệu. Lưu ý đường dẫn là /api/wordpress/sites/<id> (sites.id dạng số, không phải tên miền).

DELETE /api/wordpress/sites/42

Tách khỏi Trình quản lý WordPress​

Gỡ khỏi trình quản lý, giữ nguyên tệp.

POST /api/wordpress/sites/42/detach

Nạp lại dữ liệu WP từ hệ thống tệp​

Quét lại /var/www/html tìm các tệp wp-config.php và làm mới siêu dữ liệu website.

POST /api/wordpress/reload

Hành động WP-CLI​

Các hành động có sẵn: 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.",
"stderr": "",
"returncode": 0
}

Ứng dụng Node.js / Python (PM2)​

Theo dõi nhật ký ứng dụng​

GET /api/pm2/example.com/logs?lines=100

Khởi động / dừng / khởi động lại ứng dụng​

Khởi động lại sẽ kéo image mới nhất về trước.

POST /api/pm2/example.com/start
POST /api/pm2/example.com/stop
POST /api/pm2/example.com/restart

Cập nhật cài đặt ứng dụng​

Có thể gửi bất kỳ trường nào trong version, requirements, startup_file, custom_cmd, workdir, cpu, ram.

PATCH /api/pm2/example.com
Content-Type: application/json

{
"version": "20",
"startup_file": "/var/www/html/index.js",
"cpu": "1",
"ram": "1"
}

Xoá ứng dụng​

Dừng container, hoàn lại cấu hình máy chủ web, gỡ dịch vụ khỏi docker-compose.yml, và xoá nó khỏi cơ sở dữ liệu.

DELETE /api/pm2/example.com

Cài một ứng dụng mới​

Tạo ứng dụng (các endpoint ở trên sau đó quản lý nó). Phần thân yêu cầu dạng form-encoded (không phải JSON), và phản hồi truyền trực tiếp các sự kiện trạng thái/lỗi JSON phân tách bằng dòng mới khi việc cài đặt tiến hành, thay vì một đối tượng JSON duy nhất.

domain_id và service_name là bắt buộc. Tuỳ chọn: startup_file, cpu_limit, mem_limit, port, subdirectory, version (mặc định latest), custom_cmd, requirements, git_repo_url.

POST /api/nodejs/install
Content-Type: application/x-www-form-urlencoded

domain_id=12&service_name=myapp&version=20&startup_file=index.js
POST /api/python/install
Content-Type: application/x-www-form-urlencoded

domain_id=12&service_name=myapp&version=3.12&startup_file=app.py
{"status": "Checking if existing installation processes are running.."}
{"status": "Validating provided data"}
{"status": "Service added successfully", "success": true}
{"status": "Starting docker container.."}

Trợ giúp​

Các endpoint tiện ích nhỏ phục vụ các form cài đặt Node.js/Python.

Lấy các phiên bản runtime có sẵn​

type là nodejs hoặc python. Chuyển tiếp nguồn phát hành của endoflife.date, lưu đệm 24 giờ.

GET /api/docker/tags/nodejs

Kiểm tra một tệp có tồn tại trong docroot của ứng dụng không​

Chỉ kiểm tra các tệp .py và .js.

POST /api/helpers/check-file-exists
Content-Type: application/json

{"file": "app.py"}
{"file": "app.py", "exists": true}

Phát hiện tệp khởi động của một kho Git​

Clone kho để phát hiện điểm vào của nó (main trong package.json, hoặc các tên tệp thông dụng như index.js/app.py).

POST /api/helpers/detect-git-startup-file
Content-Type: application/json

{"git_repo_url": "https://hitechcloud.org", "app_type": "nodejs"}
{"startup_file": "index.js"}

Trình cài đặt tự động​

Liệt kê các ứng dụng đã cài​

GET /api/autoinstaller
{
"sites": [{"site_name": "example.com", "type": "WordPress"}],
"counts": {"wordpress": 1, "sitebuilder": 0, "node": 0, "python": 0},
"technologies": ["wordpress", "sitebuilder", "node", "python"],
"domain_count": 1
}

DNS động​

Liệt kê mọi mục​

GET /api/dynamic-dns
{
"domains": {
"example.com": [
{"line_number": 14, "subdomain": "home", "ttl": "300", "type": "A", "record": "1.2.3.4", "token": "abc123xyz", "last_updated": "2025-01-15T12:00:00Z", "raw_line": "home 300 IN A 1.2.3.4 ; webcall=abc123xyz updated=2025-01-15T12:00:00Z"}
]
}
}

Tạo mục​

POST /api/dynamic-dns
Content-Type: application/json

{"domain": "example.com", "subdomain": "home", "ip": "0.0.0.0"}
{"message": "Dynamic DNS entry created", "entry": {"subdomain": "home", "record": "0.0.0.0", "type": "A", "token": "abc123xyz"}}

Cập nhật mục​

domain, line_number, subdomain, ip và token đều bắt buộc.

PUT /api/dynamic-dns
Content-Type: application/json

{
"domain": "example.com",
"line_number": 14,
"subdomain": "home",
"ip": "1.2.3.4",
"token": "abc123xyz"
}

Xoá mục​

DELETE /api/dynamic-dns
Content-Type: application/json

{"domain": "example.com", "line_number": 14}

Tự động cập nhật IP (không cần xác thực)​

Được router hoặc ứng dụng DDNS của bạn gọi để cập nhật bản ghi bằng IP của bên gọi:

GET /dynamic-dns/update?token=abc123xyz

Trình sửa vùng DNS​

Một trình sửa vùng độc lập tại /api/dns/..., tách biệt với các endpoint DNS theo phạm vi tên miền dưới /api/domains/<domain>/dns.... Hai nhóm trùng nhau về mục đích nhưng dùng tên trường khác nhau — nhóm này trả về các bản ghi đã phân tích với line/multiline (không phải record), và bản ghi mới dùng trường record (không phải value).

Liệt kê tên miền kèm trạng thái vùng​

GET /api/dns
{"domains": [{"domain_id": 1, "domain_url": "example.com", "zone_file_exists": true}]}

Lấy các bản ghi DNS đã phân tích​

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}
],
"validation_error": null
}

Lấy tệp vùng thô​

GET /api/dns/example.com/raw

Lưu tệp vùng thô​

PUT /api/dns/example.com/raw
Content-Type: application/json

{"content": "$ORIGIN example.com.\n$TTL 3600\n..."}

Thêm một bản ghi DNS​

POST /api/dns/example.com/records
Content-Type: application/json

{"name": "www", "ttl": "3600", "type": "A", "record": "1.2.3.4"}

Ví dụ MX:

{"name": "example.com.", "ttl": "3600", "type": "MX", "priority": "10", "record": "mail.example.com."}

Ví dụ TXT / SPF:

{"name": "example.com.", "ttl": "3600", "type": "TXT", "record": "v=spf1 include:_spf.example.com ~all"}

Cập nhật một bản ghi theo số dòng​

PATCH /api/dns/example.com/records/12
Content-Type: application/json

{"content": "www 3600 IN A 5.6.7.8", "serial": "2025011501"}

Trường serial ngăn xung đột khi sửa đồng thời — hãy truyền serial bạn đã đọc khi lấy vùng.

Xoá một bản ghi​

DELETE /api/dns/example.com/records/12

Bản ghi nhiều dòng (ví dụ DKIM):

DELETE /api/dns/example.com/records/15
Content-Type: application/json

{"end_row_id": 18}

Đặt lại vùng về mẫu mặc định​

POST /api/dns/example.com/reset

Xuất tệp vùng​

Khác với bản xuất theo phạm vi tên miền (truyền trực tiếp một tệp để tải xuống), endpoint này trả nội dung vùng dưới dạng JSON.

GET /api/dns/example.com/export
{"domain": "example.com", "content": "$ORIGIN example.com.\n...", "filename": "example.com.zone"}

Thống kê lưu lượng (GoAccess)​

Liệt kê tên miền kèm tình trạng sẵn có thống kê​

GET /api/stats
{"domains": [{"domain_url": "example.com", "has_stats": true}]}

Lấy báo cáo GoAccess của một tên miền​

GET /api/stats/example.com
{
"domain": "example.com",
"available": true,
"html": "<!DOCTYPE html>..."
}

Thống kê được daemon GoAccess sinh mỗi 24 giờ.


Dịch vụ hệ thống​

Liệt kê mọi dịch vụ​

GET /api/services
{
"services": [
{"service": "nginx", "container_state": "running", "health_status": "healthy"},
{"service": "mysql", "container_state": "running", "health_status": "healthy"}
]
}

Lấy trạng thái dịch vụ​

GET /api/services/nginx
{
"service": "nginx",
"container_state": "running",
"health_status": "healthy",
"available_actions": ["disable"]
}

Khởi động / dừng / khởi động lại một dịch vụ​

POST /api/services/nginx
Content-Type: application/json

{"action": "enable"}
{"message": "Service nginx enabled successfully", "service": "nginx", "container_state": "running", "health_status": "healthy"}

Webmail​

Lấy thông tin webmail​

GET /api/webmail
{"is_running": true, "webmail_url": "https://webmail.example.com/"}

Tạo token tự động đăng nhập​

Tạo một token dùng một lần để tự động đăng nhập Roundcube.

POST /api/webmail/user@example.com
{
"email": "user@example.com",
"token": "abc123...",
"autologin_url": "https://webmail.example.com/autologin.php?token=abc123...",
"webmail_url": "https://webmail.example.com/"
}

Trình tạo website​

Lấy nội dung HTML và CSS​

GET /api/website-builder/example.com
{
"domain": "example.com",
"docroot": "/var/www/html",
"html": "<!DOCTYPE html>...",
"css": "* { box-sizing: border-box; }"
}

Lưu nội dung​

PUT /api/website-builder/example.com
Content-Type: application/json

{
"html": "<!DOCTYPE html><html>...</html>",
"css": "body { margin: 0; }"
}

Tạo một website mới​

POST /api/website-builder
Content-Type: application/json

{"domain_id": 1, "subdirectory": ""}
{"message": "Website created successfully on example.com", "site_name": "example.com"}

Gỡ một website (xoá tệp)​

DELETE /api/website-builder/sites/7

Tách một website (giữ tệp)​

POST /api/website-builder/sites/7/detach

Bảng điều khiển​

Widget mức sử dụng tài nguyên​

Cùng dữ liệu mà widget mức sử dụng trực tiếp của bảng điều khiển hỏi liên tục.

GET /api/dashboard/resource-usage
{
"cpu": {"usage": {"pct": 26, "human": "0.3 cores"}, "total": {"pct": 800, "human": "8.0 cores"}},
"memory": {"usage_pct": 11, "used": {"human": "723.5M"}, "total": {"human": "6.0G"}},
"bandwidth": {"usage_pct": 0, "total_sent": {"human": "0bit"}},
"tasks": {"current": 220, "limit": 900, "usage_pct": 24},
"uid": 1001, "user": "myuser", "timestamp": "2026-01-15T12:00:00Z"
}

Widget dung lượng đĩa / inode​

GET /api/dashboard/disk-inodes
{"inodes_used": 87581, "inodes_soft": 1000000, "inodes_hard": 1000000, "disk_used": 2838644, "disk_soft": 51200000, "disk_hard": 51200000, "device": "/home/myuser/", "date": "2026-01-15T12:00:00Z"}

Đánh dấu đã hoàn thành chuyến tham quan làm quen​

POST /api/dashboard/tour/complete
{"ok": true}

Plugin​

Chỉ có mặt nếu máy chủ đã cài ít nhất một plugin (nếu không GET /api/endpoints sẽ không liệt kê nó).

Liệt kê các plugin đã cài​

GET /api/plugins
{"plugins": [{"name": "example-plugin", "..."}]}

Phục vụ ô tìm kiếm của thanh bên. what chọn loại thực thể; một số loại bị chặn sau cờ tính năng riêng hoặc giấy phép Enterprise (403 nếu không có).

GET /api/search/domains
GET /api/search/mysql_databases
GET /api/search/files?q=index&folder=&ext=.php
[{"name": "example.com", "link": "/domains"}]

Các giá trị what được hỗ trợ: files, folders, features, websites, mysql_databases, mysql_users, postgresql_databases, postgresql_users, domains, emails, ftp, containers, services, crons.


Khảo sát API​

Liệt kê mọi tuyến /api/* hiện đang được đăng ký trên máy chủ (tức là thực sự có sẵn với bản dựng đang chạy và các mô-đun đã bật), kèm (các) phương thức HTTP của từng tuyến. Hữu ích để khám phá những gì có sẵn mà không phải dựa vào tài liệu này.

GET /api/endpoints
{
"endpoints": [
{"path": "/api/account", "methods": ["GET"]},
{"path": "/api/mysql/databases", "methods": ["GET", "POST"]}
],
"total": 317
}

Phản hồi lỗi​

Mọi endpoint đều trả về mã trạng thái HTTP chuẩn:

MãÝ nghĩa
200OK
201Đã tạo
202Đã chấp nhận (thao tác bất đồng bộ đã bắt đầu)
400Yêu cầu sai / thiếu trường bắt buộc
401Chưa xác thực (thiếu hoặc sai token)
403Bị cấm (tính năng chưa bật hoặc tên miền không thuộc sở hữu)
404Không tìm thấy tài nguyên
409Xung đột (ví dụ serial không khớp, tài nguyên đã tồn tại)
500Lỗi máy chủ nội bộ
503Dịch vụ không khả dụng
504Hết thời gian chờ

Phản hồi lỗi luôn có trường error:

{"error": "You do not own this domain"}