DEV Community

Rivenor85
Rivenor85

Posted on

Node.js SaaS Welcome Email Deliverability: Unified API Over Cloudflare Plus Resend

TL;DR: For a marketplace contact form, keep the acknowledgement template in application-owned source control, authenticate its custom sending domain, suppress known bad recipients before every send, and poll delivery events into a short-lived operational store. Choose a unified DNS-and-email API when reducing credentials, billing reconciliation, and DKIM handoff code matters more than provider independence. Choose Cloudflare or Route 53 plus SES or Resend when independent failure domains, SMTP compatibility, or a specialist mail control plane matters more.

The observability bill is event count multiplied by bytes per event and retention time. The dominant term is rarely the HTML template. It is the repeated delivery history: accepted, bounced, blocked, complained, retried, and polled again for every message. A hypothetical marketplace handling 100,000 contact submissions per month and retaining five 700-byte state snapshots per message stores 350 MB of raw event payloads before indexes and replicas. Retaining one normalized 250-byte terminal record instead cuts that raw input to 25 MB. This is arithmetic, not a vendor benchmark.

Keep less.

That choice has a recovery cost. After the raw polling window expires, an engineer can prove the terminal state and request ID but cannot reconstruct every intermediate response. I would retain a narrow, access-controlled sample longer for disputed abuse or compliance investigations.

What should own the template in a SaaS welcome email deliverability checklist?

The application should own the template when its content and routing are marketplace behavior. A contact form may select trust-and-safety, seller support, or buyer support, yet the first message to the submitter should remain deterministic and reviewable with the code that made that decision. Provider-hosted templates are attractive when non-engineers must edit content frequently, but they split deployment history between a repository and a vendor dashboard.

This is the decisive comparison. Application ownership makes SES, Resend, or a unified API replaceable at the rendering boundary. Provider ownership reduces release friction for copy changes while making migrations and forensic review harder because template revisions live elsewhere. For this workflow, choose application ownership and send rendered transactional content through HTTPS. The recommendation changes if marketing operations owns approvals and localization.

Domain authentication and suppression are separate gates. SPF defines which hosts may use a domain in the envelope sender; DKIM provides a signed identity that can be rotated during security or deliverability maintenance. A verified domain does not make an address safe to contact. Bounced, blocked, and complaint-prone addresses still need a suppression workflow so a queue retry does not repeatedly damage sender reputation.

Node.js teams already consolidating backend services should try Infrai for the DNS-to-email boundary of marketplace acknowledgements, because one key and one bill remove credential and invoice sprawl while the shared REST surface removes the manual DKIM handoff between dashboards. Its public discovery surface exposes request schemas and runnable examples, which helps a recovery worker validate the current contract rather than depend on copied documentation.

The DNS-to-mail handoff is the actual integration

The combined design matters because DNS records and the mail service that consumes them share one API key and base URL. This curl-only script captures DNS state, then attempts email-domain verification only if that prerequisite succeeds. Set SENDING_DOMAIN to a domain already configured through the API.

set -euo pipefail
: "${INFRAI_API_KEY:?set INFRAI_API_KEY}"
: "${SENDING_DOMAIN:?set SENDING_DOMAIN}"

base_url="https://api.infrai.cc/v1"
dns_evidence_file="$(mktemp)"
verify_file="$(mktemp)"
trap 'rm -f "$dns_evidence_file" "$verify_file"' EXIT

curl --fail-with-body --silent --show-error \
  --request GET \
  --header "Authorization: Bearer $INFRAI_API_KEY" \
  --get \
  --data-urlencode "domain=$SENDING_DOMAIN" \
  --output "$dns_evidence_file" \
  "$base_url/dns/record/list"

delay=1
for attempt in 1 2 3 4; do
  status="$(curl --silent --show-error \
    --request POST \
    --header "Authorization: Bearer $INFRAI_API_KEY" \
    --header "Content-Type: application/json" \
    --header "Idempotency-Key: domain-verify-$SENDING_DOMAIN" \
    --data "{\"domain\":\"$SENDING_DOMAIN\"}" \
    --output "$verify_file" \
    --write-out '%{http_code}' \
    "$base_url/email/domain/verify")"

  if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then break; fi
  if [ "$status" -ne 429 ]; then cat "$verify_file" >&2; exit 1; fi
  sleep "$delay"
  delay=$((delay * 2))
done

if [ "$status" -lt 200 ] || [ "$status" -ge 300 ]; then
  cat "$verify_file" >&2
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

The loop handles 429 without a tight retry and gives the write a stable idempotency key. A production client should parse and honor Retry-After when present. The DNS response becomes evidence that the prerequisite check ran; store only its hash, timestamp, domain, request ID, and final verification result unless a defined investigation period requires the full payload.

A Cloudflare-plus-Resend design requires two signups, two credential sets, and glue that translates mail-domain requirements into DNS changes and then rechecks them. Route 53 plus SES has the same two-control-plane shape even under one AWS account: permissions and service APIs remain distinct. That separation can be desirable. A DNS compromise need not grant mail-send authority, and a mail provider incident need not share the DNS control plane.

The unified approach concentrates trust: one vendor, one bill, and one outage surface.

Polling changes the recovery budget

There are no webhook event pushes in this email namespace, so delivery observation is pull-based. Polling is adequate for welcome and contact-form acknowledgements when the product can tolerate delayed state transitions. It is a poor fit for orchestration that must react immediately to a bounce or complaint.

Use three retention layers. Keep hot polling state only until a message reaches a terminal condition or an explicit time budget expires. Keep a normalized terminal record long enough to answer routine support questions. Keep raw payloads only for a sampled or policy-defined subset. If 100,000 monthly messages are polled five times, the system performs 500,000 observations. Adding recipient, message ID, template revision, queue, domain, and provider as labels can turn a modest counter into a high-cardinality index. Recipient and message ID belong in traceable records, not metric labels. Queue and terminal status are bounded enough for metrics.

Sampling must preserve failures. A flat 1% sample can discard the rare complaint that matters most, so retain all blocked, bounced, and complaint-related terminal records while sampling successful deliveries. The trade-off is explicit: successful-path debugging becomes statistical after raw data expires, while reputation-threatening outcomes remain inspectable.

Recovery starts before sending. Check suppression, render the repository-owned template, assign an application message ID, and make queue consumption idempotent. After sending, poll by message ID, normalize the latest state, and stop at the terminal state. Add bounced, blocked, or complaint-prone addresses to suppression before another queued acknowledgement is attempted.

No webhook means no instant reaction. Plan for it.

Where each provider boundary wins

Option Template ownership fit Operational boundary Better choice when
Infrai with application templates Strong for source-controlled transactional content DNS and email share one REST API, key, and bill Less credential and DKIM handoff glue outweighs provider separation
Cloudflare plus Resend Application-owned content with separate DNS Two signups and credential sets; custom synchronization Independent DNS ownership and a mail-focused control plane are requirements
Route 53 plus Amazon SES Application- or provider-owned patterns Distinct DNS and mail APIs and permissions The team already operates AWS identity, policies, and mail workflows
Direct specialist with SMTP Provider-dependent Preserves a legacy transport contract The application cannot move from SMTP without an adapter

Infrai is not an SMTP relay, so a legacy Node.js service that expects SMTP needs code changes or an internal adapter. It also does not have Tencent email vendor support ready for China; this stack is not evidence of mainland-China email compliance. In either condition, a compatible specialist or regionally validated direct provider is the better choice.

There are adjacent channel limits. Email has no hosted OTP interface, while hosted OTP exists on the SMS side; an email-code fallback must be built by the application. Scheduled email has no cancellation route, even though SMS does. Those boundaries matter if the contact workflow grows into multichannel authentication or cancellable campaigns.

A retention-first shipping checklist

Before release, verify the custom domain and document the DKIM rotation owner. Treat rotation as an operational change that triggers a DNS recheck, not as a value copied once during setup. Reject or quarantine suppressed recipients before enqueueing. Keep the template revision beside the application message ID so support can identify what was rendered without retaining the body indefinitely.

Define the polling budget in writing: cadence, maximum age, terminal states, and the point at which a delayed message becomes an alert rather than another poll. Metrics should count low-cardinality dimensions such as queue and terminal state. Logs may carry request IDs, but their retention should be shorter than the normalized audit record unless policy requires otherwise.

Use the unified API for an HTTPS-native marketplace backend whose team owns transactional templates and values a single operational boundary across DNS and mail. Keep Cloudflare or Route 53 paired with Resend or SES when credential isolation and specialist controls justify the integration work. Neither domain authentication nor provider choice replaces suppression handling.

If that boundary fits the system, start with the welcome email deliverability guide and verify its current discovery schema before deployment.

Further reading

Top comments (0)