Sentroy vs Resend
Resend is a polished managed email API. Sentroy is an open platform where transactional email is one of several bundled services (mail, storage, auth, env vault). This page is an honest side-by-side so you can pick the right one for your team — and a migration snippet if you decide to switch.
Quick comparison#
The five questions most teams actually care about when picking a transactional email vendor.
| Sentroy | Resend | |
|---|---|---|
| Pricing model | Flat platform tier; mail volume not metered per send | Per-email metered ($/email above free tier) |
| Self-hostable | Yes — Postfix/Dovecot/Rspamd stack ships as IaC | No — managed only |
| Open formats | MJML templates, raw MIME, IMAP-backed inbox | React Email components, raw HTML |
| Lock-in | Low — standards-based, exportable, can stand up your own copy | Moderate — proprietary API + dashboard, no self-host path |
| Bundled with other products | Storage + auth + env vault + status pages, one tenant | Email-only; pair other services yourself |
What is the same#
The places these two products meaningfully overlap.
- Both expose a clean REST API for transactional send with Bearer-token auth.
- Both handle DKIM, SPF, and DMARC for verified domains.
- Both deliver webhook events for
sent,bounced,opened,clicked, andunsubscribed. - Both support per-domain webhook scoping with HMAC-signed payloads.
- Both have first-class TypeScript SDKs with full typings.
- Both let you template once and reuse across sends.
What is different#
Honest differences in both directions — neither product is strictly better.
Where Sentroy is different
- Self-hostable end-to-end: the same Postfix/Dovecot/Rspamd stack we run in production ships as an IaC bundle.
- Multilingual templates as a first-class shape (
{tr, en, ...}per field) — no extra plumbing to ship locale-aware email. - IMAP-backed inbox API for reading replies, not just sending. Threading, folders, mark-as-read all included.
- Same access token also reaches storage, auth projects, and env vault — one credential per company.
- Flat pricing — send volume isn't the meter, so high-volume bursts don't spike the bill.
Where Resend is different
- Larger ecosystem of pre-built React Email templates and integrations.
- Longer track record on deliverability — more years of IP warmup and reputation history.
- Generous free tier for early-stage projects (3k emails / month at the time of writing).
- More polished dashboard for non-developers reviewing delivery metrics.
- SOC 2 Type II audited; some regulated buyers require this checkbox.
When to pick Sentroy#
Concrete situations where Sentroy is the better call.
- You want one vendor for email + file storage + auth, and you don't want to wire three SDKs and three billing relationships together.
- You ship a multilingual product and want template translations to live in the template itself, not in your application code.
- Your compliance team needs the option to self-host the mail stack on infrastructure you control (EU residency, HIPAA, etc.).
- You need both send and inbox in the same API — e.g. a support inbox that reads replies and threads them with the original transactional send.
When to stick with Resend#
Cases where staying on Resend is the right call — we'd rather you pick the right tool than churn after a month.
- You only need email and you already have storage / auth solved elsewhere — the bundle isn't a draw.
- You've invested heavily in React Email components and your team prefers JSX over MJML.
- You need a vendor with a multi-year audited deliverability record on day one of a regulated launch.
Migration#
One operation, both APIs side by side. Most ports take an afternoon — the SDK shape is intentionally familiar.
Sending a transactional email with a template and variables:
import { Resend } from "resend"
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: "Acme <onboarding@acme.dev>",
to: "user@example.com",
subject: "Welcome to Acme",
react: WelcomeEmail({ name: "Jane" }),
})import { Sentroy } from "@sentroy-co/client-sdk"
const sentroy = new Sentroy({
baseUrl: "https://sentroy.com",
companySlug: "acme",
accessToken: process.env.SENTROY_ACCESS_TOKEN!,
})
await sentroy.send.email({
from: "onboarding@acme.dev",
to: "user@example.com",
subject: "Welcome to Acme",
domainId: "<acme-domain-id>",
templateId: "<welcome-template-id>",
variables: { name: "Jane" },
})The Sentroy template lives on the server, so the body markup ships once and renders with whichever variables you pass at send time. Multilingual templates auto-pick the locale via the lang field.