You're shipping transactional email — receipts, password resets, magic links, notifications. You can deliver them through an SMTP relay (port 587 / 465 with STARTTLS or implicit TLS) or through a REST API (HTTPS POST with a JSON body). Both work. Both are battle-tested. The choice is not religious — it's an engineering call shaped by your stack, your latency budget, and how much observability you actually want.
This post is the comparison I wish existed when I was integrating Sendr365 the first time. We'll cover the tradeoffs, the failure modes, and which one to reach for in five common scenarios.
The 60-second summary
- REST API wins when you want structured retries, signed webhooks, observability per send, and tight code-side control. Best fit: modern SaaS app code, edge functions, serverless workers.
- SMTP relay wins when you can't change the sending code — legacy CMS, off-the-shelf platforms (WordPress, Shopify themes, Magento), third-party tools that only know how to talk SMTP, or scenarios where you need a drop-in replacement for your existing mail server.
- You can mix them. Send transactional from REST and let your CRM use SMTP. As long as both authenticate against the same domain, deliverability is the same.
Latency: where they actually differ
REST API in the modern config: a single HTTPS POST. TLS handshake reused on warm connections, total round-trip 80-250ms depending on region and how clean your network path is. The body is JSON; the response includes a message ID synchronously.
SMTP relay: at minimum, a TLS handshake, an EHLO, an AUTH, a MAIL FROM, an RCPT TO, a DATA, the message body, and a QUIT. Six round trips before the message is even handed off — typically 400-900ms total on a cold connection. Connection pooling helps a lot (subsequent sends drop to ~150ms), but the first send of any cold worker eats the full handshake.
For password reset emails where the user is staring at a loading spinner, that difference matters. Use REST and resolve the request in 200ms. For batch notifications fired from a background job, neither matters.
Observability: REST has the structural advantage
SMTP's reply codes are coarse. 250 = accepted,421 = transient, 5xx = permanent. The text after the code varies by provider and is often unparseable. You learn that your message was rejected; you don't learn why with any structure.
REST APIs return JSON. Sendr365's send response gives you:
{
"id": "msg_8c2f4a1e9b3d4f7a",
"status": "queued",
"tenant_id": "ten_abc",
"domain": "yourdomain.com",
"from": "[email protected]",
"to": "[email protected]"
}The id threads through every downstream event — sent, delivered, opened, clicked, bounced, complained, unsubscribed. SMTP gives you no equivalent. Most relays fall back to parsing the message ID out of the queued message, which works but adds a code path you didn't need.
Webhooks: a REST-only feature in practice
Both REST APIs and SMTP relays can dispatch webhooks for downstream events (delivered, opened, etc.). But REST APIs let you correlate the inbound webhook to the original send via the same message ID. SMTP relays correlate via the message ID generated at SMTP time, which you have to parse out and store.
Sendr365 emits HMAC-SHA256-signed webhooks for every event regardless of how the message was sent. The difference is that REST users get theid in the response and can store it before the webhook ever arrives — clean correlation. SMTP users have to read theQueued as XYZ line in the SMTP response and store that.
Retries: where SMTP's queue model still helps
SMTP servers are queue-by-design. If your relay accepts a message but the downstream MTA is slow, the relay holds the message and retries on its own schedule (usually exponential backoff up to 72 hours per RFC 5321). Your code is done.
REST APIs return immediately, so your code owns the retry. With Sendr365 the send is queued upstream the moment our API returns, so you get the same durability — but only if the API call itself succeeded. If your network blip ate the POST, your code has to re-fire it. SMTP's long-lived TCP connection with built-in retries is more forgiving in flaky-network environments (mobile devices, container starts behind unreliable NAT).
For most server-to-server traffic this doesn't matter. For edge functions or mobile clients sending mail directly (rare and usually wrong), SMTP's retry semantics are a small advantage.
Authentication: what each one expects
REST authenticates with a per-tenant API key, sent as anX-API-Key header. The key never leaves your server-side env; rotation is instant; revocation is instant. We track usage per key for audit-log purposes.
SMTP authenticates via PLAIN or LOGIN with a username and password. We tie these to the same API key system but the credential is sent with every connection — your relay code (or its config file) holds it. Rotation requires a config push and a graceful restart; revocation can leave in-flight connections authenticated for a few seconds.
Neither is meaningfully more secure if you're doing the basics right (TLS, secret manager, no env vars committed to git). The operational difference is speed of rotation — REST wins by a small margin.
Templates and dynamic content
REST APIs let you reference a template by ID and pass variables in the request body:
POST /api/v1/email/send
{
"to": "[email protected]",
"template_id": "tmpl_welcome_v3",
"variables": {
"first_name": "Alice",
"verify_url": "https://app.example.com/verify/abc123"
}
}SMTP needs the rendered HTML in the message body. Your code does the substitution, then hands the final body to the relay. That's fine — most templating engines do it in a few ms — but it means any template change requires a code deploy. With REST and template IDs, you can update copy in the dashboard without redeploying.
Five concrete scenarios
1. Modern Node/Python/Go SaaS, server-side sends
Use REST. Faster, easier to log, cleaner correlation with webhooks. The only reason to choose SMTP here is if you already have an SMTP client integrated and don't want to switch.
2. WordPress, Shopify, Magento, off-the-shelf CMS
Use SMTP relay. The plugin ecosystem assumes SMTP. Drop in our host, port, and credentials and it just works. Sendr365 supports both port 587 (STARTTLS) and 465 (implicit TLS) for compatibility with every plugin we've seen.
3. Edge function (Cloudflare Workers, Vercel Edge, AWS Lambda)
Use REST. Edge runtimes either don't support raw TCP (Workers) or charge for connection time. HTTPS POST is what they're built for.
4. Existing on-prem app with hardcoded SMTP config
Use SMTP relay. Replace the host with ours and you're done. No code changes. Domain auth stays the same.
5. Mixed: high-volume marketing + transactional in one app
Use REST for both, but on different IP pools. Sending marketing and transactional mail from the same IP pool is one of the fastest ways to torch your sender reputation — a campaign blast that triggers complaints contaminates your password-reset deliverability the next morning. Use REST endpoints scoped to separate pools and let the platform isolate them upstream. Read more in our Transactional Email Handbook.
What about latency-critical sends to specific receivers?
Both SMTP and REST hand off to the same upstream MTA infrastructure. Once the message is queued, the protocol you used to submit is invisible to Gmail or Microsoft. Inbox delivery time is dominated by upstream queue depth and receiver-side throttling, not by your submission protocol.
If your password reset takes 3 seconds to land, that's probably upstream queue + Gmail's receive-side processing — not your submission method.
The real-world recommendation
New SaaS, fresh codebase: REST. Better DX, better observability, better correlation with downstream webhooks, easier to evolve.
Existing system you can't modify: SMTP relay. We support both on Sendr365 — same domain auth, same DKIM signing, same deliverability, same dashboard.
If you're still deciding, read the developer docs — the quickstart shows both protocols side-by-side and you can pick whichever fits your stack. The pricing page tier you land on is the same either way; we don't charge differently by protocol.
