Guide

Password Reset Emails: Choosing an API

A user clicks 'Forgot password' and stares at their inbox. If the reset email takes 3 minutes or lands in spam, that's a lost session, a support ticket, or a lost customer. This guide compares email APIs specifically for the reset flow — delivery speed, deliverability to Gmail and Outlook, and pricing — then shows how to verify your sender setup and test the whole loop from the terminal.

Written by Nick Barraclough Product Manager

VerifiedCLI 3.1.16 · last tested June 6, 2026

Command references used in this guide: nylas email search, nylas email list, and nylas email read.

Why are password reset emails different from other email?

A password reset email is a transactional send with a human actively waiting on it — the tightest latency requirement in email. Marketing mail can arrive any time in an hour; a reset email that takes minutes strands the user on the login screen, and one that lands in spam usually ends the session. Reset links also expire, commonly within 15-60 minutes, so slow delivery eats directly into the link's usable lifetime.

That profile drives every choice in this guide: you want a sender path optimized for time-to-inbox on single messages, a domain reputation unpolluted by bulk campaigns, and a test harness that measures the loop the way a user experiences it — from the API call to the link in the inbox. Volume math matters too: at 100,000 users with a typical forgot-password rate of a few percent per month, resets are thousands of sends: small for a transactional provider, but enough to demand authentication done right.

What does Gmail require from reset-email senders?

Since February 1, 2024, Google's email sender guidelines require all senders to Gmail accounts to "set up SPF or DKIM email authentication" and use TLS. Senders above 5,000 messages per day must set up SPF and DKIM and a DMARC policy (even p=none qualifies), and must "keep spam rates reported in Postmaster Tools below 0.3%." Messages also have to follow the RFC 5322 format rules.

For reset flows the practical consequence is that authentication is table stakes, not an optimization. Every transactional provider in the next section walks you through publishing SPF and DKIM records during domain verification. What providers can't do for you is keep your reset stream's reputation separate from your marketing stream's — that separation is yours to design, and the spam-prevention section below covers it.

How do the email APIs compare for reset flows?

Transactional email APIs exist for exactly this job: one-way, event-triggered messages sent from your application's domain. The 4 providers below cover the realistic range from infrastructure-priced to deliverability-focused. Pricing facts come from each vendor's public pricing page, linked in the table, as of June 2026.

ProviderPricing anchorFit for password resets
Amazon SES$0.10 per 1,000 emailsCheapest at scale; you own reputation management, IP warmup, and bounce handling
PostmarkFrom $15/month for 10,000 emailsBuilt around transactional speed; separates transactional and broadcast message streams by design
SendGridFrom $19.95/month for 50,000 emailsFull marketing + transactional platform; fine for resets if you already run it
Nylas$15/month including 5 connected accountsContextual (two-way mailbox) API — wrong tool for high-volume resets, right tool for testing them and for low-volume sends from a real mailbox

The honest read: for sending resets at scale, pick a transactional provider. Nylas connects to existing mailboxes (Gmail, Outlook, IMAP) for two-way email, which is the wrong shape for blasting one-way notifications — but exactly the right shape for the receiving side of your reset tests, where a real inbox has to confirm delivery. The transactional vs contextual comparison covers the full decision matrix.

How do you keep reset emails out of spam?

Reset deliverability comes down to 3 controls: authenticate the domain, isolate the stream, and watch the metrics. Authentication is the SPF/DKIM/DMARC setup from Gmail's rules above. Isolation means sending resets from a dedicated subdomain (like auth.example.com) so a marketing campaign's spam complaints never drag down the reputation your reset emails depend on — one subdomain per stream is the pattern Postmark's product design enforces and the other providers recommend.

Verify the DNS side from the terminal before going live. The 3 checks below confirm your records exist; the deliverability debugging guide explains how to read the results and fix the 7 most common failures.

# SPF on the sending subdomain
dig +short TXT auth.example.com | grep spf

# DKIM selector published by your provider
dig +short TXT pm._domainkey.auth.example.com

# DMARC policy
dig +short TXT _dmarc.example.com

How do you test the reset loop end to end?

An end-to-end reset test triggers the flow, then verifies a real inbox received the message and the link inside it works. The inbox side is where most test setups get awkward — and where a CLI on a real test account beats a mock SMTP server, because Gmail's spam filtering is part of what you're testing. The loop below polls for up to 60 seconds, then extracts the reset URL from the message body.

# 1. Trigger the reset in your app (API call or UI test)

# 2. Poll the test inbox for the reset email (60s wall-clock budget)
DEADLINE=$(( $(date +%s) + 60 ))
while [ "$(date +%s)" -lt "$DEADLINE" ]; do
  MSG_ID=$(nylas email search "Reset your password" \
    --from no-reply@auth.example.com --json | jq -r '.[0].id // empty')
  [ -n "$MSG_ID" ] && break
  sleep 5
done
[ -z "$MSG_ID" ] && echo "reset email never arrived" && exit 1

# 3. Extract the reset link from the body
nylas email read "$MSG_ID" --json | jq -r '.body' \
  | grep -oE 'https://example.com/reset[^"<]*' | head -1

Wire the same 3 steps into CI and you have a regression test for the full reset path — sender config, provider delivery, and link generation. For one-time-code flows instead of links, the OTP extraction guide covers pulling 6-digit codes from the same pipeline, and the Playwright email testing guide shows the browser-test integration.

Next steps