Migrate from Resend to PostStack
The same developer experience on EU infrastructure. Paid plans start at €5, not $20.
Resend and PostStack are intentionally similar at the wire level — both expose a typed TypeScript SDK over a clean REST API, both authenticate with a Bearer API key, and both use lowercase JSON keys (`from`, `to`, `subject`). The migration is mostly a search-and-replace, plus a DNS update so receiving MTAs can verify mail leaving the PostStack outbound IPs. Most teams complete the cutover in under an hour. The bigger gains come after: PostStack is up to 71% cheaper at the entry tier, hosts IMAP mailboxes on the same domain, and runs entirely inside the European Union.
Why switch from Resend?
- Paid plans start at €5/month. Resend has no paid tier below $20
- Save up to 71% on your bill at the entry tier and 55–57% at high volumes
- IMAP and POP3 mailboxes, webmail, and DMARC aggregate reports, none of which Resend ships
- EU data residency in Helsinki, Finland, not US data centers
- The same send-call shape (`from`, `to`, `subject`, `html`), so most teams cut over in under an hour
Price comparison
Competitor prices are public list prices (USD) verified September 2026; PostStack prices are in EUR. Figures are approximate after currency conversion — check each provider's pricing page for current rates.
| Volume | Resend | PostStack | Savings |
|---|---|---|---|
| 3,000/mo | Free | €0 | - |
| 10,000/mo | ~$20/mo | €5/mo | ~71% |
| 50,000/mo | ~$20/mo | €15/mo | ~14% |
| 100,000/mo | ~$35/mo | €30/mo | ~2% |
| 500,000/mo | ~$350/mo | €130/mo | ~57% |
| 1,000,000/mo | ~$650/mo | €255/mo | ~55% |
Code migration
Before (Resend)
import { Resend } from 'resend';
const resend = new Resend('re_...');
await resend.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Hello!',
html: '<h1>Welcome!</h1>',
});After (PostStack)
import { PostStack } from '@poststack.dev/sdk';
const poststack = new PostStack('sk_live_...');
await poststack.emails.send({
from: 'hello@yourdomain.com',
to: ['user@example.com'],
subject: 'Hello!',
html: '<h1>Welcome!</h1>',
});Feature comparison
| Feature | Resend | PostStack |
|---|---|---|
| REST API | Yes | Yes |
| TypeScript SDK | Yes | Yes |
| Webhooks | Yes | Yes |
| Email Templates | Yes | Yes |
| Broadcasts | Yes | Yes |
| Contact Management | Yes | Yes |
| Open/Click Tracking | Yes | Yes |
| SMTP Relay | Yes | Yes |
| Inbound Email + Webhooks | Limited | Yes |
| IMAP/POP3 Mailboxes | No | Yes |
| Visual Email Builder | Broadcasts editor | Yes |
| DMARC Aggregate Reports | No | Yes |
| Workflow Automation | Yes (billed per run) | Yes (included) |
| Embeddable Signup Forms | No | Yes |
| EU Data Residency | No | Yes |
| Dedicated IP | $30/mo add-on (Scale, 3,000+/day) | €25/mo add-on (any paid plan) |
API mapping
Side-by-side reference for the most common operations as you migrate.
| Concept | Resend | PostStack |
|---|---|---|
| Send transactional email | resend.emails.send({ from, to, subject, html, ... }) | poststack.emails.send({ from, to, subject, html, ... }) |
| Send with attachments | attachments: [{ filename, content }] | attachments: [{ filename, content }] |
| Send with React Email | react: <WelcomeEmail name="Alice" /> | html: render(<WelcomeEmail name="Alice" />) — pre-render then pass html |
| Add a domain | resend.domains.create({ name }) | poststack.domains.create({ name }) |
| Manage contacts and audiences | resend.contacts.create({ audience_id, email }) | poststack.contacts.create({ email }), then poststack.segments.addContacts(id, { contact_ids }) |
| Send a broadcast | resend.broadcasts.send(id) | poststack.broadcasts.send(id) |
| Webhook signature verification | Svix signature header (Resend uses Svix under the hood) | X-PostStack-Signature header, HMAC-SHA256 of the raw request body |
Migration gotchas
React Email needs to be pre-rendered
Resend accepts a raw `react: <Component />` prop and renders server-side internally. PostStack expects `html` to be a string, so call `@react-email/render`’s `render()` first and pass the result. Same component, one extra line.
API key prefix differs
Resend keys begin with `re_…`; PostStack keys with `sk_live_…` (production) or `sk_test_…` (sandbox). Keep them in distinct env vars so nothing crosses over during the cutover.
DNS records change, not domain verification status
Your domain’s SPF, DKIM, and DMARC records need to point at PostStack’s SPF include and our generated DKIM selectors. Keep Resend’s records live during the staged cutover — receiving MTAs will accept mail from whichever provider actually sent it as long as DKIM aligns.
Webhook payload shape
Both providers send a JSON event with `type` and `data`. The field names inside `data` differ. Run a quick adapter in your webhook handler during the transition, or subscribe to both providers in parallel for a day to confirm parity before cutting Resend webhooks off.
Migration steps
- 1Sign up for PostStack and get your API key
- 2Install the PostStack SDK: npm install @poststack.dev/sdk
- 3Add your domain and verify DNS records
- 4Replace the Resend SDK import with PostStack
- 5Update your API key to your PostStack key
- 6Test in development, then switch production traffic
Frequently asked questions
How long does the migration take?
Most teams finish in under an hour: sign up, verify a domain (DNS propagation aside, this is a few minutes), swap the SDK import, and deploy. The DNS propagation is the longest single step.
Can I run Resend and PostStack in parallel?
Yes — there is no exclusivity at the DNS or SMTP layer. Add PostStack as a second sending provider, route 10% of traffic to it, verify deliverability matches, then ramp to 100%. The dual-provider window also lets you compare webhook payloads side-by-side.
Do I need to re-verify my domain?
Yes — every email provider verifies domains independently via DNS records (SPF include, DKIM CNAMEs, DMARC). PostStack auto-generates the records when you add a domain, and you can keep Resend’s records in parallel during the cutover.
What about my existing suppression list?
Export it from Resend and import it into PostStack — the dashboard accepts a CSV of up to 10,000 addresses at a time, and single entries can be added over the API. The list is enforced from the next send.
Will my open and click tracking continue?
Yes. PostStack inserts the open pixel and rewrites click links the same way Resend does. The tracking pixel and link redirect are PostStack-hosted, so tracked links in new emails point at PostStack instead of Resend. Links in emails you already sent through Resend keep working through Resend.
What if I am using Resend Audiences and Broadcasts?
PostStack has matching APIs for contacts, segments, broadcasts, and subscription topics; a Resend audience maps to a PostStack segment. Export your audience as CSV from Resend, import the contacts into PostStack, and add them to a segment (or recreate it as a rule-based segment). Broadcasts are created against a segment and sent with `broadcasts.send(id)`, just as on Resend.