How it Works
A full in-depth explanation of Relais’ architecture and how it works.
Overview
Relais runs as a Next.js app deployed on Vercel, backed by a PlanetScale Postgres database. The mail server uses Stalwart, running in Docker.
Outbound email is currently relayed through AWS SES while the server’s IP reputation builds.
The key thing to understand: Relais never stores your email. It acts only as a relay; email comes in through Stalwart, gets passed to the Gmail API, and is immediately discarded from the mail server.
DIAGRAM GOES HERE
Inbound Email (Receiving)
Inbound email in Relais consists of the following 3 steps:
- DNS MX records that point the user’s custom domain to Relais’ Stalwart endpoint. This tells the sender “where” the user’s mail server domain should be located.
- The Stalwart endpoint contains Mail Transfer Agent hooks, which on email receive, fires a webhook to the Relais server to notify and to send the new email to the webhook endpoint.
- The Relais webhook endpoint triggers, and forwards the email into the user’s Gmail inbox.
MX Resolution
When a user adds their domain to Relais, they need to configure a DNS MX record that points their domain to mail.relais.sh, Relais’ Stalwart mail server. When someone sends an email to you@yourdomain.com, their email provider performs a DNS lookup, finds this MX record, and knows where to deliver the message to.
Stalwart MTA Hooks
Stalwart uses a feature called MTA Hooks, which are essentially webhooks that fire at different stages of an SMTP transaction. Relais hooks into two stages:
- RCPT stage: When the sender’s mail server (e.g. Gmail) wants to deliver an email to
you@yourdomain.com, Stalwart checks if the domain is registered with Relais (via its local database). If it isn’t, it rejects the email with a status code550, notifying the sender that the domain is unreachable. If it is registered, Stalwart accepts the recipient and continues processing. - DATA stage: Once the full email body has been received, Stalwart fires another webhook with the complete message (ex. headers, body, etc.). Relais reconstructs the raw RFC 822 email, base64-encodes it, and hands it off to a delivery workflow. It then notifies Stalwart to “discard” the message, meaning Stalwart never stores it.
If Relais is temporarily unreachable (say, Vercel has an outage), Stalwart responds with a temporary failure. The sender’s mail server will queue the message and retry for up to 5 days (standard SMTP behavior).
Gmail Delivery
Once Stalwart fires webhooks to the Relais server, Relais does a database query, figuring out which Gmail account should receive the email. It checks for an exact address match first (e.g. support@yourdomain.com) if configured, then falls back to a catch-all route, and finally the domain owner’s account. The email is then “inserted” into the user’s Gmail inbox via the Gmail API messages.insert with the appropriate labels (e.g. INBOX, UNREAD). Since different functions in this webhook endpoint are subject to failure, “workflow” functions provided by Vercel Workflow are used, which on transient errors are automatically re-enqueued for execution.
Outbound Email (Sending)
Outbound email is a bit trickier since major email providers such as Gmail and Outlook take massive measures in what’s considered “spam”.
Emails sent to email providers from new IPs commonly have low IP reputation (whether that be from being on a spam blocklist previously, just being new, or both). With that being said, it is strongly recommended to use a reputable SMTP service such as AWS SES to avoid the cold-start problem.
Currently, Relais uses Stalwart as a relay, routing outbound emails to AWS SES, while it’s domain and IP are warming up. This is why you might see DNS TXT records containing amazonses when setting up outbound email.
Outbound email in Relais consists of the following 3 steps:
- The user configures “Send As” in Gmail with SMTP credentials generated by Relais, pointing to the Stalwart mail server.
- When the user sends an email, Gmail connects to the Relais Stalwart server over SMTP (port 587,
STARTTLS), authenticates, and submits the message. - Stalwart relays the message through AWS SES, which DKIM-signs it and delivers it to the recipient.
Gmail Send As
To send email from your custom domain, you can use use Gmail’s built-in “Send mail as” feature. When an address is set up in Relais, it generates a unique set of SMTP credentials (a username and a cryptographically random password) and creates a corresponding account on the Stalwart server.
You can then use these credentials inside Gmail’s “Send mail as” settings under Settings > Accounts and Import > Send mail as. Afterwards, you’ll be able to select your custom domain as the “From” address when composing any email.
SMTP Submission
When a user hits “Send” in Gmail using their custom domain identity, Gmail opens an SMTP connection to mail.relais.sh on port 587 with STARTTLS encryption. It authenticates using the credentials from the previous step and submits the message. Stalwart accepts the authenticated submission and queues it for outbound delivery.
SES Relay
(Stalwart routes outbound mail through AWS SES, which DKIM-signs and delivers)
Instead of delivering the email directly to the recipient’s mail server (which would likely get caught in spam with a fresh IP), Stalwart routes outbound mail through AWS SES. SES KIM-signs the message using Easy DKIM and delivers it on Relais’ behalf. The recipient sees From: you@yourdomain.com with passing DKIM, SPF, and DMARC with no indication that the email was relayed unless the email’s headers are inspected.
DNS Records
When adding a domain to Relais, you’ll need to configure several DNS records. These records allow different servers to do a lookup of where your domain’s mail should be located, and to prove that you’ve authorized Relais to send on your behalf.
| Record | Type | Host | Value | Purpose |
|---|---|---|---|---|
| MX | MX | @ | mail.relais.sh (priority 10) | Tells senders where to deliver email for your domain |
| SPF | TXT | @ | v=spf1 ip4:<server-ip> include:amazonses.com -all | Authorizes the mail server and SES to send on your behalf |
| DKIM | CNAME | <token>._domainkey (×3) | <token>.dkim.amazonses.com | Proves emails haven’t been tampered with in transit |
| DMARC | TXT | _dmarc | v=DMARC1; p=quarantine | Tells recipients what to do if SPF/DKIM fail |
Exact values for your domain will be provided after adding it in the dashboard. The DKIM records are three CNAME entries, this is specific to AWS SES’s “Easy DKIM” setup, where SES manages the key rotation for you.
Authentication
Google OAuth
Relais uses Google OAuth for sign-in. When you first connect your account, Google asks you to grant Relais the gmail.insert scope, this is a narrow, write-only permission that lets Relais place emails into your inbox (i.e. new emails sent to your custom domain). It cannot read, search, modify, or delete any of your existing email.
Behind the scenes, Google issues an access token (short-lived) and a refresh token (long-lived). Relais stores these encrypted in its database and uses them to call the Gmail API when delivering inbound email. If you ever want to revoke access, you can do so from your Google Account permissions page.
SMTP Credentials
Each “Send As” address gets its own set of SMTP credentials. When setting up an outgoing email for an address, Relais generates a cryptographically random password and creates a corresponding account on the Stalwart server.
Webhook Security
Stalwart authenticates its webhook requests to Relais using a shared secret sent in a custom X-Hook-Secret header. Relais validates this using a timing-safe comparison to prevent brute-force timing attacks.
A custom X-Hook-Secret header is used instead of the Authorization header because Vercel’s edge network strips Authorization headers during domain redirects (e.g., apex to www). In contrast, a custom header passes through intact.