A booking platform needs email. Customer gets a confirmation. Tenant gets a "you have a new booking" alert. Referrer gets a "your referral just converted" credit notice. The interesting bit isn't sending those — it's making them look like they come from the tenant, not the platform, while still being deliverable, threadable, and manageable.
This post is about the design calls we made.
The "From:" problem
When Acme Spaces gets a booking, the customer's inbox should read:
From: Acme Spaces <bookings@acme.com>
NOT
From: Orkestr <notifications@orkestr.in>
Subject: Your booking on Acme is confirmed
The customer's relationship is with Acme. We're plumbing.
There are three architectural paths. We mapped them to our existing plan tiers:
| Tier | What customer sees | Cost |
|---|---|---|
| STARTER (free) | Acme Spaces <notifications@orkestr.in> |
Display-name override per send. One Resend domain. |
| GROWTH ($49) | Acme Spaces <bookings@acme.orkestr.in> |
Per-tenant subdomain via Resend Domains API + Cloudflare wildcard. Programmatic. |
| PRO ($199) | Acme Spaces <bookings@acme-spaces.com> |
Tenant brings their own domain, adds DNS records once, full white-label. |
Tier 1 is what shipped this week. Tiers 2 and 3 are queued.
Why we picked Resend over Klaviyo, SendGrid, etc
The full comparison is in the docs, but the punchline: Klaviyo is built for "one merchant, one Klaviyo account". Running a tenant per Klaviyo account at our pricing would be $2,000/month before we sent a single email. SendGrid's multi-tenant story is sub-users, which is clunky. Resend gave us a single REST API, a great free tier (3k/month, 100/day), and Domains-API control so we can register tenant domains programmatically when we get to tier 2 + 3.
RFC2822 threading
Inbound → /v1/email/inbound → resolve tenant from local-part → find-or-create Thread → write Message. Reconnection back into the same conversation uses the standard References + In-Reply-To headers. Outbound (reply from /provider/inbox) writes a Message-ID we control so the customer's reply slots back into the same thread.
The platform inbox
A subtle gotcha: support@orkestr.in, legal@orkestr.in,
dpa@orkestr.in — these aren't tenants. We lazily provision a system
tenant with subdomain platform and route them all to it. Admin sees
them in /admin/inbox with a "PLATFORM" badge. No dropped mail.
What we deliberately didn't build
IMAP server. A real "open this inbox in Apple Mail" would need either Gmail/Outlook OAuth (Google's verification is calendar-weeks) or running our own IMAP server (Dovecot + custom adapter, multi-week + ops burden). We shipped two pragmatic shortcuts instead:
- Forward-to address — per tenant, every inbound message also gets sent to their personal email. They use their normal mail app for reading.
- Resend SMTP relay — published in
/provider/settings/emailfor outbound from native mail apps, with a clear note that the mail-app path bypasses inbox tracking.
We also laid the BYO-mailbox foundation: schema for IMAP/SMTP
credentials, encrypted via the same AES-256-GCM cipher we use for
integration credentials, plus a connect-and-test form. The actual
IMAP fetch loop using imapflow + mailparser is the next
focused commit.
What we got right
- Reusing existing primitives. The email-mirror hook on the notification pipeline meant adding new transactional emails costs ~5 lines.
- Honest stubs over half-built features. When a feature isn't fully wired we return HTTP 501 with a clear message, not silent no-ops.
- One schema for inbox + mailbox. Inbound from Resend and inbound from a future IMAP poll both land in the same Thread/Message tables.
What we got wrong
The plus-addressing scheme for tenants (acme+booking@orkestr.in)
seemed clever — until we realised some inbound mail clients strip the
extension before routing. So we ended up with a simpler rule:
<subdomain>@orkestr.in for tenants, period. Plus-extensions still
work for the future "departments" feature but we don't rely on them
for routing.
If you're building a multi-tenant platform that needs email, try us free — the inbox + email layer is one of the bits we're most proud of.