API
REST API v1 — Public reference for billing integrations and custom automation (WHMCS, Blesta, HostBill, and similar). Covers accounts, domains, apps, databases, cron jobs, and SSO.
Base URL: {APP_URL}/api/v1
Examples: https://panel.example.com/api/v1 · http://203.0.113.10:8443/api/v1
Authentication: Bearer token with scoped abilities
Rate limit: 60 requests/minute per authenticated user (default)
Headers: send Authorization: Bearer YOUR_TOKEN, Accept: application/json, and Content-Type: application/json on write requests
Not in this API: backups, restore, FTP, file manager, terminal, phpMyAdmin — use the MetroPanel UI.
Current: Use GET /auth/me to verify API credentials (for example WHMCS TestConnection). Do not use public GET /health for token checks — it only proves the panel is reachable. Optional per-token IP allowlists can restrict which client IPs may call the API.
Authenticated endpoints require a Bearer token, the matching ability (where listed), and a passing IP allowlist when configured (empty = allow any IP). List endpoints are paginated (current_page, data, per_page, total, …). Packages list returns { "data": [...] } (not paginated).
Full request and response details are in the sections below.
| Method | Endpoint | Ability | Description |
GET
|
/health
|
public | Public liveness (does not check API tokens) |
GET
|
/auth/me
|
valid token | Authenticated connection / credential check (WHMCS TestConnection) |
GET
|
/sso/login/{user_id}
|
signed URL | SSO redirect (throttle 30/min) |
GET
|
/packages
|
packages:read
|
List packages |
GET
|
/packages/{id}
|
packages:read
|
Show package |
GET
|
/accounts
|
accounts:read
|
List accounts (?username= exact filter)
|
POST
|
/accounts
|
accounts:write
|
Create account |
GET
|
/accounts/check-username
|
accounts:read
|
Username availability (hosting + panel users) |
GET
|
/accounts/usage/bulk
|
accounts:read
|
Bulk resource usage (max 100 IDs) |
GET
|
/accounts/{id}
|
accounts:read
|
Show account (?include=apps,usage)
|
DELETE
|
/accounts/{id}
|
accounts:write
|
Terminate account |
PATCH
|
/accounts/{id}/suspend
|
accounts:write
|
Suspend account |
PATCH
|
/accounts/{id}/unsuspend
|
accounts:write
|
Unsuspend account |
PATCH
|
/accounts/{id}/password
|
accounts:write
|
Change account password |
PATCH
|
/accounts/{id}/package
|
accounts:write
|
Change package |
PATCH
|
/accounts/{id}/resources
|
accounts:write
|
Update resource / feature limits |
GET
|
/accounts/{id}/usage
|
accounts:read
|
Resource usage |
POST
|
/accounts/{id}/login-link
|
accounts:write
|
SSO login URL (optional deep-link target)
|
GET
|
/domains
|
domains:read
|
List domains |
POST
|
/domains
|
domains:write
|
Add domain |
GET
|
/domains/{id}
|
domains:read
|
Show domain |
DELETE
|
/domains/{id}
|
domains:write
|
Remove domain |
POST
|
/domains/{id}/ssl
|
domains:write
|
Install SSL |
GET
|
/app-templates
|
apps:read
|
List installable app templates |
GET
|
/apps
|
apps:read
|
List apps (paginated summary) |
POST
|
/apps
|
apps:write
|
Install app |
GET
|
/apps/{id}
|
apps:read
|
Show app |
DELETE
|
/apps/{id}
|
apps:write
|
Remove app |
POST
|
/apps/{id}/deploy-zip
|
apps:write
|
Deploy ZIP into PHP / Node / Static app |
POST
|
/apps/{id}/deploy-git
|
apps:write
|
Git pull+rebuild (Node git-sourced apps) |
GET
|
/databases
|
databases:read
|
List databases |
POST
|
/databases
|
databases:write
|
Create database |
GET
|
/databases/{id}
|
databases:read
|
Show database (db_password never returned)
|
DELETE
|
/databases/{id}
|
databases:write
|
Remove database |
PATCH
|
/databases/{id}/password
|
databases:write
|
Reset DB password |
POST
|
/databases/{id}/allowed-ips
|
databases:write
|
Allow remote MySQL IP |
DELETE
|
/databases/{id}/allowed-ips/{ip}
|
databases:write
|
Revoke remote MySQL IP |
GET
|
/cron-jobs
|
cron:read
|
List cron jobs |
POST
|
/cron-jobs
|
cron:write
|
Create cron job |
GET
|
/cron-jobs/{id}
|
cron:read
|
Show cron job |
PATCH
|
/cron-jobs/{id}
|
cron:write
|
Update cron job |
DELETE
|
/cron-jobs/{id}
|
cron:write
|
Remove cron job |
Async operations: Database create/remove, domain removal, app install, and account termination may complete asynchronously. Poll the resource or list endpoints if status is pending.
All API requests (except the public health check and the signed SSO login URL) require a Bearer token:
Create an API token
- Sign in to MetroPanel as an admin or reseller
- Open Security → API Tokens
- Enter a name (optional IP allowlist), then create — the plain-text token is shown once; store it securely
Token presets (panel UI):
| Preset | What it can do | Typical use |
| Read only | View only — list accounts, packages, domains, apps, databases, and cron. Cannot create, change, or delete anything. | Monitoring / dashboards, reporting or sync scripts that only pull status, safer testing without write risk |
| Provisioning | Accounts, packages, domains, apps, databases (read + write) | WHMCS / billing automation |
| Full access |
Same as Provisioning + cron management (cron:read / cron:write)
|
Integrations that also manage cron jobs |
Read only is for viewing data only — it cannot create, change, or delete anything. Prefer it for monitoring, reporting, or connection checks when you do not need writes.
For WHMCS module setup (username/password fields, Provisioning preset, and IP pinning), see WHMCS Module.
Access scope: The token acts as the owning user. Admins see all accounts; resellers see accounts they manage. Abilities control which endpoints work; visibility controls which records are returned.
Per-token IP allowlist
You can optionally restrict a token so only listed client IPs may use it. This applies to all authenticated API calls, including GET /auth/me.
- Empty — allow any client IP (default)
- Set — up to 20 IPv4 / IPv6 / CIDR entries (comma, space, or semicolon separated)
-
Denied — HTTP
403withThis API token is not allowed from your IP address.
Configure the allowlist when creating the token under Security → API Tokens.
Examples: 203.0.113.10, 10.0.0.0/24, 2001:db8::/32.
Most endpoints require a matching ability on the token. GET /auth/me only needs a valid token (any abilities).
| Ability | Endpoints |
| (any valid token) |
GET /auth/me
|
accounts:read
|
GET /accounts, GET /accounts/check-username, GET /accounts/usage/bulk, GET /accounts/{id}, GET /accounts/{id}/usage
|
accounts:write
|
Create, delete, suspend, unsuspend, password, package, resources, login-link |
packages:read
|
GET /packages, GET /packages/{id}
|
domains:read
|
GET /domains, GET /domains/{id}
|
domains:write
|
Create, delete, install SSL |
apps:read
|
GET /apps, GET /apps/{id}, GET /app-templates
|
apps:write
|
Install, remove, ZIP/Git deploy |
databases:read
|
GET /databases, GET /databases/{id}
|
databases:write
|
Create, delete, reset password, allowed IPs |
cron:read
|
GET /cron-jobs, GET /cron-jobs/{id}
|
cron:write
|
Create, update, delete |
*
|
Full ability pass (wildcard) |
Missing ability response:
-
Authenticated endpoints: 60 requests per minute per user (default), including
GET /auth/me -
Public
GET /health: 60/min - SSO login URL: 30/min
When exceeded, the API returns 429 Too Many Requests.
GET /health (Public) — Check if panel is running
No authentication required. Use this only to verify the panel process is reachable. It does not validate API tokens — a revoked or fake Bearer token still returns 200. For credential checks (WHMCS TestConnection), call GET /auth/me instead.
Response
GET /auth/me (Auth) — Verify API token (WHMCS TestConnection)
Requires a valid Bearer token and a passing IP allowlist (if configured). No special ability is required. Invalid or revoked tokens return 401. Disallowed client IP returns 403.
Example
Response
All errors return appropriate HTTP status codes with a JSON body:
| Status | Meaning | Example |
401
|
Unauthenticated | Missing or invalid token |
403
|
Forbidden | Missing token ability, policy denial, unauthorized package/app, or token IP allowlist denial |
404
|
Not Found | Resource does not exist or not visible to token |
422
|
Validation / business rule error | Invalid FQDN, cron metacharacters, quota exceeded |
429
|
Too Many Requests | API rate limit exceeded (default 60/min) |
500
|
Server Error | Unexpected server error |
IP allowlist denial example:
Validation Error Response
Typical account-create validation failures: username already used (hosting or panel user), invalid package, weak password. Contact email is not rejected for “already taken” when reused across end-user accounts.
General Error Response
Service Error Response (422)
Some endpoints (databases, cron) return a simple error object for business-rule failures:
For WHMCS provisioning, use the official module guide: WHMCS Module.
For Packages, Accounts, Domains, Apps, Databases, Cron, and related endpoints, see API Reference.