Setting up transactional email shouldn’t take a week. Here’s the exact steps to go from zero to sending verified emails with AWS SES, with proper DKIM/SPF/DMARC — in 30 minutes.
The Goal
Send [email protected] emails that land in inbox (not spam), with full authentication.
Step 1: Verify Your Domain (5 min)
aws ses verify-domain-identity --domain yourdomain.com --region eu-central-1
This returns a TXT record to add to your DNS. Add it, wait for verification.
Step 2: DKIM (5 min)
aws ses verify-domain-dkim --domain yourdomain.com --region eu-central-1
Returns 3 CNAME records. Add all three to DNS:
[token1]._domainkey.yourdomain.com → [token1].dkim.amazonses.com
[token2]._domainkey.yourdomain.com → [token2].dkim.amazonses.com
[token3]._domainkey.yourdomain.com → [token3].dkim.amazonses.com
Step 3: SPF + DMARC (5 min)
Add these DNS records:
# SPF - allows SES to send on your behalf
TXT yourdomain.com "v=spf1 include:amazonses.com ~all"
# DMARC - tells receivers to trust SPF/DKIM
TXT _dmarc.yourdomain.com "v=DMARC1; p=none;"
# Custom MAIL FROM (optional but recommended)
MX mail.yourdomain.com feedback-smtp.eu-central-1.amazonses.com
TXT mail.yourdomain.com "v=spf1 include:amazonses.com ~all"
Important: Only ONE DMARC record. Duplicate DMARC records = both get ignored = emails go to spam.
Step 4: Request Production Access (10 min)
SES starts in sandbox mode (can only send to verified emails). Request production access through the AWS Console → SES → Account Dashboard → Request Production Access.
Step 5: Send From Node.js
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
const ses = new SESClient({ region: 'eu-central-1' });
await ses.send(new SendEmailCommand({
Source: '[email protected]',
Destination: { ToAddresses: [userEmail] },
Message: {
Subject: { Data: 'Welcome!' },
Body: { Html: { Data: htmlContent } }
}
}));
The Gotcha: Region Matters
SES is regional. If you verify in eu-central-1, you must send from eu-central-1. Sending from eu-west-1 with credentials from eu-central-1 will fail silently.
// CRITICAL: Must match the region where you verified
const ses = new SESClient({ region: 'eu-central-1' });
Cost
At startup volumes (< 1,000 emails/month): under $1/month.
This setup powers email notifications at MisuJob — job match alerts, application confirmations, and password resets.
What email service do you use? SES, SendGrid, Postmark? What’s your experience?

