API Reference
REST API documentation for managing domains, users, aliases, and services in CeyMail Mission Control.
CeyMail Mission Control exposes a REST API through its Next.js dashboard for managing domains, users, aliases, mail queues, services, and more. The API is used internally by the dashboard and is available to authenticated administrators.
Authentication
All API requests require a valid session cookie (mc-session). Sessions are created by logging in through the dashboard login page or the /api/auth/login endpoint.
# Log in and save the session cookie
curl -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "your-password"}' \
https://mc.example.com/api/auth/login
Include the session cookie in subsequent requests:
curl -b cookies.txt https://mc.example.com/api/domains
Session security
Sessions use HMAC-SHA256 signed tokens stored in httpOnly cookies with an 8-hour expiry. API requests that mutate data require a "fresh" session -- if your session has been active for too long, you may need to re-authenticate.
Base URL
https://mc.example.com/api
Replace mc.example.com with your actual dashboard domain. All endpoints return JSON. Successful responses use HTTP 200/201, errors use standard HTTP status codes with a JSON body containing an error field.
Rate limiting
API requests are rate-limited per IP address using a per-endpoint sliding window (1-minute intervals):
| Endpoint pattern | Rate limit |
|---|---|
POST /api/auth/login | 10 requests/minute |
POST /api/auth/setup | 5 requests/minute |
GET API endpoints | 120 requests/minute |
POST/PATCH/DELETE API endpoints | 5-30 requests/minute (varies by endpoint) |
Requests exceeding the rate limit receive HTTP 429.
Domains
List domains
# Paginated (default)
curl -b cookies.txt https://mc.example.com/api/domains
# Full list (for dropdowns/stats)
curl -b cookies.txt https://mc.example.com/api/domains?all=true
Paginated response:
{
"data": [
{
"id": 1,
"name": "example.com",
"created_at": "2026-02-10T14:30:00.000Z"
}
],
"total": 1,
"page": 1,
"pageSize": 20
}
Supports query parameters: page, pageSize, sort, dir (asc/desc), search.
Create domain
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"name": "newdomain.com"}' \
https://mc.example.com/api/domains
Response (HTTP 201):
{
"id": 2,
"name": "newdomain.com",
"created_at": "2026-02-10T15:00:00.000Z"
}
Delete domain
curl -b cookies.txt -X DELETE \
https://mc.example.com/api/domains?id=2
Response (HTTP 200):
{
"message": "Domain deleted successfully"
}
Cascading delete
Deleting a domain removes all associated users and aliases due to foreign key cascading. This action cannot be undone. If the domain has users or aliases, deletion may be blocked with a 409 Conflict.
Users (mailboxes)
List users
# Paginated with optional domain filter
curl -b cookies.txt "https://mc.example.com/api/users?domain=example.com"
# Full list
curl -b cookies.txt "https://mc.example.com/api/users?all=true"
Response:
{
"data": [
{
"id": 1,
"domain_id": 1,
"email": "john@example.com",
"created_at": "2026-02-10T14:35:00.000Z",
"domain_name": "example.com"
}
],
"total": 1,
"page": 1,
"pageSize": 20
}
Create user
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "SecureP@ssw0rd!",
"domain_id": 1
}' \
https://mc.example.com/api/users
Response (HTTP 201):
{
"id": 2,
"domain_id": 1,
"email": "jane@example.com",
"created_at": "2026-02-10T15:05:00.000Z",
"domain_name": "example.com"
}
The email domain must match the domain associated with domain_id. Mail user passwords are hashed using SSHA512 with a 16-byte random salt (Dovecot-compatible). Dashboard admin passwords use scrypt.
Update user password
curl -b cookies.txt -X PATCH \
-H "Content-Type: application/json" \
-d '{"id": 2, "password": "NewSecureP@ss!"}' \
https://mc.example.com/api/users
Delete user
curl -b cookies.txt -X DELETE \
https://mc.example.com/api/users?id=2
Aliases
List aliases
# Paginated with optional domain filter
curl -b cookies.txt "https://mc.example.com/api/aliases?domain=example.com"
# Full list
curl -b cookies.txt "https://mc.example.com/api/aliases?all=true"
Create alias
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{
"source": "info@example.com",
"destination": "john@example.com",
"domain_id": 1
}' \
https://mc.example.com/api/aliases
Response (HTTP 201):
{
"id": 1,
"source": "info@example.com",
"destination": "john@example.com",
"domain_id": 1,
"created_at": "2026-02-10T15:10:00.000Z",
"domain_name": "example.com"
}
Self-referencing aliases (source equals destination) are rejected to prevent mail loops.
Delete alias
curl -b cookies.txt -X DELETE \
https://mc.example.com/api/aliases?id=1
Mail queue
Get queue statistics
curl -b cookies.txt https://mc.example.com/api/queue
Response:
{
"active": 0,
"deferred": 2,
"hold": 0,
"bounce": 0,
"maildrop": 0,
"total": 2
}
List queue items
curl -b cookies.txt https://mc.example.com/api/queue/items
Flush queue
Force immediate delivery retry for all deferred messages:
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"action": "flush"}' \
https://mc.example.com/api/queue
Delete message from queue
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"action": "clear", "queueId": "A1B2C3D4E5"}' \
https://mc.example.com/api/queue
Clear entire queue
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"action": "clear"}' \
https://mc.example.com/api/queue
Services
List service statuses
curl -b cookies.txt https://mc.example.com/api/services
Response:
[
{
"name": "postfix",
"status": "running",
"uptime_seconds": 86400,
"uptime_formatted": "1d 0h 0m",
"memory_bytes": 52428800,
"pid": 1234
},
{
"name": "dovecot",
"status": "running",
"uptime_seconds": 86400,
"uptime_formatted": "1d 0h 0m",
"memory_bytes": 41943040,
"pid": 1235
}
]
Monitored services include: postfix, dovecot, mariadb, opendkim, spamassassin/spamd, spamass-milter, nginx/apache2, unbound, rsyslog, and ceymail-ai-filter.
Control a service
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"service": "postfix", "action": "restart"}' \
https://mc.example.com/api/services
Valid actions: start, stop, restart.
AI filter service
The ceymail-ai-filter service cannot be controlled through the services API. Use the Screening settings page or the /api/screening/config endpoint instead, which ensures the Postfix milter chain stays in sync.
DKIM
List DKIM keys
curl -b cookies.txt https://mc.example.com/api/dkim?all=true
Generate DKIM key for a domain
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}' \
https://mc.example.com/api/dkim
Error responses
All errors follow a consistent format:
{
"error": "Domain already exists"
}
| HTTP Status | Meaning |
|---|---|
| 400 | Invalid request body, parameters, or validation failure |
| 401 | Not authenticated or session expired |
| 403 | Insufficient permissions or stale session |
| 404 | Resource not found |
| 409 | Conflict (duplicate entry or foreign key constraint) |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Additional endpoints
The dashboard also exposes API routes for:
- Backup --
GET /api/backup(list),POST /api/backup(create),GET /api/backup/[id]/download - DNS --
GET /api/dns(check DNS records for all domains) - Logs --
GET /api/logs(dashboard audit logs),GET /api/logs/mail(mail server logs) - Screening --
GET/PATCH /api/screening/config,GET /api/screening/stats,GET /api/screening/logs - Settings --
GET/PATCH /api/settings(general settings),POST /api/settings/factory-reset - Updates --
GET /api/updates/check,POST /api/updates/apply,GET /api/updates/status - License --
GET/POST/DELETE /api/license - Relay --
GET/POST/DELETE /api/integrations/relay - Webmail --
GET /api/webmail(status),POST /api/webmail(setup/reconfigure) - Stats --
GET /api/stats(server health metrics)
License tiers
Some API features require a paid license. The Community tier (free) includes core mail management. Pro, Business, and Enterprise tiers unlock additional features like advanced queue management and higher domain/mailbox limits. See the Settings > License page in the dashboard for details.