Why Switch?
SMTPfast offers a Resend-compatible API, so you can migrate without rewriting your email integration. You get the same developer experience with competitive pricing and full delivery tracking.
Before and After
Before (Resend with fetch)
const res = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
Authorization: "Bearer re_your_resend_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome!",
html: "<h1>Hello!</h1>",
}),
});
const { id } = await res.json();
After (SMTPfast)
const res = await fetch("https://smtpfa.st/api/v1/emails", {
method: "POST",
headers: {
Authorization: "Bearer sf_your_smtpfast_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome!",
html: "<h1>Hello!</h1>",
}),
});
const { id } = await res.json();
That is it. Two values changed: the base URL and the API key. Everything else stays the same.
Using the Resend Node SDK?
If you are using the Resend SDK, you can point it at SMTPfast by overriding the base URL:
import { Resend } from "resend";
const resend = new Resend("sf_your_smtpfast_key");
// Override the base URL to point to SMTPfast
resend.baseUrl = "https://smtpfa.st/api/v1";
await resend.emails.send({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome!",
html: "<h1>Hello!</h1>",
});
Or use a simple fetch wrapper if you prefer not to depend on the Resend SDK at all.
Compatible Fields
SMTPfast accepts all the common Resend email fields:
| Field | Type | Notes |
|---|---|---|
from |
string |
Required. Sender address. |
to |
string | string[] |
Required. One or more recipients. |
cc |
string | string[] |
Optional. Carbon copy recipients. |
bcc |
string | string[] |
Optional. Blind carbon copy recipients. |
reply_to |
string | string[] |
Optional. Reply-to address(es). |
subject |
string |
Required. Email subject line. |
html |
string |
Email body as HTML. |
text |
string |
Email body as plain text. |
tags |
Array<{ name, value }> |
Optional. Metadata tags. |
headers |
Record<string, string> |
Optional. Custom email headers. |
scheduled_at |
string |
Optional. ISO 8601 date, up to 30 days ahead. |
Response Format
SMTPfast returns a Resend-compatible response:
{ "id": "clxyz123abc" }
You can retrieve full delivery details with GET /emails/:id, which returns Resend-compatible fields like last_event, from, to, subject, html, text, and created_at.
Retrieving Email Status
const res = await fetch("https://smtpfa.st/api/v1/emails/clxyz123abc", {
headers: { Authorization: "Bearer sf_your_smtpfast_key" },
});
const email = await res.json();
// email.last_event -> "delivered"
// email.created_at -> "2026-04-07T12:00:00.000Z"
Migration Checklist
- Create an SMTPfast account at smtpfa.st
- Add and verify your sending domain in the SMTPfast dashboard
- Generate an API key with
email:sendscope - Replace your base URL from
https://api.resend.comtohttps://smtpfa.st/api/v1 - Replace your API key from
re_...tosf_... - Test by sending a single email and confirming delivery
The whole process takes about 5 minutes. Your existing code, payload structure, and response handling all stay the same.
What About Webhooks?
SMTPfast supports delivery webhooks for events like delivered, bounced, opened, and clicked. The webhook payload format may differ slightly from Resend. Check the API docs for details on configuring webhooks.
Ready to get started?
Start sending transactional email today. Free to start, no credit card required.
Get Started for FreeRelated Posts
One approval instead of five DNS records: Domain Connect on SMTPfast
If your domain is on Cloudflare, SMTPfast can publish its sending records, and separately the inbound MX, through Domain Connect. You review each set on Cloudflare's screen, approve, and the records are written for you. Here is how it works, what gets written, and what to do when your DNS lives elsewhere.
Logs API and webhook deliveries: answer 'did it send?' without opening the dashboard
Two additions for the debugging side of email: the event log behind the Logs page is now an API, and every webhook has a delivery log with attempts, responses, automatic retries and a retry button.