This page is for people who build on imbox. The server is a Hono app on Node.js. Endpoints speak JSON, except the live event stream and raw message downloads.
The app's own API
These are the endpoints the web app uses. They can change between releases. Two parts are meant for outside programs and kept steady: extension tokens and agent mail.
Authentication & Authorization
Imbox supports three distinct authentication methods depending on the client:
1. Browser Session Cookie (imbox_session)
- Used by the main web and mobile applications.
- Issued upon successful sign-in at
POST /auth/login. - Stored as an
HttpOnly,SameSite=Lax,Securecookie. - Valid for 30 days. Stored as an SHA-256 hash in PostgreSQL.
2. Scoped Extension Tokens (imx_...)
- Used by the browser extension.
- Sent via HTTP header:
Authorization: Bearer imx_.... - Scoped strictly to Screener triage, counts, and agenda endpoints (see Browser extension).
3. Agent Mailbox Keys
- Used by external automated scripts and AI agents.
- Sent via HTTP header:
Authorization: Bearer <agent_key>. - Scoped to that one mailbox, under
/agent/v1. See Agent mail. The owner makes and revokes the keys in the app.
CSRF & Origin Validation
For cookie-authenticated requests, all state-changing HTTP methods (POST, PUT, PATCH, DELETE) require an Origin header that matches APP_URL. Requests originating from unrecognized domains are rejected with 403 cross_site_request.
Multi-Mailbox Targeting (X-Account-Id)
By default, mail endpoints aggregate data across all connected user mailboxes. To scope an operation to a specific mailbox, provide the X-Account-Id header:
X-Account-Id: acc_01h8x4j5k6m7n8p9Set to all (or omit) to query across all active user mailboxes.
Real-Time Events (GET /api/events)
Imbox streams live updates to connected clients using Server-Sent Events (SSE).
- URL:
GET /api/events - Transport:
text/event-stream - Underlying Engine: PostgreSQL
LISTEN/NOTIFYtrigger on thethreadstable.
Event Format
event: message
data: {
"type": "threads_changed",
"accountId": "acc_123",
"unreadCount": 4,
"screenerCount": 1
}If the stream drops or is interrupted by a proxy, clients automatically fall back to poll-based synchronizations.
Error Handling
All error responses return standard JSON with appropriate HTTP status codes:
{
"error": "invalid_credentials",
"message": "The email or password you entered is incorrect."
}| HTTP Status | Meaning |
|---|---|
400 Bad Request | Malformed JSON or invalid schema input. |
401 Unauthorized | Missing or expired session cookie/token. |
403 Forbidden | CSRF origin mismatch, account locked, or unauthorized token scope. |
404 Not Found | The requested resource does not exist or does not belong to your account. |
413 Payload Too Large | Attachment or email body exceeds allowed limits. |
429 Too Many Requests | Rate limit exceeded. Refer to the Retry-After header. |
500 Server Error | Unexpected backend or database error. |
Core Endpoint Catalog
Authentication (/auth)
| Method & Route | Description |
|---|---|
GET /auth/status | Check if initial owner signup is complete and if current session is active. |
POST /auth/signup | Create the initial owner account (locks permanently once created). |
POST /auth/login | Authenticate with email/password; initiates 2FA flow if enabled. |
POST /auth/login/2fa | Complete login with a 6-digit TOTP code or backup code. |
POST /auth/logout | Terminate the active session and invalidate cookie. |
GET /auth/google/start | Begin Google OAuth sign-in flow. |
GET /auth/microsoft/start | Begin Microsoft Graph OAuth sign-in flow. |
Mail & Threads (/api)
| Method & Route | Description |
|---|---|
GET /api/counts | Get unread counts, Screener counts, and folder badge totals. |
GET /api/imbox | Fetch the primary Imbox thread list (people first). |
GET /api/feed | Fetch the Feed thread list (newsletters, receipts, notifications). |
GET /api/threads/:id | Fetch full thread history, messages, and attachment metadata. |
POST /api/threads/:id/actions | Move thread, mark as read/unread, set aside, or reply later. |
POST /api/threads/bulk | Perform batch triage operations across multiple thread IDs. |
GET /api/search?q=:query | Fast full-text and trigram search with search operator filters. |
Screener (/api/screener)
| Method & Route | Description |
|---|---|
GET /api/screener | List all senders awaiting first-time approval. |
POST /api/screener/decide | Approve ("Let in") or reject ("Screen out") a sender. |
GET /api/screener/waiting | Fetch the next top N senders for quick toolbar triage. |
Sending & Drafts (/api)
| Method & Route | Description |
|---|---|
GET /api/drafts | List saved drafts. |
POST /api/drafts | Save or update a draft. |
POST /api/send | Send an email through the designated mailbox provider. |
POST /api/send/cancel | Cancel an undoable scheduled send window. |
Calendar (/api/calendar)
| Method & Route | Description |
|---|---|
GET /api/calendar/events | Fetch events across a date range. |
POST /api/calendar/events | Create an event. |
GET /api/calendar/agenda | Fetch 14-day agenda overview. |
GET /api/calendar/sources | List all connected Google, CalDAV, and local calendar sources. |
AI Assistant (/api/ai)
| Method & Route | Description |
|---|---|
POST /api/ai/chat | Send a prompt to the assistant with streaming SSE response. |
POST /api/ai/reply | Generate a contextual draft reply for a specific thread. |
POST /api/ai/summarize | Generate a concise thread summary. |
GET /api/ai/memory | Retrieve the assistant's learned user facts and tone preferences. |
POST /api/ai/settings/test | Test model features (streaming, tool calls, structured outputs). |
Next
- Agent mail: the API for outside programs.
- Database: how queries are written and tested.
- Development: run the server and the app locally.