Migrate from Mailgun

A comprehensive guide to moving your email infrastructure from Mailgun to Veil Mail, covering API changes, webhook migration, and feature differences.

Overview

Mailgun is a well-established email delivery service with both SMTP and REST API options. Veil Mail takes a modern, API-first approach with built-in privacy protections. The biggest architectural difference is that Mailgun scopes API calls by domain in the URL path, while Veil Mail uses a flat resource structure with the domain specified in the from field.

Key differences to be aware of:

  • Mailgun uses domain-scoped endpoints (/v3/{{domain}}/messages); Veil Mail uses flat endpoints (/v1/emails)
  • Mailgun supports SMTP relay; Veil Mail is API-only for better security and performance
  • Mailgun uses Basic Auth with api:key-xxx; Veil Mail uses Bearer token with veil_live_xxxxx
  • Veil Mail adds PII scanning, CASL compliance, and audience management features not available in Mailgun

SDK Migration

Replace the mailgun.js package with @resonia/veilmail-sdk.

# Remove Mailgun
npm uninstall mailgun.js form-data

# Install Veil Mail
npm install @resonia/veilmail-sdk

Send Email Comparison

Mailgun

mailgun.ts
import Mailgun from 'mailgun.js';
import formData from 'form-data';

const mailgun = new Mailgun(formData);
const mg = mailgun.client({
  username: 'api',
  key: process.env.MAILGUN_API_KEY!,
});

await mg.messages.create('yourdomain.com', {
  from: 'hello@yourdomain.com',
  to: ['user@example.com'],
  subject: 'Welcome!',
  html: '<h1>Welcome to our platform!</h1>',
});

Veil Mail

veilmail.ts
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>',
});

Key difference: Mailgun requires specifying the domain in the messages.create() call. Veil Mail infers the domain from the from address, making the API simpler. You also no longer need the form-data dependency.

Template Usage Comparison

Mailgun

mailgun-template.ts
await mg.messages.create('yourdomain.com', {
  from: 'hello@yourdomain.com',
  to: ['user@example.com'],
  subject: 'Welcome!',
  template: 'welcome-template',
  'h:X-Mailgun-Variables': JSON.stringify({
    firstName: 'Alice',
    orderNumber: '12345',
  }),
});

Veil Mail

veilmail-template.ts
await client.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Welcome!',
  templateId: 'template_xxxxx',
  templateData: {
    firstName: 'Alice',
    orderNumber: '12345',
  },
});

API Endpoint Mapping

Mailgun endpoints are domain-scoped. Veil Mail uses a flat resource structure. All Veil Mail endpoints are under https://api.veilmail.xyz.

MailgunVeil MailNotes
POST /v3/{domain}/messagesPOST /v1/emailsDomain specified in from field
GET /v3/{domain}/eventsGET /v1/analytics/overviewDifferent response structure
GET /v3/domainsGET /v1/domainsDirect mapping
POST /v3/{domain}/templatesPOST /v1/templatesDirect mapping
GET /v3/{domain}/bouncesGET /v1/suppressionsUnified suppression list
GET /v3/{domain}/statsGET /v1/analytics/overviewCombined analytics endpoint

Webhook Migration

Mailgun webhooks use different event names and payload structures. Veil Mail uses a consistent namespaced event format with simpler payloads.

Mailgun EventVeil Mail Event
deliveredemail.delivered
failed (permanent)email.bounced
failed (temporary)email.deferred
openedemail.opened
clickedemail.clicked
complainedemail.complained
unsubscribedsubscriber.unsubscribed

Mailgun uses HMAC-SHA256 with a signing key for webhook verification. Veil Mail also uses HMAC-SHA256, but with a different header name:

webhook-migration.ts
// Mailgun verification (before)
const signature = req.body.signature;
// Verify using timestamp + token + signing key

// Veil Mail verification (after)
const signature = req.headers['x-veilmail-signature'] as string;
const isValid = crypto.timingSafeEqual(
  Buffer.from(signature),
  Buffer.from(
    crypto.createHmac('sha256', process.env.VEILMAIL_WEBHOOK_SECRET!)
      .update(rawBody)
      .digest('hex')
  ),
);

What's Different

FeatureMailgunVeil Mail
SMTPSupported (SMTP relay)API-only (more secure, faster)
AuthenticationBasic Auth (api:key-xxx)Bearer token with scoped keys
Endpoint ScopingDomain-scoped URLsFlat resource URLs
PII ScanningNot availableBuilt-in, automatic
Email ValidationSeparate paid add-onIncluded with suppression checks
Log RetentionPlan-dependentFull analytics with exportable reports

SMTP users: If you're currently using Mailgun via SMTP relay, you'll need to switch to the REST API. Veil Mail does not support SMTP, but the REST API is simpler and provides better deliverability insights. The SDK handles all HTTP communication for you.

What You Gain

  • Automatic PII protection -- every email is scanned for sensitive data before delivery, something Mailgun does not offer
  • Built-in CASL compliance -- consent tracking, unsubscribe management, and physical address enforcement
  • Simpler API surface -- no domain-scoped endpoints, no form-data dependency, native TypeScript types
  • Campaigns and automation -- A/B testing, drip sequences, and automation workflows not available in Mailgun
  • SDKs for every language -- official SDKs for Node.js, Python, Go, Ruby, PHP, Java, .NET, Rust, Elixir, and more
  • RSS feeds and signup forms -- automated content delivery and embeddable subscriber forms built-in
  • Environment-scoped keys -- test safely with veil_test_ keys instead of configuring separate test domains