API: email
Mailboxes, passwords and quotas, forwarders, autoresponders, sending limits and email checks through the token API.
These endpoints manage one hosting account's email, like the Email accounts screen in Control Panel: the same checks, limits and messages, the same activity log lines, and the changes are made on the mail server at once.
A=https://api.yourdomain.com:2087/v1
H="Authorization: Bearer hf_xxx"
The path names the account (/v1/accounts/{username}/email/…); the rules are those of every
per-account endpoint. Addresses go in the path as they are, for example
/mailboxes/info@example.com (%40 for @ works too).
List mailboxes
GET /v1/accounts/{username}/email/mailboxes
{
"ok": true,
"data": [
{
"address": "info@example.com",
"quota_mb": 1024,
"used_mb": 12,
"send_only": false,
"created_at": "2026-05-02 09:30:11"
}
]
}
Create a mailbox
POST /v1/accounts/{username}/email/mailboxes. 201 with the mailbox and its password, shown only in this answer.
curl -s -X POST -H "$H" -H "Content-Type: application/json" \
-d '{"address":"info@example.com","quota_mb":1024}' $A/accounts/sarahbakes/email/mailboxes
| Field | What it does |
|---|---|
address |
required; the full address. The domain must be one of the account's, with email switched on |
password |
empty = a random one |
quota_mb |
0 = no limit; at most 102400 |
The package's mailbox limit applies ("Mailbox limit reached for this package."), and an address that is already a mailbox or a forwarder answers 422.
Change a password or quota
curl -s -X POST -H "$H" -H "Content-Type: application/json" -d '{"password":"Correct-Horse-9"}' \
$A/accounts/sarahbakes/email/mailboxes/info@example.com/password
curl -s -X POST -H "$H" -H "Content-Type: application/json" -d '{"quota_mb":2048}' \
$A/accounts/sarahbakes/email/mailboxes/info@example.com/quota
password empty makes a random one; the answer has address and password. The quota answer is the mailbox. PUT
works as well as POST.
Delete a mailbox
DELETE /v1/accounts/{username}/email/mailboxes/{address} deletes the mailbox and all its messages.
Autoresponder
Switch it on with POST (or PUT) and off with DELETE on /v1/accounts/{username}/email/mailboxes/{address}/autoresponder.
curl -s -X PUT -H "$H" -H "Content-Type: application/json" \
-d '{"subject":"Out of office","body":"Back on Monday.","days":1,"start":"2026-12-20","end":"2027-01-02"}' \
$A/accounts/sarahbakes/email/mailboxes/info@example.com/autoresponder
| Field | What it does |
|---|---|
subject, body |
required to switch it on |
days |
days before the same sender gets the reply again; default 1 |
start, end |
optional first and last day, YYYY-MM-DD |
The answer is {"address": "info@example.com", "autoresponder": true} (or false after DELETE).
Forwarders
curl -s -H "$H" $A/accounts/sarahbakes/email/forwarders
curl -s -X POST -H "$H" -H "Content-Type: application/json" \
-d '{"source":"sales@example.com","destinations":["sarah@example.net","team@example.net"]}' \
$A/accounts/sarahbakes/email/forwarders
curl -s -X DELETE -H "$H" $A/accounts/sarahbakes/email/forwarders/sales@example.com
{
"ok": true,
"data": {
"source": "sales@example.com",
"destinations": [
"sarah@example.net",
"team@example.net"
],
"created_at": "2026-05-02 09:31:40"
}
}
| Field | What it does |
|---|---|
source |
required; the address, or *@example.com for every address that has no mailbox or forwarder |
destinations |
required; 1–10 addresses, as a list or one text separated by commas |
Adding a forwarder for a source that already has one replaces its destinations.
Sending limits
GET /v1/accounts/{username}/email/limits — the emails per hour and per day that apply (0 = unlimited) and where
each comes from (account, package or server), the account's own values (null = the package's), what was sent
this hour and in the last 24 hours, whether sending is on hold, and the limit events of the last 24 hours.
curl -s -H "$H" $A/accounts/sarahbakes/email/limits
curl -s -X PUT -H "$H" -H "Content-Type: application/json" -d '{"per_hour":200,"per_day":null}' \
$A/accounts/sarahbakes/email/limits
curl -s -X POST -H "$H" $A/accounts/sarahbakes/email/limits/release
{
"ok": true,
"data": {
"per_hour": 200,
"per_day": 1000,
"per_hour_from": "account",
"per_day_from": "package",
"own_per_hour": 200,
"own_per_day": null,
"package_per_hour": 100,
"package_per_day": 1000,
"sent_hour": 12,
"sent_day": 340,
"refused_hour": 0,
"paused": false,
"held": false,
"events": []
}
}
Changing the limits (PUT or PATCH: per_hour, per_day; a field left out keeps its value) and
POST …/limits/release (let the account send again after a limit or a hold) need an administrator token. See
Sending limits.
Email checks
GET /v1/accounts/{username}/email/checks/{domain} runs the deliverability
checks of a mail domain: score (in %), dns_managed (this server runs the domain's DNS) and checks, each with
key (mx, spf, dkim, dmarc, ptr, tls, blacklist), status (pass, warn, fail), the message
(msg with args), the fix (fix with fixArgs), the record to add (name, type, value, or null) and auto
(it can be fixed here).
POST /v1/accounts/{username}/email/checks/{domain}/fix with {"check":"spf"} (or mx, dkim, dmarc; DMARC takes
report_to, the address for the reports) writes the record into this server's DNS zone. It answers 422 when the
check passes or the domain's DNS is run elsewhere.