Kuju Email API Reference
Complete REST API documentation for integrating with Kuju Email. All endpoints return JSON and accept JSON request bodies.
Overview
Base URL
http(s)://<host>:8080http(s)://<host>:2525Authentication
Public endpoints require a JWT in the Authorization header:
Authorization: Bearer <token>Admin endpoints require is_admin=true in the JWT claims. Domain admin endpoints require is_domain_admin=true or site admin privileges.
Public API
Auth
/api/auth/login/api/auth/logout/api/auth/refresh/api/invite— accept invite and set password (public, token-based)/api/forgot-password— request password reset email/api/reset-password— reset password with tokenTwo-Factor Authentication (TOTP)
/api/auth/totp/status— check if TOTP is enabledJWT/api/auth/totp/setup— generate secret + QR codeJWT/api/auth/totp/confirm?session_id=...— verify code, enable TOTP, return backup codesJWT/api/auth/totp/verify— verify TOTP code during login, issue JWT/api/auth/totp— disable TOTP (requires current code)JWTFolders
/api/folders/api/folders/api/folders/:id/api/folders/:id/api/folders/:id/messagesMessages
/api/messages— compose / send/api/messages/:id/api/messages/:id/raw— raw RFC 822 source/api/messages/:id/body— rendered body/api/messages/:id/attachments/:aid— download attachment/api/messages/:id/flags— update flags (read, starred, etc.)/api/messages/:id/move/api/messages/:id/copy/api/messages/:id/api/messages/search— advanced search/api/messages/search?q=...— quick searchMessage Analysis
/api/messages/:id/analysis— cached results + feature availability/api/messages/:id/analysis/instant— header analysis (auth, sender, hops, URLs)/api/messages/:id/analysis/ai— AI threat assessment (?force=true to re-analyze)/api/messages/:id/analysis/av-rescan— ClamAV attachment scan/api/messages/:id/analysis/url-safety— Google Safe Browsing URL checkAttachment Knowledge
/api/messages/:id/attachments/:aid/knowledge— cached extraction result/api/messages/:id/attachments/:aid/knowledge— extract text + AI summarizeDrafts
/api/drafts/api/drafts/api/drafts/:id/api/drafts/:id/api/drafts/:id/api/drafts/:id/send— send a saved draftCalendars & Events
Calendars
/api/calendars— list calendars/api/calendars— create calendar/api/calendars/:id— update calendar/api/calendars/:id— delete calendarEvents
/api/calendars/:calId/events?start=...&end=...— list events (optional RFC 3339 range filter)/api/calendars/:calId/events/:id— get event/api/calendars/:calId/events— create event/api/calendars/:calId/events/:id— update event/api/calendars/:calId/events/:id— delete eventAddress Books & Contacts
Address Books
/api/address-books— list address books/api/address-books— create address book/api/address-books/:id— update address book/api/address-books/:id— delete address bookContacts
/api/address-books/:abId/contacts?q=...— list contacts (optional search)/api/address-books/:abId/contacts/:id— get contact/api/address-books/:abId/contacts— create contact/api/address-books/:abId/contacts/:id— update contact/api/address-books/:abId/contacts/:id— delete contactCalDAV / CardDAV
Standard CalDAV and CardDAV endpoints are available for syncing calendars and contacts with third-party clients. Authentication uses HTTP Basic Auth with your email and password.
/.well-known/caldav— redirects to /caldav//.well-known/carddav— redirects to /carddav//caldav/{accountId}/{calendarName}/— CalDAV endpointBasic/carddav/{accountId}/{addressBookName}/— CardDAV endpointBasicBranding
/api/branding— branding config for the authenticated user's domain/api/branding/assets/:filename— branding asset file (logo, favicon, CSS)Account API
All account API endpoints require a valid JWT.
Preferences
/api/account/preferences— update account preferences (spam_folder, plus_tag_filing, etc.)AI & Intelligence
/api/messages/:id/thread-ai-state— get AI triage state for a thread/api/messages/:id/ai-reply— generate AI reply draft/api/messages/:id/rewrite-draft— rewrite compose draft with tone control/api/messages/:id/thread-document— generate document-centric thread analysis/api/analysis/natural-search— interpret natural language search query/api/analysis/backfill-body-search— backfill body search indexThread Graph
/api/messages/:id/thread-graph— get conversation graph (nodes + edges)Vacation
/api/vacation— get vacation responder settings/api/vacation— update vacation responder (enabled, subject, body, start/end dates)Waiting On Reply
/api/waiting— list sent messages awaiting reply/api/waiting/:id— update waiting status (resolved, snoozed)/api/waiting/:id/nudge— send follow-up nudgeTasks
/api/tasks— list tasks/api/tasks— create task/api/tasks/:id— update task/api/tasks/:id— delete task/api/tasks/:id/to-calendar— convert task to calendar eventActivity Feed
/api/feed?limit=...— merged chronological feed (messages, events, tasks)Contact Intelligence
/api/contacts/intelligence/top— top contacts by email frequency/api/contacts/intelligence/dormant— contacts with no recent communication/api/contacts/intelligence/:email— per-email communication stats/api/contacts/quick-add— quick-add sender to address bookInbox Summary
/api/inbox-summary— dashboard stats (volume, security, productivity, classifications)Workspaces
/api/workspaces— list workspaces with message counts/api/workspaces— create workspace/api/workspaces/:id— update workspace (name, color, rules, etc.)/api/workspaces/:id— delete workspace (messages preserved)/api/workspaces/:id/messages?page=1&per_page=50— paginated messages/api/workspaces/:id/messages— assign message/api/workspaces/:id/messages/:messageId— remove message from workspace/api/messages/:id/workspaces— get workspaces a message belongs toNL Commands
/api/commands/interpret— AI interprets natural language command/api/commands/execute— execute a command plan (move, archive, delete, flag)Domain Admin API
Requires a JWT with is_domain_admin or is_admin claims.
Accounts & Stats
/api/domain-admin/stats/api/domain-admin/accounts/api/domain-admin/accounts— create account (see Account Creation below)/api/domain-admin/accounts/:id/api/domain-admin/accounts/:id/api/domain-admin/accounts/:id/resend-invite— resend invite email (pending accounts only)/api/domain-admin/accounts/:id/recover— send password reset to recovery email/api/domain-admin/delivery-log/api/domain-admin/dns/check-records— verify DNS records for the admin's domainRetention Policies
/api/domain-admin/retention— get effective retention (domain + account policies)/api/domain-admin/retention/domain— upsert retention for own domain/api/domain-admin/accounts/:id/retention— get account retention override/api/domain-admin/accounts/:id/retention— upsert account retention override/api/domain-admin/accounts/:id/retention— remove account retention overrideAccount Creation
POST /api/domain-admin/accounts accepts a mode field:
- "password" (default): Admin sets the password. Account is immediately active.
- "invite": Requires
invite_email(external address). Account starts aspending_invite. An invite email is sent; the recipient sets their own password.
// Invite mode example
POST /api/domain-admin/accounts
{
"local_part": "alice",
"mode": "invite",
"invite_email": "alice@gmail.com",
"display_name": "Alice",
"quota_bytes": 1073741824
}Site Admin API
Requires a JWT with is_admin=true.
Domains
/api/admin/domains/api/admin/domains/api/admin/domains/:id/api/admin/domains/:idAccounts
/api/admin/accounts/api/admin/accounts/api/admin/accounts/:id— update account; set is_admin to promote/demote/api/admin/accounts/:idBranding (Admin)
/api/admin/branding/:domain— branding config/api/admin/branding/:domain/files— list branding files/api/admin/branding/:domain/archive— upload tar.gz/zip archive/api/admin/branding/:domain/:filename— download/preview asset/api/admin/branding/:domain/:filename— upload single asset/api/admin/branding/:domain/:filename— delete assetSystem & Licensing
/api/admin/stats/api/admin/delivery-log/api/admin/license/api/admin/license/api/admin/system-info/api/admin/settings— system settings (key-value)/api/admin/settings/corporate-domain— update corporate domain/api/admin/settings/safe-browsing-key— save Google Safe Browsing API key/api/admin/dns/check-records?domain=...— verify DNS records (MX, SPF, DKIM, DMARC)/api/admin/openapi.yamlDelivery Thresholds
/api/admin/domains/:domainId/thresholds— get spam score thresholds/api/admin/domains/:domainId/thresholds— update junk/drop thresholds and quarantine expiry/api/admin/delivery/drops— hard drop statisticsRetention Policies
/api/admin/domains/:domainId/retention— get domain retention policy/api/admin/domains/:domainId/retention— upsert domain retention policy/api/admin/domains/:domainId/retention— remove domain retention policyKumoMTA Proxy
Proxy endpoints for managing the embedded KumoMTA instance.
/api/admin/kumomta/metrics— raw KumoMTA metrics (includes uptime, version)/api/admin/kumomta/{endpoint}— proxy GET (bounces, suspensions, ready-q-suspensions)/api/admin/kumomta/{endpoint}— create bounce/suspend rules/api/admin/kumomta/{endpoint}— delete bounce/suspend rulesPlugins
/api/admin/plugins/{id}/enable-all— enable a plugin for all domainsConcepts
Account Status
| Status | Meaning |
|---|---|
active | Normal account — can login and receive mail |
pending_invite | Awaiting invite acceptance — can receive mail but cannot login |
inactive | Disabled — cannot login or receive mail |
Pending accounts that are not activated within 14 days are automatically deleted by the cleanup worker.
Domain Fields
Domains support a catch_all_account_id field. When set, mail to unknown addresses at the domain is delivered to the designated account.
PUT /api/admin/domains/:id
{"catch_all_account_id": 5} // enable catch-all → account 5
{"catch_all_account_id": null} // disable catch-allPlus Addressing
Mail sent to user+tag@domain delivers to user@domain. The tag is stored in messages.plus_tag for filtering. No configuration needed — always active.
Auto-filing: Users can enable plus_tag_filing in their preferences. When enabled, emails to user+tag@domain are automatically placed in a folder named after the tag (created if needed). Spam routing takes priority.
Branding Files
Per-domain branding lets you customize the webmail UI for each domain: logo, favicon, colors, app name, and custom CSS.
Allowed files:
branding.jsonlogo.svglogo.pngfavicon.icofavicon.svgcustom.cssSize limits:
- Images: 512 KB
- CSS / JSON: 64 KB
- Archives: 2 MB
branding.json format:
{
"app_name": "My Mail",
"primary_color": "#667eea",
"accent_color": "#764ba2"
}Examples
Login:
curl -s -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"secret"}'List folders:
curl -s http://localhost:8080/api/folders \
-H "Authorization: Bearer $TOKEN"Compose and send:
curl -s -X POST http://localhost:8080/api/messages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"from":"admin@example.com","to":["user@example.com"],"subject":"Hello","text":"Hi"}'List admin domains:
curl -s http://localhost:8080/api/admin/domains \
-H "Authorization: Bearer $ADMIN_TOKEN"