Migrate Resend sending and receiving to Postscale

Map sending calls, templates, receiving routes, and webhooks to Postscale before moving traffic.

  • Convert Resend emails.send payloads to POST /v1/send.
  • Use SMTP relay for systems that cannot call a REST API.
  • Move receiving flows to inbound aliases and signed webhooks.
  • Preserve tags, headers, reply-to, and metadata in the send payload.

What changes when you move.

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

ResendPostscaleMigration note
emails.sendPOST /v1/sendMap html/text to html_body/text_body and keep tags as Postscale tags.
emails.batchPOST /v1/send/batchBatch sends remain independent per message with per-item results.
ReceivingInbound Email APIPostscale delivers parsed inbound email via signed webhooks and stores messages for retrieval.
TemplatesPostscale templatesUse template slugs or keep rendering React Email HTML in your app.
WebhooksPostscale webhooksSubscribe endpoint by endpoint and verify HMAC signatures.
SuppressionsSuppression APIImport suppressions before sending so blocked addresses remain excluded.

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.

Resend
import { Resend } from "resend";

const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: "Acme <alerts@example.com>",
  to: ["user@example.com"],
  subject: "Welcome",
  html: "<p>Hello from Acme</p>",
  tags: [{ name: "flow", value: "onboarding" }],
});
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"],
  }),
});

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

Why migrate from Resend if the send API is simple?

Both providers offer API/SMTP sending and receiving. Evaluate Postscale for its EU operator, EU/EEA-hosted primary service data, inbound routing rules, masked addresses, and DMARC reporting.

Do Resend receiving webhooks map directly?

The workflow is similar, but payloads, routing, and signature verification differ. Configure accepting aliases or catch-all and inbound rules, then test your handler with Postscale events.

Can I keep my current template system?

Yes. Render HTML in your app exactly as before, or move templates into Postscale when you want template preview and API-managed reuse.

What about existing Resend suppressions?

Export available suppression rows, map hard bounces and spam complaints conservatively, and import them through /dashboard/suppressions before cutover.

Start your migration to Postscale.