What you'll have at the end
A real production-ready setup, not a toy. By the time you finish this post you'll have:
- An SMTPfast account on the Free plan (3,000 emails/month, no card).
- A sending domain verified at the DKIM, SPF, and DMARC level.
- An API key scoped to email sending.
- One real email delivered to a real inbox via the API.
- Open and click events flowing into your dashboard.
The order matters. Sending before the DNS is verified is the most common reason a first email lands in spam.
TLDR
curl -X POST https://smtpfa.st/api/v1/emails \
-H "Authorization: Bearer $SMTPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": "[email protected]",
"subject": "Hello from SMTPfast",
"html": "<p>It works.</p>",
"text": "It works."
}'
That's the whole API once you have a verified domain and a key. The rest of this post is the setup that makes that single curl actually deliver.
1. Create an account
Sign up at smtpfa.st with the email you actually read. We send a verification link there immediately, and we send the once-a-month usage warning if your account ever crosses 80% of your plan's send limit.
After signup you land on the dashboard. The Free tier is active by default (3,000 emails/month, 1,000 contacts, 1 domain). No credit card needed unless you upgrade later.
2. Add and verify your sending domain
You need DNS records on the domain you'll send from. Sending from a free webmail address ([email protected]) won't work because we can't add DKIM records to Google's domain.
Go to Domains โ Add domain. Enter the apex domain (yourdomain.com, not mail.yourdomain.com). The dashboard responds with three records you need to add at your DNS provider:
# DKIM (3 CNAMEs, one per token)
TYPE HOST VALUE
CNAME tok1._domainkey.yourdomain.com tok1.dkim.amazonses.com
CNAME tok2._domainkey.yourdomain.com tok2.dkim.amazonses.com
CNAME tok3._domainkey.yourdomain.com tok3.dkim.amazonses.com
# SPF (TXT, on the apex)
TYPE HOST VALUE
TXT yourdomain.com "v=spf1 include:amazonses.com ~all"
# DMARC (TXT, recommended)
TYPE HOST VALUE
TXT _dmarc.yourdomain.com "v=DMARC1; p=none; rua=mailto:[email protected]"
Most DNS providers (Cloudflare, Route 53, Namecheap, GoDaddy) accept these as pasted-in. The propagation takes anywhere from 30 seconds to a few hours; ours rechecks every 60 seconds and flips the status to Verified automatically. You don't need to babysit the page.
What each record does:
- DKIM signs every outgoing message with a private key whose public half lives in those CNAMEs. Receivers verify the signature to confirm the email wasn't tampered with in transit.
- SPF lists which servers are allowed to send mail for your domain. The
include:amazonses.comclause delegates that authority to AWS SES (the infrastructure SMTPfast runs on top of). - DMARC tells receivers what to do when SPF or DKIM fails.
p=nonemeans "let it through and report to me" while you watch for problems. Tighten top=quarantineorp=rejectonce your auth is clean.
If any of those three is missing or wrong, your mail will land in spam at most providers regardless of how good your content is.
3. Create an API key
Go to API Keys โ Create key. Name it after where it'll live (prod-server, staging, local-dev). The key is shown once and starts with sf_live_. Copy it into your secret store immediately. We never re-display it.
Scopes are the principle of least privilege for keys. The default email:send is enough for sending. Reading logs, managing contacts, or managing webhooks each have their own scope. If a key only needs to send, give it only email:send and you'll never accidentally let a leaked key delete your contact list.
Set it as an env var:
export SMTPFAST_API_KEY="sf_live_..."
4. Send your first email
Three ways depending on your stack. Pick the one you'll use in production; switching languages later is a one-line URL change.
curl
curl -X POST https://smtpfa.st/api/v1/emails \
-H "Authorization: Bearer $SMTPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": "[email protected]",
"subject": "Hello from SMTPfast",
"html": "<p>It works.</p>",
"text": "It works."
}'
Node.js (no SDK needed)
const res = await fetch("https://smtpfa.st/api/v1/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMTPFAST_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "[email protected]",
to: "[email protected]",
subject: "Hello from SMTPfast",
html: "<p>It works.</p>",
text: "It works.",
}),
});
const data = await res.json();
console.log(data.id); // "em_clx...", store this if you want to look it up later
Python (no SDK needed)
import os, requests
res = requests.post(
"https://smtpfa.st/api/v1/emails",
headers={"Authorization": f"Bearer {os.environ['SMTPFAST_API_KEY']}"},
json={
"from": "[email protected]",
"to": "[email protected]",
"subject": "Hello from SMTPfast",
"html": "<p>It works.</p>",
"text": "It works.",
},
timeout=10,
)
res.raise_for_status()
print(res.json()["id"])
The response comes back in well under 100ms because we don't actually send the email synchronously. We queue it, validate the recipient against your suppression list, and respond with an ID. The actual SMTP handoff to AWS SES happens within milliseconds in the worker.
Always include text alongside html. Email clients fall back to it on devices that prefer plain text, screen readers use it for accessibility, and anti-spam filters score multipart emails higher than HTML-only ones.
5. See what happened
Open Logs in the dashboard. Your test email shows up with a status that walks through queued โ sent โ delivered. Click the row to see the full event timeline plus the headers, recipient, and (if you enabled tracking) opens and clicks as they arrive.
If you set up a webhook (recommended for any production use), you'll get the same events POSTed to your endpoint within a second or two of each transition. The payload looks like:
{
"type": "email.delivered",
"email_id": "em_clx...",
"timestamp": "2026-04-05T10:00:00.123Z",
"data": {
"to": "[email protected]",
"from": "[email protected]",
"subject": "Hello from SMTPfast"
}
}
email.bounced and email.complained events also fire, and those are the ones you actually need to handle programmatically. We add the recipient to your suppression list automatically so you don't keep hammering a known-bad address.
Common first-send gotchas
A short list ranked by how often we see them in support tickets:
- From address mismatch. The domain in
frommust match a verified domain on your account.[email protected]works only ifyourdomain.comis verified. - DKIM not yet propagated. The dashboard shows green only after we've successfully resolved all three CNAMEs. If you added them five minutes ago and they aren't green yet, give them another twenty.
- Free webmail in
tofor testing. Gmail and Outlook are aggressive about scoring brand-new senders. Send your first test to your own inbox on your sending domain. Move to a different recipient once you've warmed up. - 403 with "Domain not verified". The server rejected the send because the domain on the
fromfield hasn't passed verification yet. Check the Domains page; the row will tell you which DNS record is still failing. - Hitting the 100/hour rate limit on Free. It's an anti-abuse cap, not a deliverability limit. Upgrade or contact us if you have a legitimate use case that needs more headroom.
Pricing at a glance
- Free, 3,000 emails/month, 1 sending domain, 1,000 contacts. No card.
- Starter, $9/month, 10,000 emails, 3 domains, 5,000 contacts.
- Growth, $19/month, 50,000 emails, unlimited domains, 25,000 contacts, open + click tracking, real-time event logs.
- Scale, $49/month, 200,000 emails, 100,000 contacts, priority queue, dedicated support, and SLA.
Full breakdown on the pricing page. The Free tier is enough to build and ship a side project end to end without paying us anything.
Where to go next
- Domain authentication guide, DKIM / SPF / DMARC explained for people who haven't dealt with email DNS before.
- Why emails go to spam, the seven things that actually trigger spam filters.
- Webhook best practices, how to handle delivery and bounce events without losing them.
- React Email templates, author your transactional emails as typed React components.
Welcome aboard.
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.