Migrate from SendGrid
A comprehensive guide to moving your transactional and marketing email infrastructure from SendGrid to Veil Mail.
Overview
Veil Mail offers a modern, privacy-first alternative to SendGrid with built-in PII protection, CASL compliance tools, and a developer experience designed for today's applications. If you're currently using SendGrid, migrating to Veil Mail is straightforward because both platforms share similar REST API conventions and Handlebars-based templating.
Key differences to be aware of:
- Veil Mail scans all outgoing emails for PII before delivery, preventing accidental data leaks
- API keys in Veil Mail are scoped to specific permissions and environments (
veil_live_for production,veil_test_for testing) - Audiences and subscribers are first-class resources with built-in consent tracking
- Webhook events use a namespaced format (e.g.,
email.deliveredinstead ofdelivered)
API Key Migration
SendGrid uses a single API key format. Veil Mail uses scoped API keys that separate production and test environments. Generate a new API key from the Veil Mail dashboard and replace your SendGrid key.
SendGrid
// SendGrid API key
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxVeil Mail
// Veil Mail API key (scoped to environment)
VEILMAIL_API_KEY=veil_live_xxxxx # Production
# VEILMAIL_API_KEY=veil_test_xxxxx # Testing (no emails sent)Tip: Veil Mail test keys (veil_test_) let you develop and test without sending real emails or consuming your quota. SendGrid requires a separate sandbox mode configuration.
SDK Migration
Replace the @sendgrid/mail package with @resonia/veilmail-sdk. The API surface is intentionally similar to make migration easy.
# Remove SendGrid
npm uninstall @sendgrid/mail @sendgrid/client
# Install Veil Mail
npm install @resonia/veilmail-sdkSend Email Comparison
SendGrid
import sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
await sgMail.send({
to: 'user@example.com',
from: 'hello@yourdomain.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({
to: 'user@example.com',
from: 'hello@yourdomain.com',
subject: 'Welcome!',
html: '<h1>Welcome to our platform!</h1>',
});Template Usage Comparison
SendGrid
await sgMail.send({
to: 'user@example.com',
from: 'hello@yourdomain.com',
templateId: 'd-xxxxxxxxxxxxx',
dynamicTemplateData: {
firstName: 'Alice',
orderNumber: '12345',
},
});Veil Mail
await client.emails.send({
to: 'user@example.com',
from: 'hello@yourdomain.com',
templateId: 'template_xxxxx',
templateData: {
firstName: 'Alice',
orderNumber: '12345',
},
});Note: The key difference is dynamicTemplateData becomes templateData, and template IDs use the template_ prefix instead of SendGrid's d- prefix.
API Endpoint Mapping
The following table maps common SendGrid API endpoints to their Veil Mail equivalents.
| SendGrid | Veil Mail | Notes |
|---|---|---|
| POST /v3/mail/send | POST /v1/emails | Similar payload structure |
| GET /v3/templates | GET /v1/templates | Direct mapping |
| POST /v3/marketing/contacts | POST /v1/audiences/:id/subscribers | Audience-scoped in Veil Mail |
| GET /v3/stats | GET /v1/analytics/overview | Different response format |
| GET /v3/suppression/bounces | GET /v1/suppressions | Unified suppression list |
| GET /v3/whitelabel/domains | GET /v1/domains | Direct mapping |
Webhook Migration
SendGrid uses flat event names in its Event Webhook. Veil Mail uses namespaced event types. Update your webhook handler to map the new event names.
| SendGrid Event | Veil Mail Event |
|---|---|
| delivered | email.delivered |
| bounce | email.bounced |
| open | email.opened |
| click | email.clicked |
| spamreport | email.complained |
| unsubscribe | subscriber.unsubscribed |
| dropped | email.failed |
| deferred | email.deferred |
Veil Mail webhooks also include a signature header (X-VeilMail-Signature) for verification, similar to SendGrid's Event Webhook signature verification.
// Veil Mail webhook handler
app.post('/webhooks/veilmail', async (req, res) => {
const signature = req.headers['x-veilmail-signature'];
// Verify signature with your webhook secret
const event = req.body;
switch (event.type) {
case 'email.delivered':
// Previously: event === 'delivered'
break;
case 'email.bounced':
// Previously: event === 'bounce'
break;
case 'email.complained':
// Previously: event === 'spamreport'
break;
}
res.json({ received: true });
});Template Migration
Both SendGrid and Veil Mail use Handlebars syntax for templates, so your existing template content is largely compatible. The main differences are in how templates are managed and referenced.
Compatible Syntax
- Variable substitution:
{{variableName}} - Conditionals:
{{#if condition}}...{{/if}} - Loops:
{{#each items}}...{{/each}} - Helpers:
{{formatDate date}}
What to Update
- Replace
dynamicTemplateDatawithtemplateDatain your send calls - Update template IDs from
d-xxxxxformat totemplate_xxxxxformat - Recreate templates in the Veil Mail dashboard or via the API
What's Different
| Feature | SendGrid | Veil Mail |
|---|---|---|
| PII Scanning | Not available | Built-in, scans all outbound emails |
| CASL Consent | Manual tracking | Built-in consent management |
| API Key Scoping | Permission-based | Environment-scoped (live/test) + permissions |
| Subscriber Model | Global contact list | Audience-scoped subscribers |
| SMTP | Supported | API-only (more secure, faster) |
What You Gain
- Automatic PII protection -- every email is scanned for sensitive data before delivery, preventing accidental data leaks
- Built-in CASL compliance -- consent tracking, unsubscribe management, and physical address enforcement out of the box
- Environment-scoped API keys -- test safely with
veil_test_keys that never send real emails - A/B testing and automation -- built-in campaign A/B testing, drip sequences, and automation workflows
- SDKs for every language -- official SDKs for Node.js, Python, Go, Ruby, PHP, Java, .NET, Rust, Elixir, and more
- RSS-to-email and signup forms -- automated content delivery and embeddable subscriber forms