Skip to content

API reference

All endpoints live on the same Worker that serves the SPA. Authentication is session-cookie based; the cookie is set by /api/auth/callback after the Prism OAuth round-trip and verified on every request. Admin endpoints check role ∈ { owner, co-owner } on the configured team.

Auth

MethodPathDescription
GET/api/auth/configPublic OAuth config used by the SPA
GET/api/auth/meCurrent user, or { user: null }
POST/api/auth/callbackExchange OAuth code for a session
POST/api/auth/logoutInvalidate session

Init

MethodPathDescription
GET/api/init/status{ configured, configStaged }
GET/api/init/brandingsite_name, site_logo_url
GET/api/init/configFull app config — open while pre-init, owner-only after
PUT/api/init/configPatch config — open while pre-init, owner-only after
POST/api/init/setupPhase 1: persist config + run schema, await owner login

POST /api/init/setup refuses if the system is already configured OR if a config is already staged (an owner-login is the only way to advance from a staged state).

Mailbox

MethodPathDescription
GET/api/foldersAll folders + counts
POST/api/foldersCreate a custom folder
PATCH/api/folders/:idRename a folder
DELETE/api/folders/:idDelete folder, move messages to inbox
GET/api/messages?folder=&cursor=&q=Paginated message list
GET/api/messages/:idFull message body + attachments
PATCH/api/messages/:idMark read/unread/starred, move folder
DELETE/api/messages/:idSoft-delete (trash) or hard-delete
POST/api/messages/bulkSame patches but on { ids[] } (≤ 500)
POST/api/messages/trash/emptyHard-delete every trashed message
GET/api/threads/:threadIdAll messages in a thread
GET/api/messages/:id/attachments/:attIdStream an attachment
GET/api/messages/:id/rawStream the original .eml

Send & drafts

MethodPathDescription
POST/api/sendSend a message. From address must be assigned to caller.
POST/api/draftsUpsert a draft (creates a folder='drafts' row)

Member-facing addresses

MethodPathDescription
GET/api/addressesAddresses assigned to current user

Members cannot add or remove their own addresses.

Admin (owner / co-owner only)

MethodPathDescription
GET/api/admin/membersAll Lumen-known team members + their storage caps
GET/api/admin/addressesAll address assignments
POST/api/admin/addressesAssign { userId, address, displayName? }
PUT/api/admin/addresses/:idUpdate display name
DELETE/api/admin/addresses/:idRemove assignment
PUT/api/admin/addresses/:id/primaryMake this address the user's primary
PUT/api/admin/members/:userId/limitsSet/clear per-user maxStorageBytes and maxMessageBytes (null to inherit, 0 for unlimited)
GET/api/admin/stats/storageSite-wide totals: bytes used, message count

A user becomes "Lumen-known" the first time they complete a Prism login.

Realtime

MethodPathDescription
GET/api/wsWebSocket. Pushes LumenEvent messages to the user.

LumenEvent:

ts
type LumenEvent =
  | { kind: "incoming"; folder: string; messageId: string }
  | { kind: "changed";  folder: string; messageId: string }
  | { kind: "deleted";  folder: string; messageId: string }
  | { kind: "folders" };

Image proxy

MethodPathDescription
GET/api/proxy/image?url=…Server-side image fetch with SSRF guard

Required for image rendering when the site default (or per-user override) has the proxy enabled. See Storage & limits.

Contacts & settings

MethodPathDescription
GET/api/contacts?q=Frecency-ranked contacts
GET/api/settingsPer-user settings + site defaults
PUT/api/settingsPatch user settings