Migrate from Resend
A straightforward guide to moving your email infrastructure from Resend to Veil Mail. Both platforms share a modern, developer-first approach, so the migration is minimal.
Overview
Resend and Veil Mail have very similar API designs. If you're already using Resend, you'll find Veil Mail's SDK and REST API immediately familiar. The primary additions Veil Mail brings are automatic PII scanning, built-in CASL compliance, and a broader feature set including campaigns, A/B testing, automation sequences, and RSS feeds.
Most of the migration involves swapping the SDK package and updating a few field names. Your existing email sending logic will remain largely unchanged.
SDK Migration
Replace the resend package with @resonia/veilmail-sdk.
# Remove Resend
npm uninstall resend
# Install Veil Mail
npm install @resonia/veilmail-sdkSend Email Comparison
Resend
import { Resend } from 'resend';
const resend = new Resend('re_xxxxxxxxxxxxx');
await resend.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Welcome to our platform!</h1>',
});Veil Mail
import { VeilMail } from '@resonia/veilmail-sdk';
const client = new VeilMail('veil_live_xxxxx');
await client.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Welcome to our platform!</h1>',
});Note: The send call signature is nearly identical. The only change is the constructor and import.
Domain Management Comparison
Resend
// List domains
const domains = await resend.domains.list();
// Add domain
const domain = await resend.domains.create({
name: 'yourdomain.com',
});
// Verify domain
await resend.domains.verify(domain.id);Veil Mail
// List domains
const domains = await client.domains.list();
// Add domain
const domain = await client.domains.create({
name: 'yourdomain.com',
});
// Verify domain
await client.domains.verify(domain.id);API Endpoint Mapping
Resend and Veil Mail endpoints map almost one-to-one. The main difference is the /v1 version prefix and base URL.
Base URL: Resend uses https://api.resend.com, Veil Mail uses https://api.veilmail.xyz
| Resend | Veil Mail | Notes |
|---|---|---|
| POST /emails | POST /v1/emails | Very similar payload |
| GET /emails/:id | GET /v1/emails/:id | Direct mapping |
| POST /emails/batch | POST /v1/emails/batch | Direct mapping |
| GET /domains | GET /v1/domains | Direct mapping |
| POST /audiences | POST /v1/audiences | Direct mapping |
| GET /api-keys | GET /v1/api-keys | Direct mapping |
Webhook Migration
Both platforms use similar webhook event structures. Update your event type names to match Veil Mail's namespaced format.
| Resend Event | Veil Mail Event |
|---|---|
| email.sent | email.sent |
| email.delivered | email.delivered |
| email.delivery_delayed | email.deferred |
| email.bounced | email.bounced |
| email.complained | email.complained |
| email.opened | email.opened |
| email.clicked | email.clicked |
Good news: Most event names are identical. The main difference is email.delivery_delayed becomes email.deferred. Veil Mail also adds additional events like subscriber.unsubscribed and campaign.sent that are not available in Resend.
Veil Mail uses the X-VeilMail-Signature header for webhook verification. Replace your Resend signature verification with the Veil Mail equivalent:
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}
// In your webhook handler
const signature = req.headers['x-veilmail-signature'] as string;
const isValid = verifyWebhook(rawBody, signature, process.env.VEILMAIL_WEBHOOK_SECRET!);React Email Integration
If you're using React Email with Resend, you can continue using your existing React Email components with Veil Mail. Use the @resonia/react-email adapter to render your components to HTML before sending.
npm install @resonia/react-emailimport { VeilMail } from '@resonia/veilmail-sdk';
import { render } from '@resonia/react-email';
import { WelcomeEmail } from './emails/welcome';
const client = new VeilMail('veil_live_xxxxx');
// Render your React Email component to HTML
const html = await render(WelcomeEmail({ name: 'Alice' }));
await client.emails.send({
from: 'hello@yourdomain.com',
to: 'user@example.com',
subject: 'Welcome!',
html,
});Your existing React Email component files can be used without modification. The @resonia/react-email adapter is a drop-in replacement for @react-email/render.
What You Gain
Migrating from Resend to Veil Mail gives you access to a broader feature set while maintaining the same developer experience you already know.
- Automatic PII protection -- every email is scanned for sensitive data (SSNs, credit cards, health records) before delivery
- Built-in CASL compliance -- consent tracking, unsubscribe management, and regulatory compliance tools
- Campaign A/B testing -- test subject lines, content, and send times to optimize engagement
- Automation sequences -- build drip campaigns and automated email workflows with branching logic
- RSS-to-email feeds -- automatically send new content to subscribers when your RSS feed updates
- Advanced analytics -- detailed delivery, engagement, and audience analytics with exportable reports
- More SDKs -- official SDKs for Node.js, Python, Go, Ruby, PHP, Java, .NET, Rust, Elixir, Unity, and Unreal Engine