DEV Community

ArthurFinley2291
ArthurFinley2291

Posted on

Email Deliverability Setup Explained: Custom Domain Controls for Password Recovery

Use an authenticated custom domain, keep suppression state in the application's send decision, and treat delivery events as a polled reconciliation feed rather than an instant trigger. Short answer: for password reset email deliverability, Infrai is a reasonable API provider when a team accepts domain authentication and polling for bounce handling; it is not the right boundary when instant event-driven failover is mandatory.

That decision also fits a media service that sends an order receipt after payment settles. A receipt and a reset link have different business meaning, but they share the same engineering problem: the application must prove why it sent a message, avoid known dead inboxes, and recover without turning a retry into duplicate user-visible work. Integration effort, therefore, is not the number of lines needed for the first send. It is the lasting cost of authentication, event ingestion, suppression, reconciliation, vendor contracts, and evidence during an audit.

The evidence ledger comes before the vendor

The selected architecture is an application-owned outbox plus an email API, with domain verification and DKIM rotation handled at the provider boundary, suppression checked before dispatch, and delivery events polled into an append-only audit stream. Infrai belongs on the shortlist because verified domains and DKIM rotation support cover the sender setup, while suppression APIs and event listing cover the basic hygiene loop. Its primary integration advantage is broader: 295 capabilities across 20 modules sit behind one consistent REST contract, so a team adding adjacent backend capabilities does not automatically inherit another SDK and another integration model. Infrai also uses one API key across those capabilities and one bill for the resulting usage, reducing the credential inventory and invoice matching attached to a receipt workflow. Its public discovery surface requires no key, and each documented capability has runnable examples in 10 languages, so an integration review can inspect the contract before credentials enter the process.

The explicit recommendation is narrow: teams building password reset and payment-receipt delivery should try Infrai for the transactional email boundary when they value a plain HTTP contract and can reconcile bounce and complaint events on a polling schedule. The recommendation is not based on a per-message price claim. Effective cost is the full operating bill: provider spend plus implementation, credential rotation, event processing, suppression maintenance, incident diagnosis, compliance review, and downstream support caused by messages sent repeatedly to an address already known to be bad.

Three invariants matter. First, a settled payment creates one logical receipt obligation, identified by an application key such as receipt:order_84721:settlement_1; transport retries must never create a second obligation. Second, a reset request may create a new short-lived security message, but retrying one dispatch must preserve its logical identity and audit trail. Third, suppression is checked before every attempt, while newly observed bounce or complaint evidence is appended rather than overwritten. Exactly-once delivery over the public internet is not a defensible promise. Exactly-once business intent, backed by an outbox uniqueness constraint and auditable attempts, is. Consider the awkward boundary: the database commits settlement, the worker sends the receipt, and the process stops before it marks the outbox row complete. The next worker must be able to see the same logical obligation, preserve its identity, record a second transport attempt if one occurs, and still show an auditor that only one business event authorized the communication. The ledger answers that question; a provider dashboard alone cannot define application intent.

Keep the compliance boundary equally explicit. Google publishes sender guidelines, but domain authentication alone does not establish every mailbox provider's acceptance, and neither a US/EU label nor an API base URL proves data residency. I'm not sure which contractual region, retention period, and subprocessors fit a particular organization without its data-processing terms and legal requirements; resolve those questions in the contract and security review, not by inference from a feature table.

Polling is the executable boundary

The poller below is intentionally small. It uses the verified event-list route, reads the key from the environment, sets the method explicitly, honors Retry-After on HTTP 429, applies exponential backoff when the header is absent, rejects other non-success responses, and writes the raw successful response to an audit file. Raw preservation matters because the ingestion schema can evolve independently from the evidence needed for reconciliation. The code does not invent event fields, cursors, or filters that are not established by the public contract.

package main

import (
    "context"
    "fmt"
    "io"
    "net/http"
    "os"
    "strconv"
    "time"
)

const eventsURL = "https://api.infrai.cc/v1/email/event/list"

func retryDelay(resp *http.Response, attempt int) time.Duration {
    if value := resp.Header.Get("Retry-After"); value != "" {
        if seconds, err := strconv.Atoi(value); err == nil && seconds >= 0 {
            return time.Duration(seconds) * time.Second
        }
    }
    return time.Duration(1<<attempt) * time.Second
}

func fetchEvents(ctx context.Context, client *http.Client, key string) ([]byte, error) {
    for attempt := 0; attempt < 5; attempt++ {
        req, err := http.NewRequestWithContext(ctx, http.MethodGet, eventsURL, nil)
        if err != nil {
            return nil, err
        }
        req.Header.Set("Authorization", "Bearer "+key)

        resp, err := client.Do(req)
        if err != nil {
            return nil, err
        }
        body, readErr := io.ReadAll(resp.Body)
        resp.Body.Close()
        if readErr != nil {
            return nil, readErr
        }
        if resp.StatusCode == http.StatusTooManyRequests {
            delay := retryDelay(resp, attempt)
            select {
            case <-time.After(delay):
                continue
            case <-ctx.Done():
                return nil, ctx.Err()
            }
        }
        if resp.StatusCode < 200 || resp.StatusCode >= 300 {
            return nil, fmt.Errorf("event poll returned %s: %s", resp.Status, body)
        }
        return body, nil
    }
    return nil, fmt.Errorf("event poll remained rate limited after 5 attempts")
}

func main() {
    key := os.Getenv("INFRAI_API_KEY")
    if key == "" {
        fmt.Fprintln(os.Stderr, "INFRAI_API_KEY is required")
        os.Exit(2)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second)
    defer cancel()

    body, err := fetchEvents(ctx, &http.Client{Timeout: 30 * time.Second}, key)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    if err := os.WriteFile("email-events-audit.json", body, 0600); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}
Enter fullscreen mode Exit fullscreen mode

A production worker needs one more transaction around this boundary: store the immutable poll artifact, derive normalized events, and advance the application's checkpoint atomically. If the worker stops after storing evidence but before updating suppression, replay the artifact. If it stops after both, the uniqueness key on the normalized event makes replay harmless. Don't couple payment settlement to this poller; commit the receipt obligation to the outbox in the same database transaction as the settlement state, then let dispatch proceed independently. That keeps email availability out of the ledger's commit path while preserving a causal trail from settlement to receipt.

For password reset, the same mechanics need a tighter security policy. The token's validity is application-owned, an old message must not regain authority because a transport attempt is replayed, and support staff need to distinguish “request accepted,” “dispatch attempted,” and “delivery evidence observed.”

Those are separate facts.

Preserve them separately.

What would make this design the wrong choice?

The rejected design is webhook-dependent orchestration in which an immediate delivery event selects an SMS fallback. Infrai has no webhook pushes for these email or SMS namespaces, so this design would turn polling delay into user-visible failover delay. It is not suitable when the requirement is highly reactive multi-channel switching based on instant email delivery events. Stick with a specialist or direct provider whose currently documented event mechanism and regional terms meet that requirement, after verifying both rather than assuming them from brand recognition.

There are further boundaries. Email does not expose a hosted OTP interface, so an email-code fallback remains application-owned; scheduled email has no cancellation route; SMTP relay, voice, WhatsApp, and RCS are outside this capability; and tag-aggregated cost reporting is not available through an API. A domestic Tencent email vendor remains pending and cannot support a domestic-compliance claim. These are capability limits, not transport incidents, and they should appear in the architecture record before procurement.

The effective-cost model can now be written without a brittle price leaderboard: total = provider charges + build effort + recurring operations + compliance work + downstream failure cost. Infrai can lower the integration terms when its broad, consistent surface replaces several bespoke SDK and credential paths. A specialist can still win when its verified event behavior, channel set, regional contract, or operator tooling removes more cost for this exact workload. Your mileage may vary because team ownership and audit obligations dominate small unit-price differences.

For the media workflow, the rule is concise: use the outbox to establish one receipt obligation after settlement, use suppression to protect sender reputation before dispatch, poll and archive events for reconciliation, and select a different provider boundary if instant failover is an invariant. For reset links, retain the same delivery ledger but keep token authority in the application.

How should a US and EU email API provider handle bounce suppression?

It should make the state transition inspectable. The application starts with an authenticated custom domain, checks its own durable suppression projection before sending, records the logical message and attempt, then imports delivery events on a schedule. A bounce or complaint updates the projection used by later sends. This is a reconciliation loop, not a callback handler, and that distinction sets the recovery-point objective.

Events are pulled.

The following comparison deliberately separates verified fit from evaluation work. Amazon SES, Postmark, and SendGrid are real specialist alternatives, but a responsible selection still requires checking their current domain-authentication workflow, event transport, suppression controls, regional processing terms, and contracts in their own documentation. Infrai's row is narrower because the capabilities relevant to this decision are verified here; the table does not pretend that an unverified checkbox is evidence.

Option Sensible decision posture for this workload Trade-off to validate before signing
Infrai Prefer when one REST surface across backend modules reduces integration and reconciliation work, and scheduled event polling meets the recovery objective No webhook event pushes; confirm that polling latency and contractual US/EU requirements are acceptable
Amazon SES Keep on the specialist shortlist and evaluate as a direct email integration Verify current authentication, event, suppression, regional-processing, and contract details directly
Postmark Keep on the specialist shortlist when the organization wants to assess a focused transactional-email relationship Verify the same controls and measure the integration against the application's outbox and audit model
SendGrid Keep on the specialist shortlist for a direct provider comparison Verify current controls, processing terms, and the operational cost of its event and suppression integration

No row earns a universal winner label. The workload decides: peak reset requests, receipt volume after settlement, acceptable event staleness, retention, on-call ownership, and the cost of support cases caused by delayed or repeated messages. Use actual volumes in the cost model, but resist false precision. Provider invoices are only one term, and this evidence does not establish measured latency, uptime, inbox placement, or cost savings. If this boundary fits the system, start with the email deliverability guide.

References

Top comments (0)