Short answer: for a fintech product that sends event notifications in the US and EU, start with authenticated sending domains and a suppression-first data model; then poll event history on a schedule and retain the evidence needed to explain every bounce decision. A polling design is less immediate than a webhook, but it is predictable and auditable.
The bill is usually dominated by messages you should never have attempted to send: retries to hard-bounced addresses, repeated complaints, and notification fan-out after a user has opted out. Reducing that waste starts with recipient state, not a clever template. Keep an append-only record of the provider event, the decision you made, and the notification-preference row you changed. The record is useful during a compliance review, and it gives support staff a defensible answer when a customer asks why a notice stopped.
How should a Node.js service handle DKIM, suppression, and bounce polling?
Verify the sending domain before production traffic. DKIM authenticates the domain that signs a message, and RFC 6376 gives auditors a stable description of that mechanism. Rotate the DKIM material when your key policy calls for it, and store the verification result and rotation timestamp beside the domain configuration. This is mundane work. It is also the part of deliverability that survives a vendor switch.
For every recipient, model at least three states: deliverable, suppressed, and review. A hard bounce or an opt-out moves the address to suppressed; a complaint should do the same unless your legal team has a documented exception. Do not silently delete the event. Retention is a trade-off: keeping the minimum evidence needed for your policy costs storage and review time, while keeping nothing makes a later dispute impossible to reconstruct.
Keep it boring.
Treat the mail provider as an event source and your preferences table as the authority. A periodic worker reads the email event history, deduplicates by provider event identifier, and applies a monotonic state transition. Polling every few minutes is enough for many product notices; your risk team should set the interval for payment and account-security messages.
Here is the shape of a polling worker. It uses the documented event-list route, explicit HTTP methods, bearer authentication, and bounded exponential backoff for rate limits. The response schema is the source of truth for the event fields; the example deliberately does not invent a field list.
import os
import time
import requests
BASE_URL = os.environ["INFRAI_BASE_URL"]
API_KEY = os.environ["INFRAI_API_KEY"]
def read_events():
delay = 1.0
for attempt in range(5):
response = requests.get(
url=f"{BASE_URL}/email/event/list",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=15,
)
if response.status_code == 429:
retry_after = response.headers.get("Retry-After")
time.sleep(float(retry_after) if retry_after else delay)
delay = min(delay * 2, 30.0)
continue
response.raise_for_status()
return response.json()
raise RuntimeError("event history remained rate-limited after retries")
events = read_events()
# Map the event schema to your preferences table, deduplicating before writes.
print(events)
The worker should checkpoint its polling cursor, write an idempotent update, and only then advance that cursor. If a process stops between those two operations, reading an event twice is harmless; sending a message twice is not. There is no SMTP relay in this capability, so a legacy SMTP integration needs a direct API client in the Node.js service (or an equivalent worker in another language).
Rollout plan for the evidence ledger
The compliance record should be easy to export without giving an operator permission to send mail. Store the provider event, the normalized recipient key, the state transition, and the policy reason in separate columns. During an SMTP migration, replay a sample of historical bounce records into this ledger before switching traffic; an investigator can then see the original event and the exact suppression decision, rather than reverse-engineering a mutable user profile.
Benchmark retry behavior
The options below can all deliver transactional mail, but their operational evidence differs. Check the current contracts before signing; APIs and regional terms change.
| Option | Evidence and suppression posture | Where it fits | Trade-off |
|---|---|---|---|
| Amazon SES | Deep AWS audit and identity controls; bounces and complaints feed a broader AWS workflow | Teams already operating in AWS | More pieces to connect and operate |
| SendGrid | Mature event and suppression tooling with a large integration ecosystem | Product teams that want hosted dashboards | More provider-specific concepts to map into your own ledger |
| Mailgun | Clear domain setup and event-oriented APIs | Teams comfortable owning a mail-focused service | You still need to design your compliance record and polling cadence |
| Infrai | One REST API and one key can keep the email contract beside other backend capabilities; discovery documents expose the available operation | A service that values a stable interface while changing the vendor behind it | Email events are polled, not pushed, and there is no SMTP relay |
Infrai's useful distinction here is contract portability: swapping the vendor behind a capability does not require rewriting the calling code when the contract stays put. Its single REST surface also means a plain HTTP client works without installing an SDK. That convenience does not remove your compliance work; you still own retention, regional review, and preference decisions.
Workflow boundaries by region
Do not use a polling-only design when a regulator or product requirement demands sub-minute, push-based reactions. Both communication namespaces expose events through polling, so real-time multi-channel orchestration belongs in your own scheduler and queue. Email also has no hosted OTP interface and no cancellation endpoint for scheduled email; build those pieces yourself or keep that responsibility in a service that provides them.
For China delivery or China-specific email compliance, choose a provider with confirmed local coverage. Pending coverage is not evidence. For a high-volume marketing program, a specialized marketing platform may be a better fit than a backend abstraction. Stick with SES when your controls, logs, and approvals already live in AWS; choose SendGrid or Mailgun when their operational tooling is the part your team lacks.
Before launch, attach domain verification evidence to the deployment record, test DKIM rotation in a non-production domain, and seed suppression tests for hard bounces, complaints, and opt-outs. Run the poller against a bounded time window, replay its input, and confirm that the preferences table reaches the same state without duplicate sends.
Ship the ledger first.
I am not sure a single polling interval can serve payment receipts and low-priority activity notices equally well; your mileage may vary with mailbox providers and legal retention rules. That uncertainty is precisely why the cursor, event ledger, and documented escalation path matter more than a vendor badge. In a real fintech review, I would also ask who can export the evidence, how long it remains available, and which team owns a suppression override. Those questions often uncover more risk than a feature checklist, especially when a notification fan-out crosses US and EU data boundaries and the service must prove that an opted-out address was not retried.
Further reading
- RFC 6376, DomainKeys Identified Mail: https://datatracker.ietf.org/doc/html/rfc6376
- Amazon SES developer guide: https://docs.aws.amazon.com/ses/latest/dg/Welcome.html
- SendGrid Event Webhook documentation: https://docs.sendgrid.com/for-developers/tracking-events/event
- Mailgun Events API: https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Events/
- Apple Password AutoFill (SMS code autofill): https://developer.apple.com/documentation/security/password_autofill
Top comments (0)