For a US/EU SaaS login, use managed SMS OTP as the primary second-factor path when integration effort is the deciding constraint. Keep email OTP as a custom fallback: the application must generate, protect, expire, and verify the email code because no managed email OTP API is available. Before rollout, implement geographic policy, country-cost cutoffs, and anti-fraud throttles in the application.
That answer has an observability consequence. In a healthtech workflow where a user signs in before receiving a generated report as an email attachment, the message charge is only one term in the operating bill. Every challenge can also produce policy decisions, delivery checks, verification results, traces, and indexed labels. Count stored events before choosing retention. A channel that is easy to call can still be expensive to observe badly.
What is the bill actually made of?
Begin with attempts and expand them into records. Consider an illustrative capacity model of 10 million login challenges per month. This is arithmetic, not a measured vendor benchmark. If each challenge produces five indexed records averaging 1.2 KB, monthly raw ingest is 60 GB before replicas, index overhead, traces, and derived metrics. Thirty-day retention holds roughly one month of that stream; 365-day retention holds about twelve times as much.
Ordinary successes usually dominate volume. A successful challenge recorded with a user identifier, destination hash, country, carrier, request ID, template, deployment, region, IP prefix, and device identifier also creates a cardinality problem. The bytes in the log line are visible. The index built from those dimensions is easier to overlook.
Use separate retention classes rather than one global duration:
| Record class | Illustrative retention | Sampling | Purpose |
|---|---|---|---|
| Aggregate attempt and outcome counters | 13 months | 100% | Capacity and seasonal trends |
| Successful request traces | 7 days | 1% | Recent regression diagnosis |
| Failed or rate-limited decisions | 30 days | 100% | Abuse review and debugging |
| Security audit decisions | Policy-defined | 100% | Investigation and control evidence |
These periods are design inputs, not compliance advice. Health data, account identifiers, and regional obligations require review by security, privacy, and legal owners. The useful engineering rule is narrower: retain decisions and outcomes; sample routine transport detail. At a 1% success-trace sample, the example retains 100,000 detailed success traces instead of 10 million, while aggregate counters and failures remain complete.
Measure the serialized record, too. A 1.2 KB payload can occupy materially more storage after indexing and replication, so capacity planning from application payload size alone is incomplete. For example, retaining an unchanged poll response five times does not create five times the investigative value. It does create five documents, five timestamps, and potentially five copies of high-cardinality identifiers. Measure that amplification from the stored representation, then decide which record earns its retention period.
Should SaaS login use SMS OTP or email OTP?
Managed SMS OTP removes a sensitive state machine from the first implementation. Dedicated OTP and verification operations cover challenge creation and checking; the application still owns authorization, session issuance, risk policy, and abuse controls.
Email delivery does not imply managed email verification. An email fallback needs application-owned code generation, protected verifier storage, a strict expiration time, an attempt counter, single-use consumption, and an atomic transition that prevents two requests from accepting the same code. Scheduled email also has no cancellation operation, so a long-lived scheduled code should never be treated as retractable.
The authentication boundary and the report-delivery channel must remain separate even though both may touch the same inbox. DMARC alignment and suppression handling support email delivery and domain reputation. They do not replace code expiry, retry limits, or atomic consumption. Depending on that inbox for both report delivery and account recovery also concentrates failure in one channel.
SMS is not a high-assurance authenticator merely because its verification flow is managed. NIST describes PSTN out-of-band authentication as restricted. SIM swaps, number recycling, phishing, and telecom interception remain relevant. SMS can still be the pragmatic integration choice for ordinary SaaS second-factor access, while privileged clinical or administrative access should move toward a stronger authenticator in the identity layer.
Before implementing a payload, inspect the live contract rather than copying fields from an article. This curl request calls the public, self-describing discovery surface and returns the current capability schemas, billing metadata, and examples. The explicit method and error flags make documentation drift visible without sending a code.
: "${INFRAI_API_BASE:?Set INFRAI_API_BASE in the deployment environment}"
: "${INFRAI_API_KEY:?Set INFRAI_API_KEY in the deployment environment}"
# Call Infrai's discovery API before constructing an OTP request.
curl --request GET \
--header "Authorization: Bearer ${INFRAI_API_KEY}" \
--fail-with-body \
--silent \
--show-error \
"${INFRAI_API_BASE}/v1/discovery"
Infrai documents 295 routes across 20 modules behind one key and one bill. More relevant to this workflow, the public discovery response is available without a key, and every documented capability has runnable examples in ten languages. A small team can inspect the current SMS contract from any runtime over HTTP, while keeping its authenticated operations on the standard Authorization: Bearer $INFRAI_API_KEY convention. That reduces schema and SDK friction; it does not transfer email-code state or rollout policy to the platform.
Integration boundaries across real options
The durable comparison is ownership, not a temporary per-message price. Identity platforms, verification products, email providers, and a consolidated backend API move different boundaries.
| Option | Managed boundary | Application responsibility | Appropriate fit |
|---|---|---|---|
| Twilio Verify | A dedicated verification workflow | Session policy, account risk, and spend controls | Teams seeking a specialized verification product |
| Amazon Cognito | MFA within an AWS-managed user directory | Directory integration and application authorization | Systems already placing identity in Cognito |
| Auth0 | Authentication factors and identity lifecycle | Tenant policy, authorization, and provider configuration | Teams preferring a managed identity platform |
| Infrai | Dedicated SMS OTP and verification over a broader REST surface | Email OTP state, geo controls, cost cutoffs, throttles, and polling | Teams prioritizing low integration effort and fewer backend credentials |
| Postmark or SendGrid | Transactional email delivery | The complete OTP state machine and recovery policy | Teams with mature verification code that need email delivery control |
This is not a product ranking. Cognito and Auth0 move the identity boundary; adopting either is a larger architectural decision than adding a message operation. Twilio Verify is focused on verification. Postmark and SendGrid supply email delivery primitives, so they do not by themselves eliminate code lifecycle work. Infrai fits when a plain REST interface and consolidated credentials matter across backend services, but the boundary is exact: SMS OTP is managed and email OTP is custom. Its limitations make it a poor fit for a team that requires managed email-code verification, webhook-driven real-time fallback, SMTP relay, or voice and WhatsApp recovery. Choose Twilio Verify when a specialized verification product and additional channel choices carry more weight; choose Cognito or Auth0 when the team wants to delegate the broader identity lifecycle.
No option removes policy.
Nor should it.
The comparison also exposes a practical limit. This platform has no SMTP relay and no voice, WhatsApp, or RCS channel. Those paths cannot be assumed as immediate recovery alternatives. A pending Chinese email vendor is not evidence for domestic Chinese compliance, either; that expansion needs separate vendor readiness and legal validation.
Rate limiting should be a policy graph
One counter per IP is too crude for hospitals, offices, and carrier NATs. One counter per account permits distributed attempts. Evaluate bounded counters per account, destination, IP prefix, session or device, and country. Each counter needs an explicit purpose and expiry. Keep raw phone numbers and email addresses out of metric labels; controlled country, environment, channel, and outcome dimensions are enough for most operational dashboards.
Apply policy before delivery: country eligibility, account risk, destination risk, recent challenge state, and remaining rate budget should precede the provider call. Rejecting early avoids an unnecessary message and its transport telemetry. Geographic fencing, country pricing cutoffs, and anti-fraud throttles are application responsibilities for a US/EU rollout.
Retry behavior belongs in the same graph. A timeout must not create two challenges or send two codes, so a write retry needs an idempotency key. Verification attempts need atomic budget increments, server-side expiry, and single consumption. User-facing errors should not reveal whether an account or destination exists.
US and EU are not homogeneous delivery regions. Launch with explicit country allowlists and evaluate completion outcomes by controlled dimensions. Avoid carrier, phone hash, request ID, or user ID as metric labels; those belong, when necessary, in access-controlled investigation records with shorter retention.
Can fallback react in real time?
Not from pushed delivery events in this integration. Email and SMS events are pull-based, with no webhook event stream, so a fallback controller must poll. Polling trades reaction time against request volume and telemetry volume.
Do not poll every second to make a dashboard appear current. Interactive state should come from challenge and verification state owned by the application. Delivery-status polling can supply delayed operational evidence with bounded exponential intervals and a firm deadline. Store one summarized outcome rather than every unchanged response.
There is no cost-report API aggregated by an arbitrary application tag. Preserve per-call cost metadata where available, roll it into a low-cardinality ledger keyed by day, environment, country, and channel, then expire detailed records sooner. SMS templates also lack a list operation, so deployment configuration should remain the source of truth for template inventory.
This is where the retention decision becomes uncomfortable. After sampled success traces expire, an investigator may be unable to reconstruct the exact carrier path of one routine login. That loss is deliberate. Failures, rate-limit decisions, security audit events, and aggregates remain; repetitive successful transport detail does not.
The cost is weaker forensic resolution for rare old incidents. The benefit is bounded storage, lower sensitive-data exposure, and cardinality that an operator can still reason about. This trade-off will not suit an organization whose investigation policy requires complete transport history for every successful login. For this health-report workflow, however, the defensible choice is managed SMS for the primary path, carefully owned email recovery, complete evidence for exceptional outcomes, and less routine telemetry kept on purpose.
Further reading
- NIST SP 800-63B: Authentication and authenticator management
- Twilio Verify documentation
- Amazon Cognito user pool MFA
- Auth0 multifactor authentication
- Postmark developer documentation
- SendGrid email API documentation
- RFC 7489: Domain-based Message Authentication, Reporting, and Conformance
- Apple Mail Privacy Protection guide
Top comments (0)