K
Kaimoku

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

Public API (JWT):http(s)://<host>:8080
Internal API:http(s)://<host>:2525

Authentication

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

POST
/api/auth/login
POST
/api/auth/logout
POST
/api/auth/refresh
POST
/api/inviteaccept invite and set password (public, token-based)
POST
/api/forgot-passwordrequest password reset email
POST
/api/reset-passwordreset password with token

Two-Factor Authentication (TOTP)

GET
/api/auth/totp/statuscheck if TOTP is enabledJWT
POST
/api/auth/totp/setupgenerate secret + QR codeJWT
POST
/api/auth/totp/confirm?session_id=...verify code, enable TOTP, return backup codesJWT
POST
/api/auth/totp/verifyverify TOTP code during login, issue JWT
DELETE
/api/auth/totpdisable TOTP (requires current code)JWT

Folders

GET
/api/folders
POST
/api/folders
PUT
/api/folders/:id
DELETE
/api/folders/:id
GET
/api/folders/:id/messages

Messages

POST
/api/messagescompose / send
GET
/api/messages/:id
GET
/api/messages/:id/rawraw RFC 822 source
GET
/api/messages/:id/bodyrendered body
GET
/api/messages/:id/attachments/:aiddownload attachment
PATCH
/api/messages/:id/flagsupdate flags (read, starred, etc.)
PATCH
/api/messages/:id/move
PATCH
/api/messages/:id/copy
DELETE
/api/messages/:id
POST
/api/messages/searchadvanced search
GET
/api/messages/search?q=...quick search

Message Analysis

GET
/api/messages/:id/analysiscached results + feature availability
GET
/api/messages/:id/analysis/instantheader analysis (auth, sender, hops, URLs)
POST
/api/messages/:id/analysis/aiAI threat assessment (?force=true to re-analyze)
POST
/api/messages/:id/analysis/av-rescanClamAV attachment scan
POST
/api/messages/:id/analysis/url-safetyGoogle Safe Browsing URL check

Attachment Knowledge

GET
/api/messages/:id/attachments/:aid/knowledgecached extraction result
POST
/api/messages/:id/attachments/:aid/knowledgeextract text + AI summarize

Drafts

GET
/api/drafts
POST
/api/drafts
GET
/api/drafts/:id
PUT
/api/drafts/:id
DELETE
/api/drafts/:id
POST
/api/drafts/:id/sendsend a saved draft

Calendars & Events

Calendars

GET
/api/calendarslist calendars
POST
/api/calendarscreate calendar
PUT
/api/calendars/:idupdate calendar
DELETE
/api/calendars/:iddelete calendar

Events

GET
/api/calendars/:calId/events?start=...&end=...list events (optional RFC 3339 range filter)
GET
/api/calendars/:calId/events/:idget event
POST
/api/calendars/:calId/eventscreate event
PUT
/api/calendars/:calId/events/:idupdate event
DELETE
/api/calendars/:calId/events/:iddelete event

Address Books & Contacts

Address Books

GET
/api/address-bookslist address books
POST
/api/address-bookscreate address book
PUT
/api/address-books/:idupdate address book
DELETE
/api/address-books/:iddelete address book

Contacts

GET
/api/address-books/:abId/contacts?q=...list contacts (optional search)
GET
/api/address-books/:abId/contacts/:idget contact
POST
/api/address-books/:abId/contactscreate contact
PUT
/api/address-books/:abId/contacts/:idupdate contact
DELETE
/api/address-books/:abId/contacts/:iddelete contact

CalDAV / 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.

GET
/.well-known/caldavredirects to /caldav/
GET
/.well-known/carddavredirects to /carddav/
GET
/caldav/{accountId}/{calendarName}/CalDAV endpointBasic
GET
/carddav/{accountId}/{addressBookName}/CardDAV endpointBasic

Branding

GET
/api/brandingbranding config for the authenticated user's domain
GET
/api/branding/assets/:filenamebranding asset file (logo, favicon, CSS)

Account API

All account API endpoints require a valid JWT.

Preferences

PUT
/api/account/preferencesupdate account preferences (spam_folder, plus_tag_filing, etc.)

AI & Intelligence

GET
/api/messages/:id/thread-ai-stateget AI triage state for a thread
POST
/api/messages/:id/ai-replygenerate AI reply draft
POST
/api/messages/:id/rewrite-draftrewrite compose draft with tone control
POST
/api/messages/:id/thread-documentgenerate document-centric thread analysis
POST
/api/analysis/natural-searchinterpret natural language search query
POST
/api/analysis/backfill-body-searchbackfill body search index

Thread Graph

GET
/api/messages/:id/thread-graphget conversation graph (nodes + edges)

Vacation

GET
/api/vacationget vacation responder settings
PUT
/api/vacationupdate vacation responder (enabled, subject, body, start/end dates)

Waiting On Reply

GET
/api/waitinglist sent messages awaiting reply
PUT
/api/waiting/:idupdate waiting status (resolved, snoozed)
POST
/api/waiting/:id/nudgesend follow-up nudge

Tasks

GET
/api/taskslist tasks
POST
/api/taskscreate task
PUT
/api/tasks/:idupdate task
DELETE
/api/tasks/:iddelete task
POST
/api/tasks/:id/to-calendarconvert task to calendar event

Activity Feed

GET
/api/feed?limit=...merged chronological feed (messages, events, tasks)

Contact Intelligence

GET
/api/contacts/intelligence/toptop contacts by email frequency
GET
/api/contacts/intelligence/dormantcontacts with no recent communication
GET
/api/contacts/intelligence/:emailper-email communication stats
POST
/api/contacts/quick-addquick-add sender to address book

Inbox Summary

GET
/api/inbox-summarydashboard stats (volume, security, productivity, classifications)

Workspaces

GET
/api/workspaceslist workspaces with message counts
POST
/api/workspacescreate workspace
PUT
/api/workspaces/:idupdate workspace (name, color, rules, etc.)
DELETE
/api/workspaces/:iddelete workspace (messages preserved)
GET
/api/workspaces/:id/messages?page=1&per_page=50paginated messages
POST
/api/workspaces/:id/messagesassign message
DELETE
/api/workspaces/:id/messages/:messageIdremove message from workspace
GET
/api/messages/:id/workspacesget workspaces a message belongs to

NL Commands

POST
/api/commands/interpretAI interprets natural language command
POST
/api/commands/executeexecute a command plan (move, archive, delete, flag)

Domain Admin API

Requires a JWT with is_domain_admin or is_admin claims.

Accounts & Stats

GET
/api/domain-admin/stats
GET
/api/domain-admin/accounts
POST
/api/domain-admin/accountscreate account (see Account Creation below)
PUT
/api/domain-admin/accounts/:id
DELETE
/api/domain-admin/accounts/:id
POST
/api/domain-admin/accounts/:id/resend-inviteresend invite email (pending accounts only)
POST
/api/domain-admin/accounts/:id/recoversend password reset to recovery email
GET
/api/domain-admin/delivery-log
GET
/api/domain-admin/dns/check-recordsverify DNS records for the admin's domain

Retention Policies

GET
/api/domain-admin/retentionget effective retention (domain + account policies)
PUT
/api/domain-admin/retention/domainupsert retention for own domain
GET
/api/domain-admin/accounts/:id/retentionget account retention override
PUT
/api/domain-admin/accounts/:id/retentionupsert account retention override
DELETE
/api/domain-admin/accounts/:id/retentionremove account retention override

Account 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 as pending_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

GET
/api/admin/domains
POST
/api/admin/domains
PUT
/api/admin/domains/:id
DELETE
/api/admin/domains/:id

Accounts

GET
/api/admin/accounts
POST
/api/admin/accounts
PUT
/api/admin/accounts/:idupdate account; set is_admin to promote/demote
DELETE
/api/admin/accounts/:id

Branding (Admin)

GET
/api/admin/branding/:domainbranding config
GET
/api/admin/branding/:domain/fileslist branding files
POST
/api/admin/branding/:domain/archiveupload tar.gz/zip archive
GET
/api/admin/branding/:domain/:filenamedownload/preview asset
POST
/api/admin/branding/:domain/:filenameupload single asset
DELETE
/api/admin/branding/:domain/:filenamedelete asset

System & Licensing

GET
/api/admin/stats
GET
/api/admin/delivery-log
GET
/api/admin/license
PUT
/api/admin/license
GET
/api/admin/system-info
GET
/api/admin/settingssystem settings (key-value)
PUT
/api/admin/settings/corporate-domainupdate corporate domain
PUT
/api/admin/settings/safe-browsing-keysave Google Safe Browsing API key
GET
/api/admin/dns/check-records?domain=...verify DNS records (MX, SPF, DKIM, DMARC)
GET
/api/admin/openapi.yaml

Delivery Thresholds

GET
/api/admin/domains/:domainId/thresholdsget spam score thresholds
PUT
/api/admin/domains/:domainId/thresholdsupdate junk/drop thresholds and quarantine expiry
GET
/api/admin/delivery/dropshard drop statistics

Retention Policies

GET
/api/admin/domains/:domainId/retentionget domain retention policy
PUT
/api/admin/domains/:domainId/retentionupsert domain retention policy
DELETE
/api/admin/domains/:domainId/retentionremove domain retention policy

KumoMTA Proxy

Proxy endpoints for managing the embedded KumoMTA instance.

GET
/api/admin/kumomta/metricsraw KumoMTA metrics (includes uptime, version)
GET
/api/admin/kumomta/{endpoint}proxy GET (bounces, suspensions, ready-q-suspensions)
POST
/api/admin/kumomta/{endpoint}create bounce/suspend rules
DELETE
/api/admin/kumomta/{endpoint}delete bounce/suspend rules

Plugins

POST
/api/admin/plugins/{id}/enable-allenable a plugin for all domains

Concepts

Account Status

StatusMeaning
activeNormal account — can login and receive mail
pending_inviteAwaiting invite acceptance — can receive mail but cannot login
inactiveDisabled — 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-all

Plus 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.css

Size 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"