Postbox — Personal Email

Per-user mailboxes with a webmail interface and native IMAP/SMTP support. Run your own Gmail-equivalent personal mailbox on your Owlat instance.

Postbox gives every team member a personal mailbox on your Owlat domain — with a webmail interface and full IMAP/SMTP so they can use any native client (Apple Mail, Thunderbird, mobile mail apps).

It's separate from marketing campaigns and the shared team inbox. Postbox is for everyday person-to-person email; campaigns are for bulk sends; the team inbox is for shared triage.

Feature flag

Postbox is off by default. Enable it from Settings → Features or run owlat-setup feature postbox on. Activating the flag also activates the personal-mail Docker Compose profile, which starts the IMAP server (apps/imap).

There are two ways to run personal mail on Owlat. A hosted mailbox (the postbox flag) is an Owlat-hosted address on a domain you've verified — Owlat is the mail server. Alternatively you can connect an external mailbox (the separate mail.external flag) and keep using your existing Gmail, Fastmail, or company account, with Owlat syncing it over IMAP/SMTP. They're independent flags; you can run either, both, or neither.

What you get

  • Per-user mailboxes with folders (Inbox, Sent, Drafts, Trash, Spam, Archive) plus custom labels
  • A webmail UI under /dashboard/postbox
  • Native IMAP4rev1 server (port 993, TLS) and SMTP submission for outgoing mail
  • App passwords for connecting native clients without exposing your account password
  • Address aliases — receive mail at multiple addresses into one mailbox
  • Per-mailbox filter rules (Sieve-like): match on from/to/subject/body, then move, label, mark read, star, forward, trash, or discard
  • Forwarding rules
  • Per-identity signatures
  • Vacation auto-responder with date ranges
  • Snooze: hide a thread until a date you pick
  • Scheduled send and an undo-send window
  • A personal address book that autocompletes recipients
  • Two composer modes (simple rich text, or the full block-based builder)
  • Search with Gmail-style operators
  • Threading across replies / forwards
  • Remote-image blocking and one-click quoted-text collapse when reading
  • Connect an external mailbox (separate mail.external flag): use your own Gmail / Fastmail / company account over IMAP+SMTP, no sending domain required

Setting up your mailbox

Mailboxes aren't created automatically on first visit — they're provisioned explicitly. There are two paths:

  • Admin pre-reservation at invite time — an admin can pick the address for a new member when they're invited, so the mailbox is waiting for them the moment they accept.
  • Self-service from Postbox settings — open Postbox → Settings → Add account, pick a localpart, and choose a verified domain from the dropdown (marcel + @yourdomain). The address is created on submit.
Creating a hosted mailbox is admin-gated

Provisioning a hosted mailbox requires admin permission (mailbox.create runs under admin context). You also need at least one verified domain — verify one under Settings → Domains first.

Once the mailbox exists:

  1. Open Postbox → Settings → Aliases and add any extra addresses you want to receive at. These must be on a domain that's already configured in Owlat with valid MX records pointing at your MTA.
  2. (Optional) Open Settings → Signatures and add a signature for each address you send from.

That's it for receiving mail. To send from a hosted mailbox you also need the sending domain configured under Settings → Domains (same DKIM/SPF setup as the marketing side).

Connect an external mailbox

If you don't want a hosted address — or you have no domain to verify — you can bring your own. The Connect external mailbox capability lets each user link an existing Gmail, Fastmail, iCloud, Outlook.com, or company account over IMAP + SMTP. Owlat keeps it in sync and lets you read, search, and send from it inside the same Postbox UI, without registering a sending domain.

This is a separate feature flag (mail.external) from hosted Postbox. Enabling it activates the external-mail Docker Compose profile, which starts the mail-sync worker (apps/mail-sync) that talks IMAP/SMTP to your provider.

Open the connect flow

Go to Postbox → Settings → External mailbox (or Add account → Connect external mailbox).

Pick a preset or enter your server details

Quick-setup buttons pre-fill IMAP/SMTP host and port for Gmail, Fastmail, iCloud, and Outlook.com. Otherwise enter your IMAP host/port and SMTP host/port manually, with the SSL toggle per server.

Enter your credentials

Provide the email address, username (defaults to the email address), and password. For Gmail / Outlook you'll need an app password with 2-factor enabled. Credentials are stored encrypted at rest — read queries never return them.

Test, then connect

Hit Test connection to verify IMAP and SMTP independently, then Connect mailbox. The mail-sync worker connects and begins syncing; the connection shows a live status (Connecting, Connected, Authentication failed, or Connection error).

External vs. hosted

An external mailbox is not authoritative on your local MTA — inbound mail is still delivered by your provider and synced in, not by Owlat's MX. Outbound mail goes through your provider's own SMTP. You can update credentials or disconnect at any time from the same page; disconnecting stops sync but retains already-synced messages.

Composing mail

From any folder click Compose. The composer supports rich text, attachments, reply/forward, drafts (auto-saved), and switching identities if you have multiple sending addresses on the mailbox. Recipient fields autocomplete from your personal address book, which builds itself automatically from the people you send to (separate from the org-shared CRM contacts).

There are two composer modes:

  • Simple — a fast in-house rich-text editor for everyday person-to-person mail.
  • Full — the block-based Owlat email builder, for when you want a designed, branded message.

Either way the body is rendered through the same email pipeline (boilerplate, CSS inlining, dark-mode handling) before it ships.

Scheduled send and undo-send

  • Undo send: after you hit Send, the message sits in a short pending window (30 seconds by default) before it actually dispatches. Click Undo within the window and the draft returns to the composer untouched.
  • Scheduled send: pick a future date and time and the draft is held until then, dispatched by a safety-net cron so it goes out even if nothing else is running.

Reading mail

Message bodies render in a sandboxed frame for safety. Two reading aids:

  • Remote images are blocked by default — external images don't load (and can't phone home) until you click Show images on the message. Inline and data-URI images always render.
  • Quoted text is collapsed — the original thread that a reply quotes is hidden behind a toggle, so you see the new message first and can expand the history when you want it.

Conversation view

The inbox can group messages by conversation (one row per thread, with a message count and unread badge) instead of one row per message. Toggle it with the conversation/list button in the inbox header. It's opt-in and inbox-only — the per-message list (with its hover and j/k keyboard triage) stays the default and serves every other folder.

AI: summarize & suggest replies

When the ai feature flag is on (it needs an LLM provider configured — see Feature flags), each open thread shows a Summarize button (2–4 bullet points) and Suggest replies (a few ready-to-send options; pick one to open a pre-filled reply). The output is advisory — it is never sent automatically, and the thread is treated as untrusted input.

Calendar invites

A message carrying a calendar invite (a text/calendar part, including the inline form Google Calendar and Outlook send) renders an invite card with the summary, time, location, and organizer. Accept / Maybe / Decline sends an RSVP back to the organizer with a standard METHOD:REPLY .ics attached.

Block a sender

Inside an open thread, Block sender is a one-click action: it creates a high-priority filter that routes all future mail from that address to Spam (or moves it to Trash if the mailbox has no Spam folder) and moves the current message to Spam.

Encrypted & signed mail (PGP / S-MIME)

Postbox detects PGP and S/MIME messages and labels them honestly — Encrypted (PGP) or Signed (PGP) · not verified. Owlat does not yet verify signatures or decrypt bodies, so it never shows a misleading "verified" check; encrypted bodies are flagged rather than rendered as gibberish, and inline clear-signed messages show their readable text.

Contacts

Postbox → Contacts is your personal address book. Addresses you send to are remembered automatically and power recipient autocomplete; the Contacts page lets you search, add, edit, and remove entries, or start a new message to one.

Filters

Settings → Filters lets you create rules that apply to incoming mail. Each rule has a list of match conditions (from / to / cc / subject / body, a custom header by name, message size with greater-than / less-than, and has attachment) and a list of actions: move to folder, add label, mark read, star, forward to…, move to trash, and discard (silent drop). Rules run in order; you can reorder them.

Discard vs. move to trash

Move to trash files the message in your Trash folder. Discard drops it silently — the message is not stored at all. Use discard for noise you never want to see.

Aliases & forwarding

  • Aliases: addresses that route into your mailbox. support@yourdomain and hello@yourdomain can both land in the same inbox without an actual second account.
  • Forwarding: addresses where copies should go out to. Useful for forwarding to an external address while keeping a copy locally.

Both are configured under Postbox → Settings.

Vacation responder

Under Settings → Vacation set a subject, message body, and date range. Owlat replies once per sender for the duration of the window.

Native clients (IMAP / SMTP)

Postbox runs a real IMAP4rev1 server (in apps/imap) and accepts SMTP submission through the MTA. To connect a native client:

  1. Go to Postbox → Settings → App passwords and generate one. The password is shown once; copy it now.
  2. In your mail client, add an account with:
    • IMAP: server mail.<your-domain>, port 993, encryption SSL/TLS, username <your-mailbox-address>, password <app-password>
    • SMTP: server mail.<your-domain>, port 587 (STARTTLS), same username and app password

You can issue multiple app passwords — one per device — and revoke any of them individually.

App-password scope

An app password authenticates a single mailbox. It does not grant access to the Owlat dashboard, API, or other mailboxes. Revoking it kicks the corresponding IMAP/SMTP session within seconds.

Postbox search supports a subset of Gmail's operators. Combine them in a single query.

OperatorExampleMatches
from:from:alice@acme.comMessages from this address
to:to:billing@yourdomainMessages sent to this address
subject:subject:invoiceSubject contains this text
has:attachmenthas:attachmentHas at least one attachment
has:no-attachmenthas:no-attachmentNo attachments (single hyphenated token)
is:unreadis:unreadNot yet marked as read
is:readis:readMarked as read
is:starredis:starredFlagged / starred
in:in:trash, in:sent, in:spamIn a specific system folder
label:label:newslettersHas a specific custom label
before:before:2026-04-01Received before a date (YYYY-MM-DD)
after:after:2026-01-01Received after a date
older_than:older_than:7dOlder than N days (also h hours, m minutes)
newer_than:newer_than:30dNewer than N days (also h, m)

Plain words match against subject, body, sender, and recipient. Quote phrases for an exact match: "quarterly review".

Snooze

Open any thread and click the snooze icon. Pick a date and it disappears from the inbox until then — at which point it reappears at the top, untouched.

How Postbox relates to other Owlat features

PostboxTeam InboxMarketing
Flagpostboxinboxcampaigns / automations / transactional
Per-user mailboxYesNo (shared)n/a
IMAP/SMTPYesNoNo
OutboundOne-to-one mailRepliesBulk + triggered
Receives MX mailYes (own aliases)Yes (shared addresses)No
ThreadingYesYesn/a

You can run any combination — Postbox alone, marketing alone, both together. There's no requirement to enable one before the other.

A connected external mailbox (mail.external) is a third option that fits alongside the hosted Postbox column: it surfaces in the same webmail UI, but inbound mail is delivered and outbound mail is sent by your own provider, so it needs neither MX records nor a verified sending domain on Owlat.

Limits & privacy

  • Mailboxes live in the same Convex deployment as the rest of your data. They aren't shared with other tenants.
  • The MTA caps per-message submission size and connection-pool usage, and rate-limits the IMAP authentication endpoint (failed logins are tarpitted) (see Self-hosting → Production).
  • Inbound spam filtering uses the same content scanner that protects campaigns (scan.content flag).
  • File attachments are scanned by ClamAV when scan.files is on.

Troubleshooting

I don't see "Postbox" in the sidebar. The flag isn't on yet. Toggle it from Settings → Features or owlat-setup feature postbox on, then restart the stack.

IMAP says "auth failed". Confirm you're using an app password, not your dashboard password. App passwords are bound to a single mailbox address — use that address as the username.

Outbound mail bounces. The sending domain isn't verified yet. Open Settings → Domains, add the domain, and apply the DNS records shown.

A native client can't reach the IMAP server. Check that port 993 is published on the host and that IMAP_GREETING_HOST resolves to the same hostname your TLS cert is issued for.

My external mailbox shows "Authentication failed". Re-enter the password on Settings → External mailbox → Update credentials. Gmail and Outlook need an app password with 2-factor enabled — your normal account password won't work. The mail.external flag (and its external-mail Docker profile / mail-sync worker) must also be running.

For deeper architecture details (schema, IMAP command flow, MTA integration) see Postbox architecture.