Appearance
Emails API
All endpoints require a bearer token (a login JWT or an API key).
INFO
Email hosting is offered on request - contact us before using these endpoints.
Mailboxes live on a domain you have already verified. If the domain's ownership is not verified yet, creating a mailbox returns 400 asking you to publish the verify-domain TXT record first. See the Domains API.
The email object
json
{
"uuid": "mbx_abc123",
"email": "hello@example.com",
"domainName": "example.com",
"storageSize": 5,
"status": "ACTIVE",
"alias": "",
"catchAll": 0,
"diskUsage": 20971520,
"serverId": "srv_mail_1",
"createdAt": "2026-07-01T12:00:00Z",
"updatedAt": null
}| Field | Meaning |
|---|---|
email | The full address. |
storageSize | Mailbox quota in GB (1 to 50). |
status | ACTIVE or DISABLED (you set these). SUSPENDED is set by us and locks the mailbox. |
alias | Forwarding target. Empty string means no forwarding. |
catchAll | 1 if this mailbox receives all mail sent to unknown addresses on the domain, else 0. |
diskUsage | Current usage in bytes. |
List mailboxes
http
GET /api/emails?domain=example.com&page=1&limit=20Paginated. The domain filter is optional.
Mailbox counts per domain
http
GET /api/emails/domainsReturns [{ "domainName": "example.com", "count": 3 }] for each domain that has at least one mailbox.
Create a mailbox
http
POST /api/emails/:domainNamejson
{
"email": "hello@example.com",
"password": "Sup3rSecret",
"storageSize": 5,
"serverId": "srv_mail_1"
}| Field | Type | Notes |
|---|---|---|
email | string | The full address. Its domain part must equal :domainName or you get 400. |
password | string | 8+ characters with an uppercase letter, a lowercase letter, and a digit. |
storageSize | number | Quota in GB, 1 to 50. |
serverId | string | Only required the first time you create a mailbox on the domain (it picks the email server). Omit it afterwards. |
Email addresses are globally unique, so a duplicate returns 400 "Email is already taken.".
Describe a mailbox
http
GET /api/emails/:domainName/:uuidUpdate a mailbox
http
PUT /api/emails/:domainName/:uuidEvery field is optional - send only what you want to change:
json
{
"password": "N3wPassword",
"alias": "team@example.com",
"catchAll": true,
"status": "DISABLED",
"storageSize": 10
}| Field | Type | Notes |
|---|---|---|
password | string | New password (same rules as create). |
alias | string | Forward a copy of incoming mail here. Send "" to clear it. Cannot equal the mailbox's own address. |
catchAll | boolean | Make this the catch-all for the domain. |
status | string | ACTIVE or DISABLED only. |
storageSize | number | New quota in GB, 1 to 50. |
Suspended mailboxes
A SUSPENDED mailbox rejects all edits (400 "Cannot update a suspended email"), and you cannot set SUSPENDED yourself - it is an account-level state we manage.
Delete a mailbox
http
DELETE /api/emails/:domainName/:uuidReturns 204. Irreversible.
Mailbox stats
http
GET /api/emails/:domainName/:uuid/mailbox-statsjson
{ "messageCount": 214, "lastSent": "2026-07-16T09:12:00Z", "lastReceived": "2026-07-17T06:44:00Z" }Set up email on a domain
http
POST /api/emails/:domainName/email-setupjson
{ "emailServerId": "srv_mail_1" }Turns on email for the domain and generates the DNS records you need to publish (all with TTL 300):
| Record | Host | Purpose | Required |
|---|---|---|---|
| MX | @ | Where mail is delivered | Yes |
| SPF | @ | Authorises our servers to send for you | Yes |
| DKIM | <id>._domainkey | Signs your outbound mail | Yes |
| DMARC | _dmarc | Reporting and policy | Recommended |
| SRV | _imaps._tcp | IMAP autodiscovery (993) | Recommended |
| SRV | _submission._tcp | SMTP submission autodiscovery (587) | Recommended |
Revalidate DNS
http
POST /api/emails/:domainName/revalidate-dnsRe-checks the published records on demand and updates each record's status. This is what the console's Recheck DNS button calls.
Regenerate DNS
http
POST /api/emails/:domainName/regenerate-dnsWipes and rebuilds the domain's email DNS records. This is what the console's Regenerate Records button calls.
Update your CNAME after regenerating
Regenerating rotates the DKIM key and also rotates the SSL validation delegation label, so the _acme-challenge CNAME record changes. Update that CNAME at your DNS provider after regenerating, or the next certificate renewal will fail.
Remove email setup
http
DELETE /api/emails/:domainName/email-setupStrips the email records and unassigns the email server. Ownership and SSL records are left alone. Returns 204.
Metrics
Sent / received / bounced counts at three scopes. Add ?from= and ?to= (RFC3339 or YYYY-MM-DD) to pick a window - the default is the last 7 days and the max range is 90 days.
| Endpoint | Scope |
|---|---|
GET /api/emails/:domainName/:uuid/metrics | Mailbox total |
GET /api/emails/:domainName/:uuid/metrics/daily | Mailbox, daily |
GET /api/emails/:domainName/metrics | Domain total |
GET /api/emails/:domainName/metrics/daily | Domain, daily |
GET /api/emails/metrics/account | Account total |
GET /api/emails/metrics/account/daily | Account, daily |
Totals return { "sent": 0, "received": 0, "bounced": 0 }. Daily variants return an array with a date on each row.
Unsubscribes
Every message you send carries a one-click unsubscribe link. When a recipient uses it, their address is added to your domain's suppression list and you stop sending to it.
http
GET /api/unsubscribes/:domainId?page=1&limit=20Paginated list of unsubscribed addresses on the domain. Each entry: { "id", "email", "domain", "domainId", "createdAt" }.
http
DELETE /api/unsubscribes/:domainId/:emailRemoves an address from the list, which re-enables sending to it. Returns 204. An invalid domain id returns 400 "Invalid domain ID".
curl example
Create a mailbox on example.com:
bash
curl -X POST https://cloud-api.microapps.io/api/emails/example.com \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "hello@example.com",
"password": "Sup3rSecret",
"storageSize": 5,
"serverId": "srv_mail_1"
}'