Mailboxes
Purpose. A mailbox is an IMAP account (and POP3, unless POP3 is switched off server-wide with protocols.pop3) with a password, a Maildir and an optional quota. Dovecot authenticates against a view over the same table the API writes (v_dovecot_credentials; v_dovecot_users is the userdb and iterate source), so changes are live.
Behaviour.
POST /api/v1/domains/{id}/mailboxes{ localPart, password, displayName?, quotaBytes? }— local part lower-cased, 1–64 characters froma-z0-9._+-, starting and ending with a letter or digit, no consecutive dots; password ≥10 chars, stored as Argon2id; quota defaults to the domain default. Refused with402 license_degradedfrom the licence’sdegradedstage on, or402 license_limit_reachedat the licence’s mailbox limit (nothing is refused in grace or in an install’s 30-day evaluation); existing mail is unaffected. 409 if the address exists as a mailbox or alias.PATCH /api/v1/mailboxes/{id}—suspended:trueblocks login and inbound delivery (mail is rejected at SMTP, not queued) and ends every webmail session, so lifting the suspension does not bring them back (active:falsedoes the same);active:falseis the soft-delete equivalent; ending the sessions also holds every message the mailbox scheduled with Send later (Compose, send and drafts), so none goes on its own after the suspension is lifted: each waits in Scheduled, marked Not sent, for the owner to send, move or cancel;quotaBytes,displayName.sendingBlocked:falseis the one way to clear a containment block (Compromised-mailbox containment); it cannot be set totrueby hand, only by the worker.sendingBlockedis notsuspended. A mailbox blocked for outbound abuse still signs in, still receives, and still reads its mail — only submission is refused.sendingBlocked,sendingBlockedReasonandsendingBlockedAtare read-only on the mailbox and shown as a banner on its admin page.POST /api/v1/mailboxes/{id}/passwordresets the password and ends every webmail session of the mailbox, an administrator’s on-behalf session included; an access token already issued is refused on its next request, because its session has ended. IMAP sessions already open stay open until they reconnect, and app passwords keep working — they are separate credentials, revoked one by one. It holds every message the mailbox scheduled with Send later: none leaves on its own, and each waits in Scheduled, marked Not sent, until somebody sends, moves or cancels it, because which session scheduled one is not recorded. After a compromise, cancel there what the owner did not write.DELETEremoves the row, and with it the mailbox’s settings, its profile picture and every message it has waiting to be sent later or held; the Maildir on disk is kept (reclaim via backup/restore tooling — deliberate; a purge command is planned).- Export (owner and admin):
POST /mailboxes/:id/export→201 { url, expiresIn }, a single-use link valid five minutes;GETit to download<address>-<date>.tar.gz, one mboxrd file per folder (INBOX.mbox,Archive/2026.mbox), which Thunderbird, Apple Mail and most clients import. It holds the folders’ mail only: messages waiting in Scheduled and the profile picture are in the database, not in a folder, and are not in it. Read-only — no message is marked read. Adomain_admingets403, because managing a mailbox is not reading it, a system mailbox404, a server with no IMAP bridge503 export_unavailable. Audited when the link is spent (mailbox.export_started), thenmailbox.exportedwith the folder and message counts when the archive is complete, ormailbox.export_failedwhen it is not — so a download that breaks half-way still leaves a row. The admin console offers it on the mailbox page and in the delete confirmation. - Sending: authenticated submission on :587 (STARTTLS) / :465 (TLS) with the mailbox address as username; the envelope sender must be the mailbox or an alias that points to it (
reject_sender_login_mismatch). - Quota is enforced by Dovecot (
maildirquota backend).quotaBytes: 0is unlimited, and takes effect at once, also on a mailbox that had a limit before. A message that would exceed it is accepted, then deferred at delivery with452 4.2.2 Quota exceeded: it stays in this server’s mail queue and Postfix retries it, so it is delivered at the next retry (within about an hour) after the owner clears space or an admin raises the quota, and bounced to the sender only after five days (maximal_queue_lifetime). It shows on the Mail queue page meanwhile (quota_full_tempfail = yes, a top-level Dovecot setting). Through0.12.1it was refused with552 5.2.2and bounced at once. - Usage.
GET /api/v1/mailboxes/{id}/usage→{ mailboxId, address, quotaBytes, usedBytes, messages, percent, updatedAt };GET /api/v1/domains/{id}/usagereturns the same shape for every mailbox of the domain (unpaged). Figures come from Dovecot’squota_cloneplugin, which upsertsquota_usage(username, bytes, messages)through a pgsql dict on every change to the mailbox (delivery, expunge, move) — soupdatedAtisnulland the counters are0until the mailbox has received or changed something.percentisnullfor unlimited quotas and can exceed 100 after a quota is lowered. Deleting a mailbox removes its usage row. To rebuild a row from disk (e.g. after a restore) rundoveadm quota recalc -u <address>in thedovecotcontainer. - Opening a mailbox in the webmail. An owner or admin can open any active mailbox in the mail client as its owner sees it (
POST /api/v1/mailboxes/{id}/webmail-session), and an owner, admin or domain_admin can open their own (POST /api/v1/mailboxes/mine/webmail-session); both return a single-use hand-off URL that the webmail spends atPOST /api/v1/auth/handoff, and the access is audited under the administrator’s name (REST API, Admin UI).
Configuration. Outbound rate limit per sender, per hour (limits.perUserMessagesPerHour) and message size (limits.messageSizeBytes) are server settings (PUT /api/v1/server/config).
Limits & edge cases. The dmarc-reports@<first domain> mailbox is a hidden system mailbox (DMARC report ingestion, DMARC aggregate reports), and so is noreply@<first domain> once a password-reset link or a licence warning has been sent (Password reset by email, Licensing); neither is listed, deleted or given a password (409), and no token sends as one, because noreply@ is the one login the licence’s send stop lets through. Usage is reported by the daemons, not computed from disk by the API: a mailbox that has never had a delivery shows 0 even if its Maildir was restored from a backup. Address = localPart@domain is unique across mailboxes and aliases. Deleting a domain requires deleting its mailboxes first. App-specific passwords: App passwords and mailbox two-factor authentication. Filters and autoresponders: Mailbox filters & autoresponders.
App passwords and 2FA. A mailbox owner can mint per-device credentials for IMAP and SMTP and enrol a second factor for webmail; enabling the second factor makes app passwords the only way into a mail client, because IMAP cannot prompt for a code. See App passwords and mailbox two-factor authentication.