Guides
Migrating from Resend
Side-by-side comparison of Resend and Sendr endpoints to help you migrate.
Sendr's API is intentionally similar to Resend's. Most migrations take under an hour.
Package swap
# Remove Resend SDK
npm remove resend
# Install Sendr SDK
npm install sendr
Initialization
// Before (Resend)
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
// After (Sendr)
import { Sendr } from "sendr";
const sendr = new Sendr(process.env.SENDR_API_KEY);
Sending emails
The core send call is nearly identical:
// Before (Resend)
const { data, error } = await resend.emails.send({
from: "hello@acme.com",
to: "user@example.com",
subject: "Hello",
html: "<p>Hello!</p>",
});
// After (Sendr)
const email = await sendr.emails.send({
from: "hello@acme.com",
to: "user@example.com",
subject: "Hello",
html: "<p>Hello!</p>",
});
Key differences:
- Sendr throws errors instead of returning
{ data, error }— wrap in try/catch - Sendr returns the email object directly (not nested in
data)
Error handling
// Before (Resend)
const { data, error } = await resend.emails.send(params);
if (error) {
console.error(error.name, error.message);
}
// After (Sendr)
import { ApiError, RateLimitError, AuthenticationError } from "sendr";
try {
const email = await sendr.emails.send(params);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error("Bad API key");
} else if (error instanceof RateLimitError) {
await sleep(error.retryAfter * 1000);
} else if (error instanceof ApiError) {
console.error(error.statusCode, error.code, error.message);
}
}
REST API endpoint mapping
| Feature | Resend | Sendr |
|---|---|---|
| Send email | POST /emails | POST /v1/emails |
| Get email | GET /emails/:id | GET /v1/emails/:id |
| Update email | PATCH /emails/:id | — |
| Cancel email | POST /emails/:id/cancel | DELETE /v1/emails/:id |
| List emails | GET /emails | GET /v1/emails |
| Send batch | POST /emails/batch | POST /v1/emails/batch |
| Create domain | POST /domains | POST /v1/domains |
| List domains | GET /domains | GET /v1/domains |
| Get domain | GET /domains/:id | GET /v1/domains/:id |
| Verify domain | POST /domains/:id/verify | POST /v1/domains/:id/verify |
| Delete domain | DELETE /domains/:id | DELETE /v1/domains/:id |
| Create API key | POST /api-keys | POST /v1/api-keys |
| List API keys | GET /api-keys | GET /v1/api-keys |
| Delete API key | DELETE /api-keys/:id | DELETE /v1/api-keys/:id |
| Create webhook | — | POST /v1/webhooks |
| Get webhook | — | GET /v1/webhooks/:id |
| List webhooks | — | GET /v1/webhooks |
All Sendr endpoints are prefixed with /v1/.
Environment variable rename
# .env
# Before
RESEND_API_KEY=re_abc123
# After
SENDR_API_KEY=sndr_live_abc123
React Email compatibility
Sendr is fully compatible with React Email components. No changes needed:
import { render } from "@react-email/render";
import WelcomeEmail from "./emails/welcome";
const html = await render(<WelcomeEmail name="Alice" />);
await sendr.emails.send({
from: "hello@acme.com",
to: "alice@example.com",
subject: "Welcome!",
html, // React Email rendered HTML works as-is
});
Features available on Sendr but not Resend
- Marketing emails —
POST /v1/emails/marketingwith automaticList-Unsubscribeheaders - Campaigns — broadcast to contact lists with scheduling and analytics
- Audiences & Contacts — built-in subscriber management
- Test mode — test-mode API keys capture emails to a Test Inbox
- Overage billing — continue sending beyond monthly quota instead of hard cutoff
- Analytics — built-in delivery stats, open/click rates, and benchmarks
Webhook event name differences
| Event | Resend | Sendr |
|---|---|---|
| Delivered | email.delivered | email.delivered |
| Bounced | email.bounced | email.bounced |
| Opened | email.opened | email.opened |
| Clicked | email.clicked | email.clicked |
| Complained | email.complained | email.complained |
Webhook event names are identical — no changes needed if you're already processing Resend events.
Checklist
- Replace
resendpackage withsendr - Update import from
ResendtoSendr - Change
RESEND_API_KEYtoSENDR_API_KEY - Prefix REST API URLs with
/v1/ - Update error handling from
{ data, error }pattern to try/catch - Create API keys in Sendr dashboard
- Verify sending domains in Sendr dashboard
- Update webhook endpoints (if any) — event names unchanged