Skip to content
Writing
MailgunMigrationEmail APIDevOps

Migrating from Mailgun to SadaSend in 10 Minutes (Step-by-Step Guide)

Tired of complex Mailgun domain setups, confusing invoice add-ons, and legacy SDKs? Here is the step-by-step guide to migrating to SadaSend in under 10 minutes.

Why Engineering Teams Are Migrating Away from Mailgun

Mailgun played a vital role in pioneering developer-friendly transactional email in 2010. Over the past decade, however, successive acquisitions and corporate restructuring have resulted in steep price increases, complicated domain hierarchy requirements, and persistent SDK technical debt.

Specifically, the legacy mailgun.js SDK forces developers to install heavyweight external dependencies (form-data, stream polyfills) just to send a basic JSON payload over multipart HTTP POST. In modern serverless and edge architectures (Vercel, AWS Lambda, Cloudflare Workers), these extra dependencies increase bundle size, slow cold starts, and complicate simple deployments.

SadaSend was architected from the ground up as a pure JSON Anycast REST API and managed SMTP relay, purpose-built for modern cloud runtimes and autonomous AI agents with per-key recipient allowlists.

Architecture & Protocol Comparison Matrix

Operational FeatureLegacy MailgunModern SadaSend
Wire ProtocolMultipart form-data via SDKNative application/json REST API & ESMTP 587
Client Dependenciesmailgun.js + form-data (~2.1 MB)0 Dependencies (Global native fetch)
Authentication SchemeBasic Auth (api:key-...) or API keyStandard Bearer Token (Authorization header)
Subdomain RoutingRequires rigid domain URL pathsDomain resolved automatically from From header
AI Agent GuardrailsNone (Unconstrained blast radius)Hardware allowlists & Approval holds
Global Edge IngestionRegional US/EU silosAnycast edge nodes with low latency

1. Side-by-Side Code Migration: Replacing mailgun.js with Fetch

In your application code, you can eliminate the entire Mailgun client initialization and replace it with standard, dependency-free TypeScript fetch calls.

TYPESCRIPT
// ==========================================
// BEFORE: Legacy Mailgun Implementation
// ==========================================
// 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! });
//
// const result = await mg.messages.create('mg.yourdomain.com', {
//   from: 'Alex <alex@yourdomain.com>',
//   to: ['customer@enterprise.com'],
//   subject: 'Quarterly Audit Report',
//   text: 'Your security audit report is ready for download.',
// });

// ==========================================
// AFTER: Modern SadaSend Native Fetch
// ==========================================
export async function sendAuditReport(to: string, reportUrl: string) {
  const response = await fetch('https://api.sadasend.com/emails', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.SADASEND_API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': `report-${to}-${Date.now()}`,
    },
    body: JSON.stringify({
      from: 'Alex <alex@yourdomain.com>',
      to,
      subject: 'Quarterly Audit Report',
      html: `<p>Your security report is ready: <a href="${reportUrl}">Download PDF</a></p>`,
      text: `Your security report is ready: ${reportUrl}`,
    }),
  });

  if (!response.ok) {
    const errorBody = await response.json().catch(() => ({}));
    throw new Error(`SadaSend dispatch failed (${response.status}): ${errorBody.message}`);
  }

  const { id } = await response.json();
  return { success: true, messageId: id };
}

2. Zero-Downtime DNS & Domain Verification Protocol

Migrating production email sending requires careful DNS staging to prevent deliverability drops or SPF authentication failures during the transition.

  • Step 1 (Add Domain): Register your sending domain in the SadaSend dashboard (/app/domains/new). SadaSend provisions 2048-bit RSA and Ed25519 DKIM keys.
  • Step 2 (Merge SPF Records): Do NOT delete your Mailgun SPF record immediately. Merge both mechanisms into a single DNS TXT record: "v=spf1 include:mailgun.org include:_spf.sadasend.com ~all". (Note: Never publish two separate SPF records).
  • Step 3 (Publish DKIM Selectors): Add the SadaSend DKIM CNAME/TXT records alongside your existing Mailgun selectors. Multiple DKIM selectors happily coexist on the same domain.
  • Step 4 (Switch Traffic): Deploy the updated code with SADASEND_API_KEY in staging, verify delivery, and roll out to production.
  • Step 5 (Cleanup): Keep Mailgun active for 48 hours to handle any queued retries, then prune the mailgun.org SPF mechanism and cancel the legacy subscription.
Free plan

Building AI agents that send email?

Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with ten tools — on the free plan, without a card.