⚡ mxlogin-go — REST interface to the mail.mxlogin.com webmail backend (CrossBox / MXroute). Full email client over HTTP: read, search, manage and send mail — including from locked-down hosts (no SMTP needed). Always-connected shared session, auto-reconnecting on token expiry.
🔑 Authentication
POST/api/admin/login
Admin dashboard login. Sets the HttpOnly
mxlogin_admin cookie (12h TTL, SameSite=Lax).body
{"password": "…"} → {"ok": true, "admin": true} · wrong password → 401 wrong passwordPOST/api/admin/logout
Clears the admin session →
{"ok": true}GET/api/admin/me
Valid cookie →
{"admin": true, "expires": <epoch>} · else 401Every other endpoint requires either the admin cookie or the API key, passed as:
header
X-API-Key: <key> · query ?api_key=<key>wrong/missing → 401
{"detail": "invalid or missing X-API-Key"}▤ Multi-mailbox routing
All mail endpoints accept
?mailbox=<email> to target a stored mailbox. With 0 mailboxes configured the env account (MXLOGIN_EMAIL) is used; with 1 it's automatic; with 2+ the param is required:
400 {"detail": "multiple mailboxes configured — specify ?mailbox=<email>"} · unknown mailbox → 404 mailbox not configured: <email>Mailboxes auth required
GET/mailboxes
List configured mailboxes (no passwords). Each item:
email, label, created, last_used, connected, serverPOST/mailboxes
Add a mailbox — validates by logging in upstream first, then stores the password Fernet-encrypted.
body
{"email"*, "password"*, "label"?} · bad creds → 401 invalid credentials: …PUT/mailboxes/{email}
Rotate password / update label (re-validates by login). →
{"ok": true, "email": …} · missing → 404 mailbox not foundDELETE/mailboxes/{email}
Remove mailbox + drop its session →
{"ok": true, "email": …}POST/mailboxes/{email}/test
Login + folder round-trip →
{"ok", "email", "name", "server", "folders": […]}Folders
GET/folders?mailbox=…
Full folder tree with counts:
full_name, specialty, info: {total, unseen}, children, id…POST/folders?name=Projects
Create a folder → the new folder object
PUT/folders/{id}?name=Renamed
Rename →
{"ok": true}DELETE/folders/{id}
Delete folder + its messages →
{"ok": true}Emails
GET/emails?folder=INBOX&page=1&page_size=50
List / search. Filters:
subject, sender, recipient, contains, seen, flagged, sent_after, sent_before, as_thread (ISO-8601 dates with tz). Pagination via count/next_page (upstream headers).{
"count": "4", "next_page": "6415", "page": 1, "page_size": 50,
"results": [{ "uid": 8, "folder": "INBOX", "subject": "…", "snippet": "…",
"from": {"name": "Josh", "email": "…"}, "to": […], "date": "…",
"size": 314, "seen": false, "flagged": false, "answered": false,
"forwarded": false, "thread_uid": 8, "attachment_count": 0 }]
}
GET/emails/{uid}?folder=INBOX
Full message: headers, text+html bodies, flags, thread info,
attachment_info metadata.GET/emails/{uid}/raw
Raw RFC822 .eml download (
Content-Disposition: attachment).GET/emails/{uid}/attachments
All attachments as a single zip:
attachments-{uid}.zip.GET/attachments/{uid}?section=2&folder=INBOX
One attachment part as bytes (
section = MIME section from attachment_info; message_id optional).GET/search?q=invoice&folder=INBOX
Quick substring search →
{"count", "results"}Send & drafts
POST/send?mailbox=…
Send through the webmail API — no SMTP ports. Attachments are base64 → uploaded to the account's Files (simplefs) storage → attached by reference. Reply/forward threading via
in_reply_to + references.{ "to": [{"email": "a@b.c", "name": "?"}], "cc": [], "bcc": [],
"subject": "hi", "body_text": "…", "body_html": "<p>…</p>",
"attachments": [{"filename": "f.txt", "content_type": "text/plain", "data_b64": "…"}],
"in_reply_to": "<msgid>", "references": "…" } → { "ok": true, "result": {…async ack…} }
POST/drafts
Save a draft →
{"ok", "uid", "message_id", "folder"}PUT/drafts/{uid}?folder=Drafts
Update an existing draft →
{"ok": true, "result": …}POST/emails/{uid}/actions?folder=INBOX
Combine freely:
{"seen"?, "flagged"?, "move"?, "delete"?, "trash"?, "snooze"?} → {"ok", "background", "cancel_id"}. Bulk variant /actions/bulk?more_uids=9,10.Account & system
GET/account?mailbox=…
Account details: email, name, server, quota, config, session.
GET/sessions?mailbox=… DELETE/sessions/{id}
Active device sessions; revoke one (or
all).GET/logs?mailbox=…
Recent account activity (logins etc.).
GET/selftest?mailbox=…
Connection round-trip: login, folders, counts (+ optional probe send when
MXLOGIN_SEND_TO is set).Examples
Send with an attachment (base64):
curl -X POST "https://mxlogin-go.382972.xyz/send?mailbox=josh@120319.xyz" \
-H "X-API-Key: $MXLOGIN_API_KEY" -H "Content-Type: application/json" \
-d '{"to":[{"email":"dest@yourdomain.example"}],"subject":"hi","body_text":"hello",
"attachments":[{"filename":"f.txt","content_type":"text/plain",
"data_b64":"ZmlsZSBjb250ZW50"}]}'
List a folder:
curl "https://mxlogin-go.382972.xyz/emails?folder=INBOX&mailbox=josh@120319.xyz&api_key=$MXLOGIN_API_KEY"
mxlogin-go · Go rewrite with FastAPI-parity · github.com/madhatter349/mxlogin-go