PadiMail Docs
Switch to PadiMail

Switch from Resend

Point your existing Resend code at PadiMail by changing two environment variables. Switch back the same way.

NeedsTier 1: IndividualYou can try the switch with a test key straight away. Sending real email from your domain needs Tier 1.

PadiMail has a Resend-compatible API. It accepts Resend's request shapes and returns Resend's response and error shapes, so the Resend SDK and your existing code keep working. Underneath it's the same as our own API: the same verification, scanning, suppressions, limits and billing.

1. Change two variables

.env
RESEND_BASE_URL=https://api.padimail.app/resend
RESEND_API_KEY=pm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Resend's Node SDK reads RESEND_BASE_URL when you don't pass a base URL in code, and so do its Go and Rust SDKs. If your code passes a base URL to the constructor, change that one value instead.

Your code doesn't change:

import { Resend } from "resend";

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

const { data, error } = await resend.emails.send({
  from: "Acme Store <hello@acme.ng>",
  to: ["ada@example.com"],
  subject: "Your receipt #1042",
  react: <ReceiptEmail orderNo="1042" />,
});

The same with cURL:

curl -X POST https://api.padimail.app/resend/emails \
  -H "Authorization: Bearer $RESEND_API_KEY" -H "Content-Type: application/json" \
  -d '{"from": "Acme Store <hello@acme.ng>", "to": "ada@example.com", "subject": "Your receipt #1042", "html": "<p>Thanks.</p>"}'

2. Bring your domains across

Add each sending domain under Domains (or with the API). We show the DNS records to add. Your Resend records can stay in place while you switch, so you can move back at any time.

3. Point your webhooks at us

Create a webhook endpoint with the Resend payload format. We then send Resend's event names and payload shape, signed with the same svix-* headers, so your existing verification code keeps working. Use the new signing secret we show you. Resend has no account.* events, so an endpoint in the Resend format never receives them; to get usage alerts (account.usage_threshold, account.usage_spike) by webhook, add a second endpoint in the PadiMail format.

What's covered

AreaEndpoints
EmailsSend, batch, get, update the schedule, cancel
DomainsCreate, list, get, verify, delete
API keysCreate, list, delete

Anything else returns 501 with a link to the equivalent in our own API. Audiences and contacts come later.

Differences to know about

  • Errors use Resend's shape (statusCode, message, name). Our own error code is added as pm_code, and explained on the Errors page.
  • Extras: you can pass our fields quota_behavior, stream and fallback in a Resend send call. Over a limit, emails wait by default instead of failing; pass quota_behavior: "reject" for login codes.
  • Test keys: pm_test_ keys work through the Resend SDK too, and never deliver real email.
  • SMTP: if you use Resend's SMTP, change the host to smtp.padimail.app and the password to your PadiMail key. The username resend is accepted.

Switch back

Set RESEND_BASE_URL and RESEND_API_KEY back to Resend's values and redeploy. Nothing else changes.

Or use our SDK

Our own Node SDK covers every endpoint, retries for you and verifies webhooks:

import { PadiMail } from "@padimail/node";
const pm = new PadiMail(process.env.PADIMAIL_API_KEY);
await pm.emails.send({ from: "Acme Store <hello@acme.ng>", to: "ada@example.com", subject: "Your receipt", react: <ReceiptEmail orderNo="1042" /> });
Was this page helpful?

On this page