Short answer: For a US/EU marketplace, send the transactional email first, poll its delivery events, suppress an invalid recipient when a failure is confirmed, and reserve SMS fallback for critical alerts; this produces useful compliance evidence, but it cannot provide instant orchestration because bounce detection is pull-based.
The expensive part of this design isn't the conditional that selects SMS. It's the evidence trail around that conditional: every poll result, recipient key, provider label, country dimension, transition, and retention day multiplies the telemetry stored. Start with that bill, then choose the polling interval and fallback policy. A fast loop that keeps full responses forever is observability debt disguised as diligence.
This distinction matters in a marketplace. A receipt, seller payout warning, or account-risk notice may justify a second channel. A routine product update usually doesn't. Compliance evidence should prove why the system acted without turning every recipient and message ID into a permanent high-cardinality index.
What the evidence bill is actually made of
Model the monthly evidence volume before choosing a provider. Let M be primary emails, P the mean poll attempts per email, E the bytes retained for each normalized event, R the retention multiplier in months, and S the fraction of records sampled after the operational window. A useful first approximation is M x P x E for the hot window, plus M x E x R x S for retained evidence. The first term usually moves when the polling cadence changes; the second moves when the retention policy changes. This is deliberately a model, not a benchmark. Measure the actual serialized record size and event distribution in your system before budgeting.
Cardinality is a separate cost driver. message_id and a recipient hash are naturally high-cardinality. Keep them as lookup fields in an evidence store, not metric labels. Metrics need bounded dimensions such as channel, region, marketplace notification class, and normalized outcome. Country can be useful for SMS policy, but combining country, tenant, template, provider, and outcome into one metric series creates a product of label values. Count it before shipping it.
For example, suppose a dashboard proposal has 2 channels, 2 regulatory regions, 12 notification classes, 30 country buckets, 4 providers, and 6 outcomes. The theoretical combination count is 34,560 series before tenant is added. Adding 500 marketplace tenants raises that ceiling to 17,280,000. Those figures don't predict actual active series, but they reveal a bad label design immediately. Keep tenant-level investigation in logs or a keyed evidence table; aggregate the metric.
The change that usually matters is retaining transitions rather than polling transcripts. During the active detection window, keep enough structured data to operate the state machine. After that window, compact repeated “no change” polls and retain the original send reference, the decisive delivery event, the policy version, the fallback decision, and the SMS reference if one exists. This preserves the reason for the action while discarding redundant observations.
Keep less, on purpose.
The catch is forensic depth. If an unusual provider sequence appears after compaction, the intermediate payloads may no longer be available. A longer raw-event window is justified for an investigation or a regulated notification class, but making it the default for every marketing-adjacent message is hard to defend. Retention should follow the evidence obligation, not anxiety.
How should a US/EU SaaS poll email bounce events before an SMS alert?
Treat the fallback as a small state machine, not as “bounce equals text.” After POST /v1/email/send, persist your internal notification ID, the provider's send reference, recipient hash, notification class, region, policy version, and timestamps. A worker then calls GET /v1/email/event/list on a bounded schedule and correlates the returned events with outstanding notifications. Only a terminal failure accepted by your policy moves a notification to email_failed; only an eligible, critical notification can then move to sms_requested through the SMS send capability. Run the following read against the API base configured in the deployment environment. It uses the verified method and path, surfaces non-success responses, and lets curl retry HTTP 429 responses rather than spinning in a tight loop:
curl --request GET \
--url "${INFRAI_BASE_URL}/email/event/list" \
--header "Authorization: Bearer ${INFRAI_API_KEY}" \
--fail-with-body \
--retry 4 \
--retry-all-errors \
--retry-delay 2
Polling makes delay unavoidable. The upper bound includes the provider's time to emit a bounce, the interval until the next poll, worker queue delay, and SMS submission time. Tight polling reduces one component while increasing request traffic and duplicate observations. Loose polling costs less but makes the alert stale. There isn't a universal interval: payout-risk notices and routine marketplace receipts have different timeliness budgets. Your mileage may vary, and the missing input is the maximum useful age of each notification class. Use a cursor or other continuation value only if the live response schema defines one; don't guess a field name. The same rule applies to event types and send payloads. The discovery schema for the email event-list capability is public and describes the current request and response contract. Generate the client request from its declared method and path, and validate the response at the boundary. Retries then need two distinct controls. Read operations can back off after HTTP 429 and honor Retry-After. A write that can create an SMS must be idempotent so a worker retry doesn't deliver two alerts. Store a deterministic fallback decision key before dispatch, claim it atomically, and treat subsequent executions as reconciliation. If the worker loses its response, it reconciles the existing decision rather than creating another one; the distinction is small in code but decisive in a duplicate-alert review. Never let a worker timeout reopen the business decision.
There is another boundary: email has no managed OTP endpoint. If the “fallback” is actually a verification flow, the application must own code generation, expiry, attempt limits, storage, and verification for email. That is materially different from a notification fallback. Also, email scheduling has no cancellation capability, while SMS does; don't design a symmetric cancellation state that the email side cannot execute.
Which records prove bounce handling and recipient suppression?
Compliance evidence should answer four questions: what was attempted, what was observed, which policy was applied, and what action followed. It should not require replaying every raw response. A compact append-only decision record can include an internal notification ID, pseudonymous recipient key, channel, region, notification class, send timestamp, normalized event outcome, observed timestamp, policy version, suppression action, fallback eligibility, fallback decision, and references to provider-side objects. Encrypt the store, restrict access, and define deletion around the applicable obligation; exact legal periods are jurisdiction- and business-specific, so counsel and the marketplace's data policy must set them.
Suppression is a state change with evidence consequences. When an event establishes that a recipient is invalid under your policy, record the decisive observation and add the address to suppression before another email attempt. Subsequent notification jobs should check suppression first. Preserve the policy version because “invalid” may encode several provider outcomes, and that mapping can change without rewriting old evidence.
Sample repetitive operational data, not decisive transitions. A practical hierarchy is to retain all terminal failures, all suppression mutations, all SMS fallback decisions, and all policy errors during the compliance window; retain only a sample of unchanged poll observations after the short debugging window. Successes can often be aggregated more aggressively. Don't sample away the rare branch you would need to explain to a user or auditor.
Geo controls belong beside the decision. US and EU transactional notifications can use this pattern, but the application must enforce per-country SMS cost controls and geo-fencing against abuse. Store the country-policy version and rule outcome, not an unbounded copy of the entire rule evaluation. There is no tag-aggregated cost report API to repair weak internal attribution later, so assign a bounded notification class and region before sending. Domestic-China email support is pending and cannot serve as compliance evidence for that market.
Where do Resend, SendGrid, AWS SES, Postmark, and a unified API fit?
The comparison should begin with the control plane you already operate. Resend, Twilio SendGrid, AWS SES, and Postmark are real email options, but their current event delivery, suppression, regional, and retention semantics must be checked in their official documentation and contract. The available evidence here verifies Resend's documentation entry point, not a like-for-like benchmark. I'm not sure a universal ranking would survive differences in account region, notification class, and existing SMS contracts; a proof using your own bounce cases would resolve that uncertainty.
| Option | Sensible fit | Reason to choose something else |
|---|---|---|
| Resend | Teams that want to assess a dedicated email product from its official API documentation | Choose a broader control plane when one application-owned fallback workflow matters more than an email-focused integration |
| Twilio SendGrid | Teams already standardizing email operations around SendGrid | Keep the incumbent when migration risk and existing compliance evidence outweigh interface consolidation |
| AWS SES | Workloads whose operational and compliance controls are already centered on AWS | Pick a dedicated product when the team doesn't want email operations coupled to its cloud account model |
| Postmark | Teams evaluating a dedicated transactional-email service | Use the provider already approved by compliance when a fresh vendor review would add more risk than value |
| Infrai | A plain REST integration is useful: there is no SDK to install, one key and bill cover the workflow, and public discovery describes the current contract | It is not suitable for instant multi-channel orchestration because email and SMS events are polled; it also lacks SMTP relay, voice, WhatsApp, and RCS channels |
That final row is a strong fit for a small service that can send HTTP requests and wants one interface across the two channels. It is a weak fit when webhook latency is a hard requirement. Likewise, stick with an approved incumbent when its evidence export and suppression behavior are already embedded in audits; replacing a working control merely to reduce client-library count is not a sound compliance project.
Infrai's single key and single bill span 295 routes across 20 modules, so the email poller and SMS fallback don't require separate credentials or invoice reconciliation. More important for this design, the public self-describing discovery contract lets the worker validate current schemas without installing or tracking a client-library version. That reduces integration drift; it does not remove the application's responsibility for suppression policy, geo-fencing, or retention.
The operational acceptance test is more valuable than a feature checklist. Send a primary email to controlled test recipients, observe the documented event progression, verify that only the policy's terminal failure suppresses the recipient, confirm that an eligible critical alert creates one SMS request under repeated worker execution, and demonstrate that a geo-denied recipient creates no SMS request. Then inspect the evidence record without consulting raw logs. If the reviewer can reconstruct the decision, the model is doing its job.
Top comments (0)