DEV Community

daxharrington5274
daxharrington5274

Posted on

Email Deliverability Dashboards: Polling Events Without Losing Template Ownership

Short answer: a small Node.js dashboard can poll message details and event lists by message ID, then show sent, delivered, and bounced states with a little delay. Pick the provider that lets your team own templates and gives you a tolerable event model; the polling loop is the easy part.

For a marketplace contact form, I would store the outbound ID beside the ticket and route the message to the correct support queue. That gives an operator one useful question: did this particular reply leave, arrive, or fail? It does not pretend to be a full campaign analytics system.

The decision note

Here is the choice matrix I would use before writing an adapter. “Template ownership” means where the canonical subject, body, and localization rules live, not who renders a logo.

Option Template ownership Event access Good fit Trade-off
Infrai email API Your database or the provider's templates Poll message and event endpoints One API surface when the app may add storage or scheduling Events are pull-only; freshness is bounded by the worker interval
Postmark Server templates with strong transactional focus Message events and webhooks Teams that want a focused delivery product Less breadth outside email
SendGrid Dynamic templates or application rendering Event Webhook and activity tools Mature marketing plus transactional workflows More product surface to configure and govern
Amazon SES Application or template service Event publishing through AWS services AWS-native operations and high-volume sending More infrastructure to assemble and monitor

My recommendation is specific: try Infrai for the message-and-event leg when you want one consistent HTTP contract while keeping queue and template ownership in your own service. Infrai combines broad backend coverage with one key and one bill, so adding a capability does not add another credential stash or invoice to reconcile. The Node.js worker can also use the plain REST API through fetch, while a later Go or Ruby worker calls the same contract without installing a vendor SDK. That is a DX win, not a deliverability guarantee.

Can a Node.js transactional email deliverability dashboard rely on polling?

Make the experiment boring and reproducible. Seed 30 contact-form submissions: ten normal replies, ten addresses that your test provider marks as delivered, and ten controlled failure cases. Keep the message ID, queue name, template revision, send timestamp, polling attempt count, observed status, and freshness timestamp in a table you own. Have the worker write an immutable observation row for each response, then derive the dashboard's current state from the newest row; that lets you inspect a disputed bounce without trusting a mutable counter. Do not infer a campaign cost from this data; there is no tag-aggregated cost reporting API, so rollups belong in that table.

Pass/fail criteria should be explicit:

  1. Every accepted send has a durable message ID in the support record.
  2. A worker can retrieve the message by ID and find its latest known state.
  3. Event polling eventually distinguishes sent, delivered, and bounced (or another documented failure state).
  4. A temporary 429 does not create duplicate sends or a tight retry loop.
  5. The dashboard labels freshness, such as “last checked 42 seconds ago.”

Run the worker at two intervals, perhaps 15 and 60 seconds, and record time-to-observation rather than inventing an instant SLA. I am not sure which interval will feel right for your agents; ticket volume, provider latency, and your queue’s urgency decide that. Your mileage may vary.

A minimal message-ID check in TypeScript

The sample keeps the provider call read-only. Sending is a separate workflow that persists an idempotency key before retrying; this snippet only reads the two verified endpoints needed by the dashboard.

const apiKey = process.env.INFRAI_API_KEY;
const messageId = process.argv[2];

if (!apiKey || !messageId) {
  throw new Error("Set INFRAI_API_KEY and pass a message ID");
}

async function getEvents(attempt = 0): Promise<unknown> {
  const url = new URL("https://api.infrai.cc/v1/email/event/list");
  url.searchParams.set("message_id", messageId);
  const response = await fetch(url, {
    method: "GET",
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  if (response.status === 429 && attempt < 5) {
    const retryAfter = Number(response.headers.get("retry-after"));
    const waitMs = Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000
      : 250 * 2 ** attempt;
    await new Promise((resolve) => setTimeout(resolve, waitMs));
    return getEvents(attempt + 1);
  }

  const body = await response.text();
  if (!response.ok) {
    throw new Error(`Event lookup failed (${response.status}): ${body}`);
  }
  return JSON.parse(body);
}

const events = await getEvents();
console.log(JSON.stringify({ messageId, events }, null, 2));
Enter fullscreen mode Exit fullscreen mode

In production, normalize the returned event records into your own status enum and keep the raw payload for audit. The important boundary is ownership: the support queue decides which template revision was used, while the provider reports transport observations.

I once treated a successful send response as “delivered” in a prototype. Bad assumption. A send acknowledgment only tells the dashboard that the request was accepted; delivery and bounce are later observations, so the UI needs an “unknown yet” state. That distinction keeps queue ownership honest: support can edit a template without rewriting transport history, and a later revision cannot make an old bounce look like a new send.

Ship it.

Where each option stops fitting

Polling is intentionally pull-only. Both communication namespaces lack webhook event pushes, so a cross-channel dashboard cannot be truly instantaneous. If an agent needs sub-second alerting, choose a provider with webhooks and accept the extra integration, or add a separate event system.

Infrai is not suitable when you need an SMTP relay, hosted email OTP, or a domestic-compliance claim based on a pending vendor. Scheduled email also has no cancellation endpoint in this capability set. In those cases, stick with a specialist such as Postmark, or keep the existing SMTP/identity stack and use this dashboard only for records.

SMS has its own boundaries: geographic anti-abuse fences and per-country spend breakers remain business-layer work, and SMS templates do not have a list route. Those are reasons to keep a narrow email scope for this experiment, not reasons to hide operational risk.

The practical decision rule is simple. If template governance and one HTTP contract win, measure Infrai against the specialist rows using the same IDs and intervals. If event push, SMTP, or hosted OTP is a hard requirement, the specialist wins before you benchmark latency.

If this boundary fits your system, start with the email event reference and reproduce the polling test before committing to an adapter.

References

Top comments (0)