Migrate from Resend
Step-by-step guide to migrate from Resend to Postflare.
Overview
Postflare is an open-source, Resend-compatible email platform built on Cloudflare infrastructure. The API is designed to be a drop-in replacement for Resend, so migration typically requires minimal code changes.
Key advantages:
- Self-hosted — deploy on your own Cloudflare account for full data ownership
- Resend SDK compatible — use the official Resend SDK with a
baseURLoverride - Open source — audit, extend, and customize to your needs
Step 1: Create a Postflare Account
Sign up at app.postflare.app and create an organization. If self-hosting, deploy Postflare to your own Cloudflare account first.
Step 2: Configure Your Domain
Add your sending domain in the Postflare dashboard. If you already have SPF, DKIM, and DMARC records configured for Resend, you will need to update them to point to Postflare.
- Go to Domains in the dashboard
- Click Add Domain and enter your domain name
- Update your DNS records as shown in the dashboard
- Click Verify to confirm the records are correct
Step 3: Create an API Key
Create a new API key in the Postflare dashboard. Postflare uses the same re_ prefix format as Resend for API keys.
Step 4: Update Your SDK Configuration
The Resend SDK can be used directly with Postflare by overriding the baseUrl:
Node.js / TypeScript
import { Resend } from 'resend';
const resend = new Resend('re_your_new_postflare_key', {
+ baseUrl: 'https://api.postflare.app',
});
// All SDK methods work the same
const { data, error } = await resend.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Hello from Postflare',
html: '<p>It works!</p>',
});Python
import resend
- resend.api_key = "re_your_resend_key"
+ resend.api_key = "re_your_new_postflare_key"
+ resend.base_url = "https://api.postflare.app"
params: resend.Emails.SendParams = {
"from": "hello@yourdomain.com",
"to": ["user@example.com"],
"subject": "Hello from Postflare",
"html": "<p>It works!</p>",
}
email = resend.Emails.send(params)cURL
- curl -X POST 'https://api.resend.com/emails' \
+ curl -X POST 'https://api.postflare.app/emails' \
- -H 'Authorization: Bearer re_your_resend_key' \
+ -H 'Authorization: Bearer re_your_new_postflare_key' \
-H 'Content-Type: application/json' \
-d '{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Hello from Postflare",
"html": "<p>It works!</p>"
}'Step 5: Migrate Webhooks
If you use webhooks, create new webhook endpoints in Postflare. The webhook event format is compatible with Resend.
Postflare also supports additional event types not available in Resend:
| Event Type | Description |
|---|---|
domain.created | Domain was added |
domain.updated | Domain status changed |
domain.deleted | Domain was removed |
contact.created | Contact was created |
contact.updated | Contact was updated |
contact.deleted | Contact was deleted |
Step 6: Test
Send a test email to verify everything works:
const { data, error } = await resend.emails.send({
from: 'hello@yourdomain.com',
to: 'test@example.com',
subject: 'Migration Test',
html: '<p>Postflare is working!</p>',
});
if (error) {
console.error('Error:', error);
} else {
console.log('Email sent:', data.id);
}API Compatibility Reference
The following table lists all Postflare API endpoints and their Resend compatibility status.
Emails
| Endpoint | Method | Resend Compatible |
|---|---|---|
/emails | POST | Compatible |
/emails/batch | POST | Compatible |
/emails | GET | Compatible |
/emails/{id} | GET | Compatible |
/emails/{id} | PATCH | Compatible |
/emails/{id}/cancel | POST | Compatible |
Domains
| Endpoint | Method | Resend Compatible |
|---|---|---|
/domains | POST | Compatible |
/domains | GET | Compatible |
/domains/{id} | GET | Compatible |
/domains/{id}/verify | POST | Compatible |
/domains/{id} | DELETE | Compatible |
Contacts
| Endpoint | Method | Resend Compatible |
|---|---|---|
/contacts | POST | Partial -- adds properties, segments, topics fields |
/contacts | GET | Partial -- organization-level instead of audience-scoped |
/contacts/{id} | GET | Partial -- supports lookup by email address |
/contacts/{id} | PATCH | Partial -- adds properties, topics fields |
/contacts/{id} | DELETE | Partial -- supports lookup by email address |
API Keys
| Endpoint | Method | Resend Compatible |
|---|---|---|
/api-keys | POST | Compatible |
/api-keys | GET | Compatible |
/api-keys/{id} | DELETE | Compatible |
Webhooks
| Endpoint | Method | Resend Compatible |
|---|---|---|
/webhooks | POST | Partial -- additional event types |
/webhooks | GET | Compatible |
/webhooks/{id} | GET | Compatible |
/webhooks/{id} | PATCH | Compatible |
/webhooks/{id} | DELETE | Compatible |
Additional Postflare Endpoints
Postflare includes additional endpoints not available in Resend:
| Endpoint | Method | Description |
|---|---|---|
/segments | POST/GET | Segment management |
/segments/{id} | GET/DELETE | Segment operations |
/topics | POST/GET | Topic management |
/topics/{id} | GET/PATCH/DELETE | Topic operations |
/contacts/{id}/segments | GET/POST/DELETE | Contact segment membership |
/contacts/{id}/topics | GET/PATCH | Contact topic subscriptions |
/broadcasts | POST/GET | Broadcast management |
/broadcasts/{id} | GET/PATCH/DELETE | Broadcast operations |
/broadcasts/{id}/send | POST | Send a broadcast |
/templates | POST/GET | Template management |
/templates/{id} | GET/PATCH/DELETE | Template operations |
/templates/{id}/publish | POST | Publish a template |
/templates/{id}/duplicate | POST | Duplicate a template |