API: firewall rules, IP blocker, cron runs and capacity
Read and set a website's firewall rules, block addresses on every website of an account, read cron job runs or run a job now, and get the server's capacity forecast.
These endpoints do what the Firewall rules, Cron jobs and Capacity forecast screens do, with the same checks and activity log lines.
A=https://api.yourdomain.com/v1
H="Authorization: Bearer hf_xxx"
The per-account paths follow the rules of every per-account endpoint: a customer's token reaches only its own account, a reseller's only its customers'.
Firewall rules
| Method and path | What it does |
|---|---|
GET /accounts/{username}/firewall-rules |
every website of the account with its rules |
GET /accounts/{username}/firewall-rules/{domain} |
one website's rules |
PUT /accounts/{username}/firewall-rules/{domain} |
set them; fields left out keep their value (needs a "Read & change" token) |
DELETE /accounts/{username}/firewall-rules/{domain} |
switch every rule off |
GET /accounts/{username}/firewall-rules/{domain}/log |
refused requests: a summary and the newest 50 |
curl -s -X PUT -H "$H" -H "Content-Type: application/json" \
-d '{"block":["203.0.113.0/24"],"login_limit":true,"paths":["/wp-login.php","/xmlrpc.php"],"rate":10,"bot":"suspicious"}' \
$A/accounts/sarahbakes/firewall-rules/example.com
| Field | Type | What it is |
|---|---|---|
allow, block |
list | IP addresses or ranges (CIDR), up to 500 each |
only_allowed |
boolean | only the allowed addresses may open the website |
countries |
list | blocked countries, two-letter codes |
login_limit |
boolean | limit requests to the paths |
rate |
integer | requests per minute and visitor: 5, 10, 20 or 60 |
bot |
string | off, suspicious or all |
crawlers, verify_crawlers |
boolean | let known search engine crawlers through, only after checking their reverse DNS |
A website the web server refuses keeps its old rules and the answer is an error.
IP blocker
Addresses and ranges blocked on every website of the account, on top of each website's own rules, each with an optional note and expiry. An address on a website's allowed list still gets through there.
| Method and path | What it does |
|---|---|
GET /accounts/{username}/ip-blocker |
the blocked addresses, oldest first (expired ones are left out) |
POST /accounts/{username}/ip-blocker |
block an address or range; answers 201 with the entry and its Location |
DELETE /accounts/{username}/ip-blocker/{id} |
unblock it |
curl -s -X POST -H "$H" -H "Content-Type: application/json" \
-d '{"cidr":"203.0.113.0/24","note":"login attempts","expires":"7d"}' \
$A/accounts/sarahbakes/ip-blocker
| Field | Type | What it is |
|---|---|---|
cidr |
string | required: an address or range (IPv4 /8 or smaller, IPv6 /16 or smaller); 500 at most per account |
note |
string | up to 200 characters |
expires |
string | 1h, 1d, 7d, 30d or never (the default) |
confirm |
boolean | block it even though it covers the address the request comes from |
{ "ok": true, "data": { "id": 4, "cidr": "203.0.113.0/24", "note": "login attempts",
"expires_at": "2026-11-09 10:00:00", "created_at": "2026-11-02 10:00:00" } }
An address already on the list, too wide a range or your own address without confirm answers 422 with the
reason in error (and field: "cidr" in the error object).
Cron job runs
| Method and path | What it does |
|---|---|
GET /accounts/{username}/cron-jobs/{id}/runs |
the job's monitor state and its last 50 runs (start, end, duration, exit code, output) |
POST /accounts/{username}/cron-jobs/{id}/run |
run the job now as the account (2 minutes at most); answers the run |
{ "ok": true, "data": { "started_at": 1793000000, "ended_at": 1793000004, "duration": 4, "code": 0,
"output": "Done\n", "truncated": false, "manual": true } }
Capacity forecast
GET /server/capacity (administrator tokens) answers every resource (disk:/, inodes:/, mem, load) with its
use, days_left (-1 when it is not running out), growth per day and a 30-day chart, plus the accounts growing fastest.