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.

bash
# 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:

bash
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 patternRate limit
POST /api/auth/login10 requests/minute
POST /api/auth/setup5 requests/minute
GET API endpoints120 requests/minute
POST/PATCH/DELETE API endpoints5-30 requests/minute (varies by endpoint)

Requests exceeding the rate limit receive HTTP 429.

Domains

List domains

bash
# 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:

json
{
  "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

bash
curl -b cookies.txt -X POST \
  -H "Content-Type: application/json" \
  -d '{"name": "newdomain.com"}' \
  https://mc.example.com/api/domains

Response (HTTP 201):

json
{
  "id": 2,
  "name": "newdomain.com",
  "created_at": "2026-02-10T15:00:00.000Z"
}

Delete domain

bash
curl -b cookies.txt -X DELETE \
  https://mc.example.com/api/domains?id=2

Response (HTTP 200):

json
{
  "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

bash
# 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:

json
{
  "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

bash
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):

json
{
  "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

bash
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

bash
curl -b cookies.txt -X DELETE \
  https://mc.example.com/api/users?id=2

Aliases

List aliases

bash
# 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

bash
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):

json
{
  "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

bash
curl -b cookies.txt -X DELETE \
  https://mc.example.com/api/aliases?id=1

Mail queue

Get queue statistics

bash
curl -b cookies.txt https://mc.example.com/api/queue

Response:

json
{
  "active": 0,
  "deferred": 2,
  "hold": 0,
  "bounce": 0,
  "maildrop": 0,
  "total": 2
}

List queue items

bash
curl -b cookies.txt https://mc.example.com/api/queue/items

Flush queue

Force immediate delivery retry for all deferred messages:

bash
curl -b cookies.txt -X POST \
  -H "Content-Type: application/json" \
  -d '{"action": "flush"}' \
  https://mc.example.com/api/queue

Delete message from queue

bash
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

bash
curl -b cookies.txt -X POST \
  -H "Content-Type: application/json" \
  -d '{"action": "clear"}' \
  https://mc.example.com/api/queue

Services

List service statuses

bash
curl -b cookies.txt https://mc.example.com/api/services

Response:

json
[
  {
    "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

bash
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

bash
curl -b cookies.txt https://mc.example.com/api/dkim?all=true

Generate DKIM key for a domain

bash
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:

json
{
  "error": "Domain already exists"
}
HTTP StatusMeaning
400Invalid request body, parameters, or validation failure
401Not authenticated or session expired
403Insufficient permissions or stale session
404Resource not found
409Conflict (duplicate entry or foreign key constraint)
429Rate limit exceeded
500Internal 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.