Mailbox Folder Cache & Management
The Squibble Email Gateway supports comprehensive hierarchical folder and directory management for mailboxes. To provide sub-millisecond response times in client sidebars and user interfaces, Squibble utilizes a Hybrid Folder Cache (Option 1) which caches directory trees in PostgreSQL while fetching message payloads statelessly on demand.
1. Architectural Strategy: Option 1 Hybrid Cache
Unlike fully synchronized mailboxes that copy all email bodies and attachments locally (leading to massive database bloat and storage liabilities), Squibble keeps message retrieval completely stateless.
- Folder Cache: Hierarchical trees and thin directory metadata (such as
MESSAGESandUNSEENstatus counts,UIDVALIDITY, andUIDNEXT) are cached in PostgreSQL. - Message Streaming: Individual email listings and attachments are pulled on-demand directly from the IMAP server and streamed over REST.
- Performance Impact: Eliminates the slow, blocking 500ms synchronous IMAP round-trips needed to render mail sidebars. Renders navigation interfaces in under 10ms.
2. API Endpoints Reference
All endpoints require a valid JWT bearer token. Scopes are granted per action:
| Endpoint | Required scope |
|---|---|
GET …/folders (list) | messages:index |
POST …/folders (create) | folders:write |
DELETE …/folders/{path} (delete) | folders:write |
PUT …/folders/{path}/subscription | folders:write |
POST …/folders/{path}/messages/actions (move/copy) | messages:move |
A read-only (messages:index) token can list folders but cannot create, delete, subscribe, or move/expunge messages.
A. List Folders
Retrieve the cached folder hierarchy for the mailbox.
- Endpoint:
GET /api/v1/email/account/{mailbox}/folders - Query Parameters:
subscribed_only(bool, defaulttrue): Only return folders marked subscribed.force_refresh(bool, defaultfalse): Perform an inline real-time IMAP sync before returning results.
- Example Response:
{ "data": [ { "id": "c1a60fa1-3bc9-4b6b-88a2-f67381180abc", "mailbox_id": "8fa80291-7f9a-4c2c-982d-8b0ab971bc3d", "path": "INBOX/Invoices", "name": "Invoices", "delimiter": "/", "flags": ["\\HasNoChildren", "\\Unmarked"], "special_use": "archive", "is_subscribed": true, "messages_count": 42, "unseen_count": 3, "uid_validity": 1717012345, "uid_next": 105, "highest_mod_seq": 54321, "created_at": "2026-05-31T10:00:00.000000Z", "updated_at": "2026-05-31T10:05:00.000000Z" } ] }
B. Create Folder
Create a new directory structure on both the IMAP server and local database cache.
- Endpoint:
POST /api/v1/email/account/{mailbox}/folders - Payload:
{ "path": "INBOX/Receipts/2026" } - Example Response (201 Created):
{ "id": "d2b71ab2-4cd8-5c7c-99b3-07cb1231a4df", "mailbox_id": "8fa80291-7f9a-4c2c-982d-8b0ab971bc3d", "path": "INBOX/Receipts/2026", "name": "2026", "delimiter": "/", "flags": ["\\HasNoChildren"], "is_subscribed": true, "messages_count": 0, "unseen_count": 0, "created_at": "2026-05-31T10:10:00.000000Z", "updated_at": "2026-05-31T10:10:00.000000Z" }
C. Delete Folder
Delete a folder structure on the IMAP server and remove it from the local cache.
- Endpoint:
DELETE /api/v1/email/account/{mailbox}/folders/{folder_path:path} - Response:
204 No Content
D. Toggle Subscription
Subscribe or unsubscribe from folder tree updates.
- Endpoint:
PUT /api/v1/email/account/{mailbox}/folders/{folder_path:path}/subscription - Payload:
{ "subscribed": false } - Response (200 OK): Returns the updated
FolderEntrywithis_subscribed: false.
E. Bulk Message Actions (Move / Copy)
Perform bulk inter-folder operations cleanly. Translates into atomized server-side IMAP operations.
- Endpoint:
POST /api/v1/email/account/{mailbox}/folders/{folder_path:path}/messages/actions - Payload:
{ "action": "move", // or "copy" "target_folder": "Archive/Processed", "uids": [101, 102, 103] } - Capability Detection & Fallback:
- If the upstream IMAP server supports the
MOVEcapability (RFC 6851), the action executes atomically in one server command:UID MOVE {uids} {target_folder}. - On older servers lacking
MOVEsupport, Squibble transparently falls back to an emulated copy sequence:UID COPYfollowed by marking messages as\Deletedand performingEXPUNGE.
- If the upstream IMAP server supports the
3. Command Injection Security
To prevent IMAP command injection (such as injecting CR/LF characters into mailbox path parameters), strict route and schema regex validation is enforced. All paths are validated against the following strict alphanumeric and delimiter constraint before executing commands:
pattern=r"^[a-zA-Z0-9_\-\./]+$"
Carriage returns, line feeds, and control characters are rejected immediately with a 422 Unprocessable Entity response, safeguarding credentials and server state.
4. Starlette Thread Pool Execution
All folder operations executing synchronous imaplib blocking calls are declared as synchronous def endpoints. This allows Starlette to process them on its background worker threadpool, preventing high-latency IMAP network I/O from blocking the asyncio main event loop.