Appearance
mail
84 endpoints at a glance
| Method | Path | Summary |
|---|---|---|
GET | /admin/mail/global-blocklist | List Global Blocklist |
POST | /admin/mail/global-blocklist | Add Global Blocklist |
DELETE | /admin/mail/global-blocklist/{entry_id} | Remove Global Blocklist |
GET | /admin/mail/keywords | List Keywords |
POST | /admin/mail/keywords | Add Keyword |
DELETE | /admin/mail/keywords/{keyword_id} | Remove Keyword |
PATCH | /admin/mail/keywords/{keyword_id} | Patch Keyword |
GET | /admin/mail/nrd/imports | List Nrd Imports |
POST | /admin/mail/nrd/imports/run | Run Nrd Import |
GET | /admin/mail/nrd/stats | Nrd Stats |
GET | /admin/mail/nrd/status | Nrd Status |
GET | /admin/mail/stalwart/allowed-ips | Stalwart Allowed Ips |
GET | /admin/mail/stalwart/blocked-ips | Stalwart Blocked Ips |
DELETE | /admin/mail/stalwart/blocked-ips/{ip} | Stalwart Unblock Ip |
GET | /admin/mail/stalwart/health | Stalwart Health |
GET | /admin/mail/stalwart/queue | Stalwart Queue |
DELETE | /admin/mail/stalwart/queue/{message_id} | Stalwart Queue Cancel |
GET | /admin/mail/stalwart/queue/{message_id} | Stalwart Queue Message |
POST | /admin/mail/stalwart/queue/{message_id}/retry | Stalwart Queue Retry |
GET | /mail/accounts | List Accounts |
POST | /mail/accounts | Create Account |
DELETE | /mail/accounts/{account_id} | Delete Account |
PUT | /mail/accounts/{account_id} | Update Account |
GET | /mail/accounts/{account_id}/filter | Get Account Filter |
PUT | /mail/accounts/{account_id}/filter | Save Account Filter |
POST | /mail/accounts/{account_id}/filter/run | Run Account Filter |
PUT | /mail/accounts/{account_id}/folders | Save Account Folders |
GET | /mail/accounts/{account_id}/folders/available | List Account Available Folders |
GET | /mail/accounts/{account_id}/rules | List Rules |
POST | /mail/accounts/{account_id}/rules | Add Rule |
DELETE | /mail/accounts/{account_id}/rules/{rule_id} | Remove Rule |
PUT | /mail/accounts/{account_id}/rules/{rule_id} | Update Rule |
PUT | /mail/accounts/{account_id}/rules/{rule_id}/enabled | Set Rule Enabled |
PUT | /mail/accounts/{account_id}/rules/reorder | Reorder Rules |
POST | /mail/accounts/{account_id}/set-default | Set Default Account |
PUT | /mail/accounts/{account_id}/smtp | Save Account Smtp |
POST | /mail/accounts/{account_id}/test | Test Account |
POST | /mail/accounts/{account_id}/test-smtp | Test Account Smtp |
POST | /mail/attachments | Stage Attachment |
DELETE | /mail/attachments/{attachment_id} | Discard Attachment |
GET | /mail/blocklist | List Blocklist |
POST | /mail/blocklist | Add Blocklist |
DELETE | /mail/blocklist/{entry_id} | Remove Blocklist |
DELETE | /mail/connection | Delete Connection |
GET | /mail/connection | Get Connection |
PUT | /mail/connection | Save Connection |
GET | /mail/contact-emails | Contact Emails |
GET | /mail/drafts | List Drafts |
POST | /mail/drafts | Create Draft |
DELETE | /mail/drafts/{draft_id} | Delete Draft |
GET | /mail/drafts/{draft_id} | Get Draft |
PUT | /mail/drafts/{draft_id} | Update Draft |
GET | /mail/filter | Get Filter |
PUT | /mail/filter | Save Filter |
POST | /mail/filter/run | Run Filter |
GET | /mail/folders | List Folders |
PUT | /mail/folders | Save Folders |
POST | /mail/folders/{folder_id}/empty-to-trash | Empty To Trash |
GET | /mail/folders/available | List Available Folders |
GET | /mail/messages | List Messages |
GET | /mail/messages/{email_id} | Get Message |
GET | /mail/messages/{email_id}/attachments/{part_id} | Download Attachment |
POST | /mail/messages/{email_id}/move | Move Message Endpoint |
POST | /mail/messages/{email_id}/move-to-inbox | Move To Inbox |
GET | /mail/messages/{email_id}/raw | Download Raw |
POST | /mail/messages/{email_id}/read | Mark Read |
GET | /mail/messages/{email_id}/reply-draft | Reply Draft |
POST | /mail/messages/{email_id}/report-spam | Report Spam |
POST | /mail/messages/{email_id}/tags | Set Message Tag |
GET | /mail/search | Search Messages |
POST | /mail/send | Send Mail |
GET | /mail/smart-folders | List Smart Folders |
POST | /mail/smart-folders | Add Smart Folder |
DELETE | /mail/smart-folders/{sf_id} | Remove Smart Folder |
PATCH | /mail/smart-folders/{sf_id} | Update Smart Folder |
GET | /mail/smart-folders/{sf_id}/messages | List Smart Messages |
PUT | /mail/smtp | Save Smtp |
POST | /mail/sync | Sync Now |
GET | /mail/tags | Folder Tags |
POST | /mail/test | Test Connection |
POST | /mail/test-smtp | Test Smtp |
GET | /mail/whitelist | List Whitelist |
POST | /mail/whitelist | Add Whitelist |
DELETE | /mail/whitelist/{entry_id} | Remove Whitelist |
mail
Test Connection
POST
/mail/test
Validate credentials and return discovered folders. Doesn't save.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "host": "string", "port": 993, "use_ssl": true, "verify_ssl": true, "username": "string", "password": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Get Connection
Save Connection
PUT
/mail/connection
Validate against the server, then save the (encrypted) credentials.
Legacy single-account alias: updates the DEFAULT account in place, or
creates the first account when none exists yet.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "host": "string", "port": 993, "use_ssl": true, "verify_ssl": true, "username": "string", "password": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Delete Connection
List Accounts
Create Account
POST
/mail/accounts
Validate against the server, then add a NEW mail account.
The first account becomes the default automatically.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "host": "string", "port": 993, "use_ssl": true, "verify_ssl": true, "username": "string", "password": "string", "label": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Update Account
PUT
/mail/accounts/{account_id}
Validate + update one account's IMAP credentials (and label).
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "host": "string", "port": 993, "use_ssl": true, "verify_ssl": true, "username": "string", "password": "string", "label": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Delete Account
DELETE
/mail/accounts/{account_id}
Remove ONE account. By default cascades its synced mail + folders.
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Query Parameters
delete_emails
Type
boolean
Default
trueResponses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Set Default Account
Test Account
List Account Available Folders
Save Account Folders
PUT
/mail/accounts/{account_id}/folders
Set one account's enabled folder set (see save_folders).
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "folder_ids": [ "string" ]
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
List Available Folders
List Folders
Save Folders
PUT
/mail/folders
Set the DEFAULT account's enabled folder set (legacy alias).
Removed folders cascade their mail away. Re-discovers from the server so
we resolve each requested id back to a real path/name without trusting
client input.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "folder_ids": [ "string" ]
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Sync Now
POST
/mail/sync
Trigger a sync. folder_id limits it to one folder, account_id
to one account; with neither, every account is synced.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "folder_id": "string", "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Empty To Trash
POST
/mail/folders/{folder_id}/empty-to-trash
Move every message in a folder to the Trash folder.
Available on any folder EXCEPT the ones a mis-click would wreck — INBOX,
Sent, Drafts, Trash itself and Gmail's All Mail (see
:func:api.mail.client.is_protected_from_empty). Never deletes — the
messages are relocated to Trash. Reflects the now-empty folder locally so
the UI updates immediately.
Parameters
Header Parameters
authorization
Path Parameters
folder_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Search Messages
GET
/mail/search
Full-text search across all folders and accounts (bodies included).
Backed by the email_text $text index — word-based matching,
unlike the substring regex of the per-folder q on /messages. Each
hit carries folder_name/folder_path/account_label so result
rows can show where the message lives.
Parameters
Header Parameters
authorization
Query Parameters
q*
Type
Requiredstring
Min Length
1page
Type
integer
Default
1limit
Type
integer
Default
50Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
List Messages
Folder Tags
Get Message
Contact Emails
GET
/mail/contact-emails
Emails where this contact is a sender or recipient (newest first).
Parameters
Header Parameters
authorization
Query Parameters
addressbook_id*
Type
Requiredstring
uid*
Type
Requiredstring
page
Type
integer
Default
1limit
Type
integer
Default
50Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Mark Read
POST
/mail/messages/{email_id}/read
Mark a message read — sets the \Seen flag on the server.
No-op when it's already read (no server round trip). Keeps the local
seen flag and the folder's unread badge in sync.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Set Message Tag
POST
/mail/messages/{email_id}/tags
Add or remove a tag (IMAP keyword) on a message — STOREs it on the server
so it round-trips with other clients (Thunderbird). Returns the new tags.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Request Body
application/json
JSON "tag": "string", "add": true
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Move To Inbox
POST
/mail/messages/{email_id}/move-to-inbox
Move a message back into the INBOX — e.g. right after whitelisting its
sender, to pull a quarantined message out of the spam folder.
No-op when the message is already in the INBOX. The server MOVE assigns
the message a fresh UID in the INBOX, so we drop the local copy here and
let the next INBOX sync re-import it (now that the sender is whitelisted,
the filter leaves it in place). The source folder's counts are refreshed
so the UI updates immediately.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Move Message Endpoint
POST
/mail/messages/{email_id}/move
Move a message to another folder.
Destination is either a synced folder (dest_folder_id) or a special-use
folder resolved server-side (special = "archive" / "trash"), so
Archive/Trash work even when those folders aren't synced. The message is
dropped locally and the source folder's counts refreshed; a move into a
synced folder reappears there on the next sync (under its new UID).
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Request Body
application/json
JSON "dest_folder_id": "string", "special": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Download Raw
GET
/mail/messages/{email_id}/raw
Download the full original message as an .eml (message/rfc822).
Served from GridFS when stored; otherwise fetched live from the server
once and persisted (lazy backfill for messages synced before we kept
raw). 404 if the message is gone from both our store and the server.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON
[
]
Download Attachment
List Whitelist
Add Whitelist
Remove Whitelist
List Blocklist
Add Blocklist
Remove Blocklist
List Rules
Add Rule
POST
/mail/accounts/{account_id}/rules
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "from_value": "string", "subject_contains": "string", "list_id_contains": "string", "dest_path": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Reorder Rules
Update Rule
PUT
/mail/accounts/{account_id}/rules/{rule_id}
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
rule_id*
Type
Requiredstring
Request Body
application/json
JSON "from_value": "string", "subject_contains": "string", "list_id_contains": "string", "dest_path": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Remove Rule
Set Rule Enabled
PUT
/mail/accounts/{account_id}/rules/{rule_id}/enabled
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
rule_id*
Type
Requiredstring
Request Body
application/json
JSON "additionalProperties": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
List Smart Folders
Add Smart Folder
POST
/mail/smart-folders
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "name": "string", "match": "all", "groups": [ { "match": "all", "conditions": [ { "field": "string", "op": "string", "value": "string" } ] } ], "conditions": [ { "field": "string", "op": "string", "value": "string" } ], "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Remove Smart Folder
Update Smart Folder
PATCH
/mail/smart-folders/{sf_id}
Parameters
Header Parameters
authorization
Path Parameters
sf_id*
Type
Requiredstring
Request Body
application/json
JSON "name": "string", "match": "string", "groups": [ { "match": "all", "conditions": [ { "field": "string", "op": "string", "value": "string" } ] } ], "conditions": [ { "field": "string", "op": "string", "value": "string" } ], "account_id": "string", "order": 0
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
List Smart Messages
Report Spam
POST
/mail/messages/{email_id}/report-spam
Block the sender's domain and move this message to the spam folder now.
Future mail from the domain is auto-routed to the spam folder by the filter
pass on each sync (new mail only). The current message is moved immediately
so it doesn't sit in the inbox.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Get Filter
Save Filter
PUT
/mail/filter
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "enabled": false, "dest_path": "string", "buckets": [ { "name": "string", "max_score": 0 } ], "keep_contacts": true, "spam_path": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Run Filter
Get Account Filter
Save Account Filter
PUT
/mail/accounts/{account_id}/filter
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "enabled": false, "dest_path": "string", "buckets": [ { "name": "string", "max_score": 0 } ], "keep_contacts": true, "spam_path": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Run Account Filter
POST
/mail/accounts/{account_id}/filter/run
Run one account's filter once now (see _run_filter).
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "folder_id": "string", "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Save Smtp
PUT
/mail/smtp
Save the sending identity (SMTP host/port/security + From + signature).
SMTP reuses the IMAP login, so an IMAP connection must exist first.
Legacy alias — operates on the DEFAULT account.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "smtp_host": "string", "smtp_port": 465, "smtp_security": "ssl", "from_address": "string", "from_name": "", "signature": ""
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Test Smtp
Save Account Smtp
PUT
/mail/accounts/{account_id}/smtp
Save one account's sending identity (see save_smtp).
Parameters
Header Parameters
authorization
Path Parameters
account_id*
Type
Requiredstring
Request Body
application/json
JSON "smtp_host": "string", "smtp_port": 465, "smtp_security": "ssl", "from_address": "string", "from_name": "", "signature": ""
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Test Account Smtp
Stage Attachment
Discard Attachment
Reply Draft
GET
/mail/messages/{email_id}/reply-draft
Prefill for reply / reply_all / forward.
Returns recipients, subject, a Markdown body seed (quoted original), and
threading headers. For forward the original's attachments are re-staged
and returned so the composer carries them.
Parameters
Header Parameters
authorization
Path Parameters
email_id*
Type
Requiredstring
Query Parameters
mode
Type
string
Default
"reply"Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Send Mail
POST
/mail/send
Build + submit a message over SMTP, file a copy to Sent, and (for a
reply) flag the original \Answered.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "to": [ "string" ], "cc": [ "string" ], "bcc": [ "string" ], "subject": "", "body_markdown": "", "body_html": "string", "attachment_ids": [ "string" ], "in_reply_to": "string", "references": "string", "reply_to_email_id": "string", "draft_id": "string", "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
List Drafts
Create Draft
POST
/mail/drafts
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "to": [ "string" ], "cc": [ "string" ], "bcc": [ "string" ], "subject": "", "body_markdown": "", "attachments": [ { "additionalProperties": "string" } ], "in_reply_to": "string", "references": "string", "reply_to_email_id": "string", "mode": "new", "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Get Draft
Update Draft
PUT
/mail/drafts/{draft_id}
Parameters
Header Parameters
authorization
Path Parameters
draft_id*
Type
Requiredstring
Request Body
application/json
JSON "to": [ "string" ], "cc": [ "string" ], "bcc": [ "string" ], "subject": "", "body_markdown": "", "attachments": [ { "additionalProperties": "string" } ], "in_reply_to": "string", "references": "string", "reply_to_email_id": "string", "mode": "new", "account_id": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Delete Draft
List Keywords
Add Keyword
Remove Keyword
Patch Keyword
List Global Blocklist
Add Global Blocklist
Remove Global Blocklist
Nrd Status
Nrd Stats
List Nrd Imports
Run Nrd Import
POST
/admin/mail/nrd/imports/run
Import the Whoisds NRD list — a specific date, else the daily default.
Runs the blocking download/upsert off the event loop.
Parameters
Header Parameters
authorization
Request Body
application/json
JSON "date": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Stalwart Health
Stalwart Queue
Stalwart Queue Message
Stalwart Queue Cancel
Stalwart Blocked Ips
Stalwart Allowed Ips
Stalwart Queue Retry
Stalwart Unblock Ip
DELETE
/admin/mail/stalwart/blocked-ips/{ip}
Remove one banned IP from Stalwart's config.
Returns a caveat the UI must show: the delete clears the persistent
ban, but a live in-memory ban may survive until a Stalwart reload/restart
(learned during the 502 incident). The durable fix is the allowlist, not
repeated unblocks.
Parameters
Header Parameters
authorization
Path Parameters
ip*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}