MailVault
Live for early-access accounts

Forward your domain’s mail to the inbox you already use

Claim a domain, publish two DNS records, and every alias you add forwards to a real mailbox. Messages are authenticated on arrival and relayed unchanged, with the sender’s DKIM signature intact — and nothing is kept once they are delivered.

what you run
$ mailvault domain add example.com
‹ prints a TXT and an MX record to publish ›

$ mailvault domain verify example.com
domain:  example.com
status:  verified

$ mailvault addr add hi@example.com --to you@gmail.com
address:      hi@example.com
forwards to:  you@gmail.com
No dashboard. Every step is a command with JSON output and exit codes a script can branch on.
what reaches you@gmail.comtop of the headers
Authentication-Results: mx.mailvault.sh;
  spf=pass smtp.mailfrom=corp.example;
  dkim=pass header.d=corp.example;
  dmarc=pass header.from=corp.example
Received: from mail.corp.example
  by mx.mailvault.sh
DKIM-Signature: v=1; d=corp.example; …
From: Dana <dana@corp.example>
To: hi@example.com
Subject: quarterly numbers
Two headers are added at the top. Everything below them — including the sender’s signature — is the original message, byte for byte.

How a message travels

Forwarding happens while the sending server is still connected. There is no queue on our side, so nothing of yours sits anywhere waiting to be sent.

  1. It arrives

    A sending server delivers to our MX over TLS. Addresses you have not added are refused before the message is sent.

  2. We authenticate it

    SPF, DKIM, DMARC and blocklists run on the message and decide whether to accept it.

  3. We relay it unchanged

    The original bytes go on to each destination, with the verdict added as a header.

  4. Or the sender retries

    If a destination cannot take it right now, the sending server is told to try again later.

Quick-start

You need an early-access account with the mailvault CLI signed in, and access to your domain’s DNS.

  1. Claim the domain

    Adding a domain prints the two records to publish: a TXT record that proves the domain is yours, and the MX record that sends its mail to us.

    $ mailvault domain add example.com
    domain:  example.com
    id:      3f1c9a2e-…
    status:  pending
    
    Publish this DNS TXT record to prove the domain is yours:
    
      name:   _mailvault.example.com
      value:  mailvault-verify=…
    
    Publish this DNS MX record so mail reaches the server:
    
      name:      example.com
      priority:  10
      value:     mx.mailvault.sh
    
    Then run:  mailvault domain verify example.com

    The MX record moves all of the domain’s mail to us. If the domain already receives mail somewhere else, add the aliases you need before you change it.

  2. Verify it

    Once the TXT record has propagated, verification marks the domain ready. Mail to a domain that is not verified yet is refused.

    $ mailvault domain verify example.com
    domain:  example.com
    status:  verified

    DNS can take a while. Exit code 8 means the record was not found yet, and 7 means the lookup itself failed; both are worth retrying, so a script can wait on them:

    $ while true; do
        mailvault domain verify example.com && break
        case $? in 7|8) sleep 60 ;; *) exit 1 ;; esac
      done
  3. Add an alias

    Write the address the way you would send to it. --to can be repeated, or take a comma-separated list, to forward one address to several mailboxes.

    $ mailvault addr add hi@example.com --to you@gmail.com
    address:      hi@example.com
    forwards to:  you@gmail.com
    endpoints:
    id:           8b7d0c41-…
    
    # one address, two mailboxes
    $ mailvault addr add team@example.com --to ana@gmail.com,ben@proton.me

    Send a message to hi@example.com. It reaches your mailbox while the sending server is still connected.

  4. Change it any time

    Addresses change without touching DNS. addr set replaces only what you name and keeps the rest.

    $ mailvault addr set hi@example.com --to new@gmail.com
    $ mailvault addr set hi@example.com --disable   # refuse its mail for now
    $ mailvault addr set hi@example.com --enable
    $ mailvault addr rm hi@example.com              # asks first; --force skips it
    $ mailvault addr list --domain example.com

Reference

What we keep

Nothing. A message is relayed while the sending server waits on the line, and is neither written down, queued nor copied. If a destination refuses it for now, the sending server is told to retry, and holding the message stays its job.

Authenticating a message means reading it: mail is decrypted in our process so SPF, DKIM and DMARC can check it. What we promise is what happens after that, and it is the whole design.

What you receive

The message is relayed byte for byte, with two headers added above it. Because nothing below them changes, the sender’s DKIM signature still verifies at your mailbox, so a message the sender signed still passes DMARC there — even though its envelope sender is now ours and SPF no longer lines up.

HeaderWhat it tells you
ReceivedThe standard trace line: the server that delivered to us, and our hostname.
Authentication-ResultsOur SPF, DKIM, DMARC and blocklist verdicts. Any header claiming to be ours that arrived with the message is renamed X-Original-Authentication-Results, so it cannot pass for the real one.
X-MailVault-ActionPresent only as quarantine: the message looked doubtful but not bad enough to refuse. It is forwarded anyway, since there is no folder on our side to hold it — filter on this header in your mailbox.

A message that fails outright is refused while the sender is connected, so it never reaches you and never leaves our servers.

Address rules

RuleWhy
At most 10 destinations per addressEach one is a separate delivery made while the sender waits.
No destination on a domain you host hereIt would forward back to us and loop.
Unknown and disabled addresses are refusedThe sender hears it before the message is sent, and nothing is relayed.
One address per local partAdding one that exists fails with exit code 5; change it with addr set.

Bounces

Forwarded mail leaves with our bounce address as its envelope sender. If a destination later bounces a message it had accepted, that bounce comes back to us and goes no further, so the original sender does not hear about it. Keep destinations to mailboxes that exist; rewriting the sender so bounces can find their way back is on the roadmap.

Catch-alls

A catch-all, written as @example.com, does not forward to a mailbox. It accepts every local part anyone tries, and relaying those guesses would spend the sending reputation your aliases depend on. Add an alias for each address you use, or deliver the catch-all to your own endpoint.

Exit codes

Every command uses the same codes, and --output json prints machine-readable results and errors.

CodeMeaning
0Success.
1Unexpected failure.
2Bad flags, arguments or configuration; nothing was sent.
3The API key was missing or refused.
4No such domain, address or key.
5It already exists.
6The server rejected the input.
7Network failure, server error or DNS outage. Retry.
8The domain’s TXT record was not found yet. Retry.