Live Tail

Watch every send, delivery, bounce, open, click, and complaint stream into your dashboard in real time. Like tail -f for email.

What it does

When an email moves through any state — queued, sending, sent, delivered, opened, clicked, bounced, complained, unsubscribed, delivery delayed, suppressed, retrying, failed — Live Tail pushes the event to your browser within ~500ms over a long-lived Server-Sent Events (SSE) connection. Filters apply server-side, so you only receive what you care about.

The last 60 seconds of events are replayed when you connect, so you never stare at an empty screen on a quiet account.

Availability

PlanLive Tail
FreeNot included
StarterNot included
GrowthIncluded
ScaleIncluded

Up to 5 concurrent live sessions per account. Free and Starter accounts can still use the standard /logs page with page-by-page navigation.

Using it from the dashboard

  1. Open /logs in the dashboard.
  2. Click the Live toggle in the top-right of the page. The pulsing green dot confirms the stream is open.
  3. Apply filters (event type chips, search box) — they are sent server-side, so only matching events stream down.
  4. Toggle Live off to return to paginated history; toggle on to resume streaming.

Connecting from your own client

The endpoint is a standard SSE feed. Any EventSource-compatible client works, including curl.

Endpoint: GET /api/dashboard/logs/stream

Auth: session cookie (the same one the dashboard uses). API-key auth and a dedicated public endpoint are on the roadmap.

Query parameters:

  • eventType — limit to a single type (queued, sending, sent, delivered, opened, clicked, bounced, complained, unsubscribed, delivery_delayed, suppressed, received, retrying, failed)
  • search — substring match against recipient, sender, or subject

From the browser:

javascript
const es = new EventSource("/api/dashboard/logs/stream?eventType=bounced");

es.addEventListener("ready", () => console.log("connected"));
es.addEventListener("replay", (e) => console.log("replay:", JSON.parse(e.data)));
es.onmessage = (e) => console.log("event:", JSON.parse(e.data));
es.onerror = () => console.warn("reconnecting...");

Event payload

Each event arrives as JSON in the SSE data: line:

json
{
  "id": "evt_01HW...",
  "emailId": "em_01HW...",
  "userId": "usr_01HW...",
  "eventType": "bounced",
  "metadata": {
    "bounceType": "Permanent",
    "bounceSubType": "General",
    "diagnosticCode": "smtp; 550 5.1.1 user unknown",
    "reportingMTA": "dsn; b.mx.example.com"
  },
  "createdAt": "2026-05-02T20:43:11.221Z",
  "email": {
    "fromAddress": "[email protected]",
    "toAddresses": ["[email protected]"],
    "subject": "Order shipped",
    "status": "bounced"
  }
}

Event names emitted on the SSE stream

  • ready — fired once on connect.
  • replay — replay of the last 60s of events on connect.
  • message — every live event after connect (default SSE event type).

Limits and behaviour

  • Up to 5 concurrent live sessions per account. A 6th connection returns 429.
  • Heartbeat every 25 seconds keeps the connection alive through proxies. Standard SSE comment line.
  • Auto-reconnect is built into the browser EventSource API. The dashboard surfaces a "Reconnecting…" state on transient errors.
  • Free and Starter accounts hitting this endpoint receive 403 Forbidden.