# Kuju Email API reference

Generated from the OpenAPI spec. Base URL, authentication and examples are on the HTML page: https://www.kaimoku.tech/kuju-email/docs

## Overview

### Base URL

See https://www.kaimoku.tech/kuju-email/docs#base-url

### Authentication

See https://www.kaimoku.tech/kuju-email/docs#authentication

## Public API

### Auth

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| POST | `/api/auth/login` | public | Login and obtain JWT (or TOTP challenge) |
| POST | `/api/auth/logout` | JWT | Logout (no-op) |
| POST | `/api/auth/refresh` | JWT | Refresh JWT |
| POST | `/api/invite` | public | accept invite and set password (public, token-based) |
| POST | `/api/forgot-password` | public | request password reset email |
| POST | `/api/reset-password` | public | reset password with token |

### Two-Factor (TOTP)

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/auth/totp/status` | JWT | check if TOTP is enabled |
| POST | `/api/auth/totp/setup` | JWT | generate secret + QR code |
| POST | `/api/auth/totp/confirm?session_id=...` | JWT | verify code, enable TOTP, return backup codes |
| POST | `/api/auth/totp/verify` | public | verify TOTP code during login, issue JWT |
| DELETE | `/api/auth/totp` | JWT | disable TOTP (requires current code) |

Parameters for `POST /api/auth/totp/confirm?session_id=...`:

- `session_id` (query, required)

### Folders

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/folders` | JWT | List folders |
| POST | `/api/folders` | JWT | Create folder |
| PUT | `/api/folders/:id` | JWT | Rename folder |
| DELETE | `/api/folders/:id` | JWT | Delete folder (must be empty) |
| GET | `/api/folders/:id/messages` | JWT | List messages in folder |

Parameters for `PUT /api/folders/:id`:

- `id` (path, required)

Parameters for `DELETE /api/folders/:id`:

- `id` (path, required)

Parameters for `GET /api/folders/:id/messages`:

- `id` (path, required)
- `page` (query)
- `per_page` (query)

### Messages

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| POST | `/api/messages` | JWT | compose / send |
| GET | `/api/messages/:id` | JWT | Get message metadata |
| GET | `/api/messages/:id/raw` | JWT | raw RFC 822 source |
| GET | `/api/messages/:id/body` | JWT | rendered body |
| GET | `/api/messages/:id/attachments/:aid` | JWT | download attachment |
| PATCH | `/api/messages/:id/flags` | JWT | update flags (read, starred, etc.) |
| PATCH | `/api/messages/:id/move` | JWT | Move message to folder |
| PATCH | `/api/messages/:id/copy` | JWT | Copy message to folder |
| DELETE | `/api/messages/:id` | JWT | Delete message |
| POST | `/api/messages/search` | JWT | advanced search |
| GET | `/api/messages/search?q=...` | JWT | quick search |

Parameters for `GET /api/messages/:id`:

- `id` (path, required)

Parameters for `GET /api/messages/:id/raw`:

- `id` (path, required)

Parameters for `GET /api/messages/:id/body`:

- `id` (path, required)

Parameters for `GET /api/messages/:id/attachments/:aid`:

- `id` (path, required)
- `aid` (path, required)

Parameters for `PATCH /api/messages/:id/flags`:

- `id` (path, required)

Parameters for `PATCH /api/messages/:id/move`:

- `id` (path, required)

Parameters for `PATCH /api/messages/:id/copy`:

- `id` (path, required)

Parameters for `DELETE /api/messages/:id`:

- `id` (path, required)

Parameters for `GET /api/messages/search?q=...`:

- `q` (query, required)
- `folder_id` (query)
- `page` (query)
- `per_page` (query)

### Message Analysis

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/messages/:id/analysis` | public | cached results + feature availability |
| GET | `/api/messages/:id/analysis/instant` | public | header analysis (auth, sender, hops, URLs) |
| POST | `/api/messages/:id/analysis/ai` | public | AI threat assessment (?force=true to re-analyze) |
| POST | `/api/messages/:id/analysis/av-rescan` | public | ClamAV attachment scan |
| POST | `/api/messages/:id/analysis/url-safety` | public | on-demand link-safety check |

### Attachment Knowledge

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/messages/:id/attachments/:aid/knowledge` | public | cached extraction result |
| POST | `/api/messages/:id/attachments/:aid/knowledge` | public | extract text + AI summarize |

### Drafts

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/drafts` | JWT | List drafts |
| POST | `/api/drafts` | JWT | Create draft |
| GET | `/api/drafts/:id` | JWT | Get draft |
| PUT | `/api/drafts/:id` | JWT | Update draft |
| DELETE | `/api/drafts/:id` | JWT | Delete draft |
| POST | `/api/drafts/:id/send` | JWT | send a saved draft |

Parameters for `GET /api/drafts`:

- `page` (query)
- `per_page` (query)

Parameters for `GET /api/drafts/:id`:

- `id` (path, required)

Parameters for `PUT /api/drafts/:id`:

- `id` (path, required)

Parameters for `DELETE /api/drafts/:id`:

- `id` (path, required)

Parameters for `POST /api/drafts/:id/send`:

- `id` (path, required)

### Calendars & Events

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/calendars` | public | list calendars |
| POST | `/api/calendars` | public | create calendar |
| PUT | `/api/calendars/:id` | public | update calendar |
| DELETE | `/api/calendars/:id` | public | delete calendar |
| GET | `/api/calendars/:calId/events?start=...&end=...` | public | list events (optional RFC 3339 range filter) |
| GET | `/api/calendars/:calId/events/:id` | public | get event |
| POST | `/api/calendars/:calId/events` | public | create event |
| PUT | `/api/calendars/:calId/events/:id` | public | update event |
| DELETE | `/api/calendars/:calId/events/:id` | public | delete event |

### Address Books & Contacts

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/address-books` | public | list address books |
| POST | `/api/address-books` | public | create address book |
| PUT | `/api/address-books/:id` | public | update address book |
| DELETE | `/api/address-books/:id` | public | delete address book |
| GET | `/api/address-books/:abId/contacts?q=...` | public | list contacts (optional search) |
| GET | `/api/address-books/:abId/contacts/:id` | public | get contact |
| POST | `/api/address-books/:abId/contacts` | public | create contact |
| PUT | `/api/address-books/:abId/contacts/:id` | public | update contact |
| DELETE | `/api/address-books/:abId/contacts/:id` | public | delete contact |

### CalDAV / CardDAV

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/.well-known/caldav` | public | redirects to /caldav/ |
| GET | `/.well-known/carddav` | public | redirects to /carddav/ |
| GET | `/caldav/{accountId}/{calendarName}/` | public | CalDAV endpoint |
| GET | `/carddav/{accountId}/{addressBookName}/` | public | CardDAV endpoint |

### Branding

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/branding` | JWT | branding config for the authenticated user's domain |
| GET | `/api/branding/assets/:filename` | JWT | branding asset file (logo, favicon, CSS) |

Parameters for `GET /api/branding/assets/:filename`:

- `filename` (path, required): Whitelisted branding filename

## Account API

### Preferences

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| PUT | `/api/account/preferences` | public | update account preferences (spam_folder, plus_tag_filing, etc.) |

### AI & Intelligence

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/messages/:id/thread-ai-state` | public | get AI triage state for a thread |
| POST | `/api/messages/:id/ai-reply` | public | generate AI reply draft |
| POST | `/api/messages/:id/rewrite-draft` | public | rewrite compose draft with tone control |
| POST | `/api/messages/:id/thread-document` | public | generate document-centric thread analysis |
| POST | `/api/analysis/natural-search` | public | interpret natural language search query |
| POST | `/api/analysis/backfill-body-search` | public | backfill body search index |

### Thread Graph

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/messages/:id/thread-graph` | public | get conversation graph (nodes + edges) |

### Vacation

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/vacation` | public | get vacation responder settings |
| PUT | `/api/vacation` | public | update vacation responder (enabled, subject, body, start/end dates) |

### Waiting On Reply

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/waiting` | public | list sent messages awaiting reply |
| PUT | `/api/waiting/:id` | public | update waiting status (resolved, snoozed) |
| POST | `/api/waiting/:id/nudge` | public | send follow-up nudge |

### Tasks

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/tasks` | public | list tasks |
| POST | `/api/tasks` | public | create task |
| PUT | `/api/tasks/:id` | public | update task |
| DELETE | `/api/tasks/:id` | public | delete task |
| POST | `/api/tasks/:id/to-calendar` | public | convert task to calendar event |

### Activity Feed

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/feed?limit=...` | public | merged chronological feed (messages, events, tasks) |

### Contact Intelligence

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/contacts/intelligence/top` | public | top contacts by email frequency |
| GET | `/api/contacts/intelligence/dormant` | public | contacts with no recent communication |
| GET | `/api/contacts/intelligence/:email` | public | per-email communication stats |
| POST | `/api/contacts/quick-add` | public | quick-add sender to address book |

### Inbox Summary

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/inbox-summary` | public | dashboard stats (volume, security, productivity, classifications) |

### Workspaces

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/workspaces` | public | list workspaces with message counts |
| POST | `/api/workspaces` | public | create workspace |
| PUT | `/api/workspaces/:id` | public | update workspace (name, color, rules, etc.) |
| DELETE | `/api/workspaces/:id` | public | delete workspace (messages preserved) |
| GET | `/api/workspaces/:id/messages?page=1&per_page=50` | public | paginated messages |
| POST | `/api/workspaces/:id/messages` | public | assign message |
| DELETE | `/api/workspaces/:id/messages/:messageId` | public | remove message from workspace |
| GET | `/api/messages/:id/workspaces` | public | get workspaces a message belongs to |

### NL Commands

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| POST | `/api/commands/interpret` | public | AI interprets natural language command |
| POST | `/api/commands/execute` | public | execute a command plan (move, archive, delete, flag) |

## Domain Admin API

### Accounts & Stats

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/domain-admin/stats` | public |  |
| GET | `/api/domain-admin/accounts` | public |  |
| POST | `/api/domain-admin/accounts` | public | create account (see Account Creation below) |
| PUT | `/api/domain-admin/accounts/:id` | public |  |
| DELETE | `/api/domain-admin/accounts/:id` | public |  |
| POST | `/api/domain-admin/accounts/:id/resend-invite` | public | resend invite email (pending accounts only) |
| POST | `/api/domain-admin/accounts/:id/recover` | public | send password reset to recovery email |
| GET | `/api/domain-admin/delivery-log` | public |  |
| GET | `/api/domain-admin/dns/check-records` | public | verify DNS records for the admin's domain |

### Retention Policies

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/domain-admin/retention` | public | get effective retention (domain + account policies) |
| PUT | `/api/domain-admin/retention/domain` | public | upsert retention for own domain |
| GET | `/api/domain-admin/accounts/:id/retention` | public | get account retention override |
| PUT | `/api/domain-admin/accounts/:id/retention` | public | upsert account retention override |
| DELETE | `/api/domain-admin/accounts/:id/retention` | public | remove account retention override |

### Account Creation

See https://www.kaimoku.tech/kuju-email/docs#account-creation

## Site Admin API

### Domains

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/domains` | JWT | List domains |
| POST | `/api/admin/domains` | JWT | Create domain |
| PUT | `/api/admin/domains/:id` | JWT | Update domain |
| DELETE | `/api/admin/domains/:id` | JWT | Deactivate domain |

Parameters for `PUT /api/admin/domains/:id`:

- `id` (path, required)

Parameters for `DELETE /api/admin/domains/:id`:

- `id` (path, required)

### Accounts

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/accounts` | JWT | List accounts |
| POST | `/api/admin/accounts` | JWT | Create account |
| PUT | `/api/admin/accounts/:id` | JWT | update account; set is_admin to promote/demote |
| DELETE | `/api/admin/accounts/:id` | JWT | Deactivate account |

Parameters for `GET /api/admin/accounts`:

- `limit` (query)
- `offset` (query)

Parameters for `PUT /api/admin/accounts/:id`:

- `id` (path, required)

Parameters for `DELETE /api/admin/accounts/:id`:

- `id` (path, required)

### Branding (Admin)

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/branding/:domain` | JWT | branding config |
| GET | `/api/admin/branding/:domain/files` | JWT | list branding files |
| POST | `/api/admin/branding/:domain/archive` | JWT | upload tar.gz/zip archive |
| GET | `/api/admin/branding/:domain/:filename` | JWT | download/preview asset |
| POST | `/api/admin/branding/:domain/:filename` | JWT | upload single asset |
| DELETE | `/api/admin/branding/:domain/:filename` | JWT | delete asset |

Parameters for `GET /api/admin/branding/:domain`:

- `domain` (path, required): Domain name (e.g. example.com)

Parameters for `GET /api/admin/branding/:domain/files`:

- `domain` (path, required): Domain name (e.g. example.com)

Parameters for `POST /api/admin/branding/:domain/archive`:

- `domain` (path, required): Domain name (e.g. example.com)

Parameters for `GET /api/admin/branding/:domain/:filename`:

- `domain` (path, required): Domain name (e.g. example.com)
- `filename` (path, required): Whitelisted branding filename

Parameters for `POST /api/admin/branding/:domain/:filename`:

- `domain` (path, required): Domain name (e.g. example.com)
- `filename` (path, required): Whitelisted branding filename

Parameters for `DELETE /api/admin/branding/:domain/:filename`:

- `domain` (path, required): Domain name (e.g. example.com)
- `filename` (path, required): Whitelisted branding filename

### System & Licensing

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/stats` | JWT | System stats |
| GET | `/api/admin/delivery-log` | JWT | Delivery log entries |
| GET | `/api/admin/license` | JWT | License status and usage |
| PUT | `/api/admin/license` | JWT | Install/update license key |
| GET | `/api/admin/system-info` | JWT | System info including module versions |
| GET | `/api/admin/settings` | JWT | system settings (key-value) |
| PUT | `/api/admin/settings/corporate-domain` | JWT | update corporate domain |
| PUT | `/api/admin/settings/safe-browsing-key` | public | save link-safety check API key |
| GET | `/api/admin/dns/check-records?domain=...` | JWT | verify DNS records (MX, SPF, DKIM, DMARC) |
| GET | `/api/admin/openapi.yaml` | JWT | OpenAPI spec for the REST API |

Parameters for `GET /api/admin/delivery-log`:

- `limit` (query)
- `offset` (query)
- `account_id` (query)
- `status` (query)

Parameters for `GET /api/admin/dns/check-records?domain=...`:

- `domain` (query, required): Domain to check
- `selector` (query): DKIM selector

### Delivery Thresholds

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/domains/:domainId/thresholds` | public | get spam score thresholds |
| PUT | `/api/admin/domains/:domainId/thresholds` | public | update junk/drop thresholds and quarantine expiry |
| GET | `/api/admin/delivery/drops` | public | hard drop statistics |

### Retention Policies

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/domains/:domainId/retention` | public | get domain retention policy |
| PUT | `/api/admin/domains/:domainId/retention` | public | upsert domain retention policy |
| DELETE | `/api/admin/domains/:domainId/retention` | public | remove domain retention policy |

### KumoMTA Proxy

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| GET | `/api/admin/kumomta/metrics` | public | raw KumoMTA metrics (includes uptime, version) |
| GET | `/api/admin/kumomta/{endpoint}` | public | proxy GET (bounces, suspensions, ready-q-suspensions) |
| POST | `/api/admin/kumomta/{endpoint}` | public | create bounce/suspend rules |
| DELETE | `/api/admin/kumomta/{endpoint}` | public | delete bounce/suspend rules |

### Plugins

| Method | Path | Auth | Description |
| --- | --- | --- | --- |
| POST | `/api/admin/plugins/{id}/enable-all` | public | enable a plugin for all domains |

## Concepts

### Account Status

See https://www.kaimoku.tech/kuju-email/docs#account-status

### Domain Fields

See https://www.kaimoku.tech/kuju-email/docs#domain-fields

### Plus Addressing

See https://www.kaimoku.tech/kuju-email/docs#plus-addressing

### Branding Files

See https://www.kaimoku.tech/kuju-email/docs#branding-files

## Examples
