Move from Mailgun to Postscale

Map Mailgun sending calls, routes, templates, and webhooks to Postscale.

  • Convert Messages API calls from multipart form data to JSON.
  • Replace Routes with aliases, inbound rules, and webhooks.
  • Move bounces, complaints, and unsubscribes before production traffic.
  • Use SMTP relay where legacy systems cannot switch to REST immediately.

What changes when you move.

A direct map from Mailgun concepts to the Postscale API and operational model.

MailgunPostscaleMigration note
Messages APIPOST /v1/sendMap html/text fields to html_body/text_body and move o:tag values to tags.
RoutesAliases and inbound rulesUse per-address aliases plus domain-level rules for sender, subject, and authentication conditions.
WebhooksPostscale webhooksCreate one endpoint with selected event types and verify HMAC signatures.
Template StoragePostscale templatesImport Handlebars-style HTML and send using template slug or ID.
SuppressionsSuppression APIExport bounces, complaints, and unsubscribes separately, then preview each CSV so reasons remain auditable.

Move your integration step by step

01

Add Postscale DNS records

Add Postscale verification, DKIM, return-path, and optional MX records while the old provider keeps sending.

02

Update your integration

Swap API credentials and normalize the send payload. Keep the old provider path behind a feature flag for rollback.

03

Import suppressions and templates

Preview and import suppression exports, move template HTML, then configure delivery, bounce, complaint, and inbound webhooks.

04

Move traffic gradually

Start at 10 percent, watch bounces and complaints by ISP, then increase volume as warming limits allow.

Convert the send call.

Compare the existing send request with its Postscale equivalent.

Mailgun
const form = new FormData();
form.append("from", "Acme <alerts@example.com>");
form.append("to", "user@example.com");
form.append("subject", "Welcome");
form.append("html", "<p>Hello from Acme</p>");
form.append("o:tag", "onboarding");
form.append("v:user_id", "usr_123");

await fetch("https://api.mailgun.net/v3/example.com/messages", {
  method: "POST",
  headers: { Authorization: `Basic ${mailgunToken}` },
  body: form,
});
Postscale
await fetch("https://api.postscale.io/v1/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.POSTSCALE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: "Acme <alerts@example.com>",
    to: ["user@example.com"],
    subject: "Welcome",
    html_body: "<p>Hello from Acme</p>",
    tags: ["onboarding"],
    metadata: { user_id: "usr_123" },
  }),
});

Production checklist.

Lower DNS TTL to 300 seconds at least 24 hours before cutover.
Keep both DKIM selectors published during the transition.
Import hard bounces, complaints, unsubscribes, and manual suppressions through /dashboard/suppressions before the first production send.
Handle both providers’ webhook formats until events from the old provider have finished arriving.
Send seed tests to Gmail, Outlook, Yahoo, iCloud, and a corporate Microsoft 365 tenant.
Cut over early in the week and avoid final traffic moves on Friday.
Monitor delivery, bounce, deferred, and complaint rates by ISP after each traffic increase.
Keep the old account active until delayed events and user replies have stopped arriving.

FAQ

What replaces Mailgun Routes?

Use Postscale aliases for address-level routing and inbound rules for conditional routing by sender, subject, headers, authentication results, or target webhook.

Can I keep SMTP during the migration?

Yes. Postscale supports SMTP relay, so legacy apps can change host, username, and password before you rewrite REST calls.

How should suppressions move from Mailgun?

Export bounces, complaints, unsubscribes, and manual suppressions as separate CSV files, then preview and commit them in /dashboard/suppressions before sending through Postscale.

Start your migration to Postscale.