API: packages and resellers
Create, change and delete hosting packages, and create, suspend, limit and delete resellers through the token API.
These endpoints manage the hosting packages and the resellers. They do exactly what the Packages and Resellers screens in Server Admin do, with the same checks and messages, and each change is written to the activity log.
A=https://api.yourdomain.com:2087/v1
H="Authorization: Bearer hf_xxx"
| Endpoint | Who |
|---|---|
GET /v1/packages, GET /v1/packages/{package} |
administrator and reseller tokens |
POST, PATCH, PUT and DELETE on packages |
administrator tokens, Read & change |
every /v1/resellers endpoint |
administrator tokens; changes need Read & change |
A reseller's token gets 403 "Only administrator tokens can do this." for a change: resellers use the packages the
administrator makes. {package} is the package's id or its name (any case).
List and read packages
curl -s -H "$H" $A/packages
curl -s -H "$H" $A/packages/Starter
The answer is the package object, or a list of them, cheapest first. An unknown package answers 404 "No such package."
Create a package
POST /v1/packages. 201 with the new package.
curl -s -X POST -H "$H" -H "Content-Type: application/json" \
-d '{"name":"Business","disk_mb":20480,"max_domains":10,"max_databases":20,"max_mailboxes":50,"price_month":9.99}' \
$A/packages
| Field | What it does |
|---|---|
name |
required; up to 40 characters, not used by another package |
disk_mb |
disk space in MB; stored in whole GB (rounded); 0 = no limit. disk_gb works too |
max_domains, max_databases, max_mailboxes |
0 = no limit |
max_mongo_databases |
MongoDB databases, 0–1000 |
price_month |
the monthly price; a paid package is sent to Stripe when Stripe billing is on |
cpu |
CPU cores, 0.1 or more; 0 = no limit |
memory_mb, max_procs |
at least 128 MB and 20 processes; 0 = no limit |
redis_mb |
16–8192 MB; 0 = none |
mail_hour |
emails sent per hour; 0 = no limit |
max_docker, trial_days, max_files, team_members, webdisk_users |
as on the Packages screen |
io_mbps, iops |
disk speed and operations a second; 0 = no limit |
feature_list |
the id of a feature list; 0 = every feature |
Fields you leave out get the screen's defaults (5 GB, 1 domain, 2 databases, 5 mailboxes and so on). A bad value answers 422 with the screen's message, for example "Memory: at least 128 MB, or 0 for no limit."
Note: when the package was saved but Stripe could not be updated, the answer is still 200 or 201 and has
"warnings": ["Saved, but Stripe was not updated: …"].
Change a package
PATCH /v1/packages/{package} (or PUT). Send only the fields to change; the others keep their value. The new
limits go to every account on the package at once.
curl -s -X PATCH -H "$H" -H "Content-Type: application/json" -d '{"price_month":12.5}' $A/packages/Business
Delete a package
DELETE /v1/packages/{package}. A package that accounts still use answers 422 "Move accounts off this package
before deleting it."
{
"ok": true,
"data": {
"deleted": "Business"
}
}
List and read resellers
curl -s -H "$H" $A/resellers
curl -s -H "$H" $A/resellers/rosa
{
"ok": true,
"data": {
"username": "rosa",
"email": "rosa@example.com",
"status": "active",
"max_accounts": 25,
"accounts": 12,
"approval": "default",
"created_at": "2026-03-01 10:12:00"
}
}
| Field | What it is |
|---|---|
max_accounts |
how many hosting accounts the reseller may make; 0 = no limit |
accounts |
their customers now |
approval |
default, on or off: whether their deletes and whole restores wait for an administrator's approval |
Create a reseller
POST /v1/resellers. 201 with the reseller and its password, shown only in this answer.
curl -s -X POST -H "$H" -H "Content-Type: application/json" \
-d '{"username":"rosa","email":"rosa@example.com","max_accounts":25,"welcome":true}' $A/resellers
| Field | What it does |
|---|---|
username |
required; 3–16 lower-case letters and numbers, starting with a letter |
email |
required |
password |
empty = a random one |
max_accounts |
0 = no limit |
welcome |
true emails them the welcome message with their sign-in details |
Suspend, unsuspend and limit a reseller
curl -s -X POST -H "$H" $A/resellers/rosa/suspend
curl -s -X POST -H "$H" $A/resellers/rosa/unsuspend
curl -s -X PUT -H "$H" -H "Content-Type: application/json" -d '{"max_accounts":50}' $A/resellers/rosa/limit
A suspended reseller cannot sign in and their tokens stop working; their customers' websites keep working. Each answers with the reseller.
Delete a reseller
DELETE /v1/resellers/{username}. Their customers move to the administrator. When deleting a reseller needs a
second administrator's approval, the answer is 403 and you do it in Server Admin, where it is sent for
approval (see Approvals).