Third-Party API IntegrationsAdvanced
Transactional Email: SMTP, SendGrid, AWS SES, Mailgun — Compared
ByDomain India Team
9 min read22 Apr 20262 views
# Transactional Email: SMTP, SendGrid, AWS SES, Mailgun — Compared
Password resets, order receipts, account notifications — every application sends transactional email. Deliverability, not volume, is the primary concern. This guide compares the options, shows the SPF / DKIM / DMARC setup that makes everything else work, and provides PHP and Node.js integration examples for the major providers.
## Why native `mail()` fails for transactional email at scale
PHP's built-in `mail()` function is the tempting starting point. It works for low volume on well-configured servers. At scale, three problems surface:
1. **Deliverability.** Shared hosting IP addresses are usually on some blocklist or another. Email lands in spam, or gets rejected outright.
2. **No observability.** The `mail()` function returns `true` as long as the mail was handed off to `sendmail` — not when it actually got delivered. You don't know which mails bounced, which were opened, which were clicked.
3. **SPF / DKIM alignment is hard.** On shared hosting you share the sending IP and domain with hundreds of other sites; the email infrastructure is not tuned for your domain specifically.
For transactional volume above a few dozen per day — password resets, order confirmations, alerts — use a dedicated service.
## The options, compared
### 1. SMTP via cPanel mail account
- **Cost:** free, included with hosting
- **Volume limit:** roughly 200–500 emails / hour on shared plans
- **Deliverability:** acceptable for your own domain after SPF + DKIM are set
- **Observability:** basic logs in cPanel
- **Good for:** single-business sites, contact form notifications, low-volume transactional
### 2. SendGrid (by Twilio)
- **Cost:** free tier 100 emails / day forever; paid from $15 / mo for 40,000 emails
- **Deliverability:** excellent — dedicated IPs, well-maintained reputation
- **Observability:** full dashboard — opens, clicks, bounces, unsubscribes
- **Good for:** growing apps; mix of transactional and marketing
### 3. AWS SES
- **Cost:** cheapest at scale — $0.10 per 1,000 emails
- **Deliverability:** solid on shared IPs, excellent on dedicated (paid extra)
- **Observability:** SNS-based event feeds (bounces, complaints, deliveries)
- **Setup friction:** requires AWS account, initial sandbox mode (capped to verified senders), verification flow to leave sandbox
- **Good for:** volume senders on AWS-integrated stacks
### 4. Mailgun
- **Cost:** pay-as-you-go from $35 / mo for 50,000 emails
- **Deliverability:** strong, especially for developers (API-first)
- **EU data-centre option** available (GDPR alignment)
- **Good for:** developer-first setups, European businesses
### 5. Postmark
- **Cost:** $15 / mo for 10,000 emails — more expensive per email than SendGrid/SES
- **Deliverability:** industry-leading, specifically optimised for transactional
- **Strict policy:** transactional only, no marketing — if you mix, you get kicked off
- **Good for:** finance / healthcare / critical transactional (password resets for security-sensitive apps)
### 6. Amazon SES via cPanel relay
- Your cPanel account's SMTP configured to forward via SES
- Combines cheap SES pricing with cPanel-native integration
- Setup: more involved, but cuts SES sandbox issues
### Recommendation matrix
| Volume | Use case | Recommended |
|---|---|---|
| < 100 / day | Contact forms, small store | cPanel SMTP |
| 100 – 5,000 / day | Normal SaaS | SendGrid free / paid |
| 5,000 – 100,000 / day | Growing SaaS | SendGrid paid / Mailgun |
| > 100,000 / day | High volume | AWS SES |
| Critical (password reset) | Any | Postmark |
## SPF, DKIM, DMARC — required for all
Before choosing a provider, set these three DNS records. They're what make the difference between your emails landing in Inbox vs Spam. All three are DNS-level configuration.
### SPF — "who is allowed to send mail as my domain"
A single TXT record at your domain's apex:
```
example.com. TXT "v=spf1 include:sendgrid.net include:mail.crystalregistry.com ~all"
```
Lists the mail servers authorised to send as `@example.com`. `~all` means "soft-fail everything else" (mark suspicious, still deliver). Start here; later you can move to `-all` (hard-fail).
Only ONE SPF record per domain — you cannot have two. If you add SendGrid to an existing SPF, modify the existing record.
### DKIM — cryptographic signing of your emails
DKIM adds a digital signature to every outbound email's headers. Receiving servers verify the signature against a public key you publish in DNS. Any tampering invalidates the signature.
Each provider gives you a CNAME or TXT record pair:
```
s1._domainkey.example.com. CNAME s1.domainkey.u123.wl.sendgrid.net.
s2._domainkey.example.com. CNAME s2.domainkey.u123.wl.sendgrid.net.
```
Add them; activate DKIM in the provider's dashboard.
### DMARC — how receivers should treat SPF / DKIM failures
```
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
```
Starts in `p=none` (monitor-only). After a few weeks of aggregated reports confirming legitimate traffic passes SPF + DKIM, graduate to `p=quarantine` (move failures to spam) and eventually `p=reject` (bounce failures outright).
Our DNS panel on all Domain India hosting plans supports all three record types. See [How to Change Your Domain DNS Settings](https://domainindia.com/support/kb/how-to-change-your-domain-dns-settings).
## PHP + SendGrid
```bash
composer require sendgrid/sendgrid
```
```php
setFrom('[email protected]', 'Your Company');
$email->setSubject('Your password reset');
$email->addTo('[email protected]', 'User Name');
$email->addContent('text/plain', "Click here to reset: https://yourdomain.com/reset/token-abc");
$email->addContent('text/html', "
Click here: Reset password
"); $sendgrid = new \SendGrid($_ENV['SENDGRID_API_KEY']); try { $response = $sendgrid->send($email); // 202 = accepted for delivery error_log("SendGrid status: " . $response->statusCode()); } catch (\Exception $e) { error_log("SendGrid error: " . $e->getMessage()); } ``` ## PHP + PHPMailer (provider-agnostic SMTP) Works with any SMTP provider — cPanel, SendGrid's SMTP endpoint, SES SMTP, Postmark SMTP. Useful when you want one library for everything. ```bash composer require phpmailer/phpmailer ``` ```php isSMTP(); $mail->Host = $_ENV['SMTP_HOST']; // smtp.sendgrid.net, email-smtp.us-east-1.amazonaws.com, mail.yourdomain.com $mail->SMTPAuth = true; $mail->Username = $_ENV['SMTP_USER']; $mail->Password = $_ENV['SMTP_PASS']; $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; $mail->Port = 465; $mail->setFrom('[email protected]', 'Your Company'); $mail->addAddress('[email protected]', 'User Name'); $mail->Subject = 'Your password reset'; $mail->isHTML(true); $mail->Body = 'Click here: Reset
'; $mail->AltBody = 'Click: https://yourdomain.com/reset/token'; $mail->send(); } catch (\Exception $e) { error_log("Mail error: {$mail->ErrorInfo}"); } ``` ## Node.js + SendGrid ```bash npm install @sendgrid/mail ``` ```javascript import sgMail from '@sendgrid/mail'; sgMail.setApiKey(process.env.SENDGRID_API_KEY); const msg = { to: '[email protected]', from: '[email protected]', subject: 'Your password reset', text: 'Click here to reset: https://yourdomain.com/reset/token', html: 'Click here: Reset
', }; try { await sgMail.send(msg); } catch (err) { console.error('SendGrid error:', err.response?.body || err.message); } ``` ## Node.js + AWS SES (via nodemailer) ```bash npm install nodemailer @aws-sdk/client-ses ``` ```javascript import nodemailer from 'nodemailer'; import { SES } from '@aws-sdk/client-ses'; const ses = new SES({ region: 'ap-south-1' }); const transporter = nodemailer.createTransport({ SES: { ses } }); await transporter.sendMail({ from: '[email protected]', to: '[email protected]', subject: 'Your password reset', text: 'Click here: https://yourdomain.com/reset/token', html: 'Click here: Reset
', }); ``` `ap-south-1` is Mumbai — lowest latency for Indian-based senders. Your SES account must be verified there (separate from other regions). ## Webhook events — bounces, opens, clicks Every reputable provider can POST to your server when events happen. Use these to: - Maintain a list of bad-bounce addresses (don't keep sending to them) - Measure engagement - Detect unsubscribes for marketing compliance - Detect when the user clicked the verification link (for conversion tracking) ### SendGrid Event Webhook 1. Dashboard → Settings → Mail Settings → Event Webhook 2. Point to `https://yourdomain.com/webhooks/sendgrid` 3. Select events: Delivered, Bounced, Deferred, Dropped, Processed 4. Optional: enable signed webhooks for authenticity Payload is an array of events: ```json [ { "email": "[email protected]", "event": "bounce", "timestamp": 1713800000, "reason": "Mailbox full" } ] ``` Handle bounce events by marking the address in your DB as `deliverable=false`. ### AWS SES via SNS SES publishes events to an SNS topic. You subscribe an HTTP endpoint or a Lambda. More plumbing but more power — handles volume well. ## Cost comparison at 10,000 emails / month | Provider | Cost | |---|---| | cPanel SMTP | Included in hosting | | SendGrid Essentials | $15 / mo (40,000 limit — cheap per email) | | AWS SES | $1 / month — cheapest at this volume | | Mailgun Foundation | $35 / mo (50,000 limit) | | Postmark | $15 / mo (10,000 limit) | At 100,000 emails / month: | Provider | Cost | |---|---| | SendGrid Pro | $90 / mo | | AWS SES | $10 / mo | | Mailgun | $75 / mo | | Postmark | $100 / mo | SES is typically the cheapest at volume. SendGrid has the easiest developer experience. Postmark has the highest price and the highest deliverability — pay for it on critical emails only. ## Common pitfalls 1. **Forgetting to verify the sender domain / address.** Every provider requires you prove ownership before sending. Verification = DNS records or click-link in an email. 2. **Multiple conflicting SPF records.** There can only be one. If you add a provider, merge into the existing record. 3. **Missing DKIM.** SPF alone is not enough — many providers (Gmail, Office 365) drop emails that pass SPF but fail DKIM. 4. **DMARC without DKIM fails.** DMARC policies require either SPF or DKIM to pass with alignment. Set up DKIM first. 5. **Wildcard "From" addresses.** `[email protected]` is fine. `[email protected]` depends on your mail server accepting any sender. Some email providers have strict sender-address requirements — check before deploying. 6. **Running marketing and transactional on the same provider.** Marketing bounces / complaints hurt transactional deliverability. Use separate accounts or separate providers (transactional: Postmark / SES; marketing: Mailchimp / Brevo). 7. **Rate limits on shared IPs.** A sudden burst looks like spam — ramp up gradually over the first 2 weeks on a new provider. 8. **Not handling bounces.** After 5 hard bounces, a provider flags your account. After 20, they suspend sending. Maintain a suppression list in your own database and never send to permanently-bounced addresses. ## Frequently asked questions **Can I send from `[email protected]` using my app?** No, not through most providers. They require you own and verify the sending domain. Use `[email protected]` with SendGrid's or SES's DKIM setup. **Why do my password-reset emails sometimes go to spam?** Most likely: missing DKIM, missing DMARC, sender reputation (new domain / new IP), or the content triggers spam filters. Run your test email through mail-tester.com — it gives a detailed score out of 10 with fixes. **Do I need a dedicated IP?** For < 50,000 emails / month — no, shared IPs are fine. For high-volume marketing — maybe, to isolate your reputation. Dedicated IPs need constant volume to stay "warm" — low volume on a dedicated IP is worse than medium volume on a shared IP. **How do I test emails without spamming myself?** Use Mailtrap.io (`smtp.mailtrap.io`) for development — captures every outgoing email in a virtual inbox, never actually sends. Switch to real provider in production. **Can I send emails from `localhost` during development?** Locally, use Mailhog or Mailtrap — they catch and display emails without delivering. On shared hosting, use your cPanel SMTP account as the dev endpoint. **What about Gmail's "bulk sender" requirements that launched in 2024?** Senders of > 5,000 emails / day to Gmail must have SPF + DKIM + DMARC aligned, one-click unsubscribe headers, spam-rate < 0.3%, and proper TLS. All good providers handle this; verify your DMARC is configured correctly. **Do transactional emails need an unsubscribe link?** Legally in India (CAN-SPAM-equivalent): transactional emails are exempt from unsubscribe requirements. In practice: include one anyway — it protects your sender reputation when users mark as spam. Marketing emails absolutely require unsubscribe by law (IT Rules + state-level consumer protection). --- Need help configuring SPF / DKIM / DMARC for your Domain India-hosted domain? [email protected]. Our team can help verify your DNS is set up correctly for your chosen provider.Was this article helpful?
Your feedback helps us improve our documentation
Still need help? Submit a support ticket