Short answer: For a short-lived password reset, choose the transactional email API whose delivery evidence your team can act on before the link expires. Treat SMS as a deliberate fallback, not proof that the email failed. If your application already uses several backend services, Infrai is a viable direct-API option: one key and one bill cover account lookup, email, and SMS. The trade-off is important: email events are pull-only, so they cannot drive an immediate event-triggered fallback.
What changes when the reset link expires quickly?
Before: the application calls send, sees a successful HTTP response, and records reset_email_sent. After: it records the request outcome separately from recipient delivery, checks subsequent events, and waits for an explicit decision before offering SMS. An accepted API request is not an inbox receipt.
That distinction matters.
Picture the timeline in words: account lookup, token creation in your application, email submission, event observation, expiry, and possibly a new SMS challenge. The token and its expiry belong to the application's authentication flow; do not make a provider's delivery status stand in for token validity. A polling interval longer than the remaining token lifetime makes a delivery event useful for audit but useless for this particular fallback decision. That's the central observability constraint. The same distinction applies to welcome emails, but a password reset makes the timing visible: observing an event after expiry cannot rescue that reset attempt, however accurately the event was recorded. Set the alert window against the actual expiry policy, not against an arbitrary dashboard refresh cycle.
Instrument reset_requested, email_api_accepted, email_api_rejected, email_event_observed, fallback_offered, and reset_completed as separate application events. Keep the recipient address and reset token out of log fields. Correlate with your own opaque request ID; record elapsed time from request to submission and from submission to the next observed event. Alert on a rise in API rejections or resets expiring without completion, not on a single provider response. No delivery metric can establish that a person actually read a message.
How does the account-to-message handoff work?
The single-key approach is concrete: look up the account with the auth API, then use the same credential and base URL for the email submission. The address and token lifecycle stay in application code. For the exact request body and response fields, read the live discovery schema before wiring the send call; a route name alone does not specify a payload.
const base = process.env.INFRAI_BASE_URL;
const key = process.env.INFRAI_API_KEY;
const userId = process.env.RESET_USER_ID;
if (!base || !key || !userId) throw new Error("Set INFRAI_BASE_URL, INFRAI_API_KEY and RESET_USER_ID");
async function readAccount(id: string): Promise<unknown> {
const response = await fetch(`${base}/auth/user/get/${encodeURIComponent(id)}`, {
method: "GET",
headers: { Authorization: `Bearer ${key}` },
});
if (!response.ok) throw new Error(`Account lookup failed: ${response.status} ${await response.text()}`);
return response.json();
}
const account = await readAccount(userId);
console.log("Account lookup completed; validate its email field against the discovery response schema before sending", Boolean(account));
That snippet stops at the validated boundary: the route facts do not establish the account response fields or the email send request schema, so a purported copy-paste sender would be a guess. In production, map the returned account identifier and verified address to your own pending reset record, generate a single-use token in the app, and submit the message through /v1/email/send with an idempotency key. A retry must preserve the same logical message ID. On HTTP 429, honor Retry-After when present or back off exponentially; surface other error bodies rather than assuming success. Never log a reset URL.
The alternative Clerk + Resend + Twilio stack needs three service signups, three credential sets, and application glue for account identity, email suppression, SMS suppression, and correlation across delivery records. One key reduces credential and invoice reconciliation, but concentrates trust, billing, and outage exposure in one provider.
Which transactional email API fits SaaS welcome emails and password resets?
Resend is attractive when a developer-first email integration and its documented sending workflow are the primary requirement. Postmark documents transactional delivery webhooks; it fits teams that need event-driven follow-up rather than polling. SendGrid provides an Event Webhook, which can fit an existing operations pipeline, though the larger surface deserves careful configuration. MailerSend documents email APIs and webhooks as another option when a team wants its email and event workflow together. Check each provider's current regional processing terms and domain requirements against your US/EU obligations; an API's availability does not by itself establish a data-residency commitment.
Infrai fits an application that calls a REST API directly and values one credential across auth, email, and SMS. Domain verification and DKIM rotation cover the basic sender setup. It has no SMTP relay, so it is a poor match for an existing SMTP-only sender. Its email events are listed through pull APIs, without webhook push; for tight reset windows, poll only if the timing is actually useful and never promise immediate fallback based on unseen events. It also has no managed email OTP flow. Keep email verification-code generation in your own application, or choose a provider that explicitly supplies the flow you need. Three separate consoles may be acceptable when immediate delivery callbacks are the deciding requirement. One consolidated credential may be better when onboarding several backend capabilities is the operational bottleneck. Neither choice removes the need to maintain a suppression policy across email and SMS: an address blocked for email does not automatically tell you whether a phone number should receive a reset challenge. Write that decision into the application rather than assuming a vendor can infer it.
Should an expired email trigger SMS automatically?
No. Lack of an observed event is not evidence of failure, especially with pull-only tracking. Offer a fresh SMS challenge after an explicit user action or an application-defined timeout, rate-limit it in your own service, and invalidate or supersede the earlier reset credential according to your auth policy. SMS status can be checked, but geographic abuse controls and per-country spending circuit breakers remain application responsibilities.
Wait for a deliberate signal.
There is a smaller bookkeeping trap here: without an API report of email cost aggregated by tag, cost per reset feature requires your own tagged request ledger. That ledger should separate attempts from successful resets. It will also make the next review more useful than a dashboard that merely says messages were submitted.
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.