Docs
guides · metrics

Metrics

One endpoint gives you the numbers that matter for a sending project: totals over a window, a per-day series to chart, and the raw counts you need to compute delivery, bounce, and complaint rates.

The metrics endpoint aggregates the same events that drive webhooks — delivery, bounce, complaint, open, click — into totals and a daily breakdown for a project. It returns counts; you compute rates from them, so you stay in control of exactly how each rate is defined.

01 Get metrics

GET/v1/metrics

Optional from and to ISO-8601 timestamps bound the window; omit them for a sensible recent default. The response echoes the resolved range so you always know which window the numbers describe.

# Last 7 days (default range)
curl https://api.drin.run/v1/metrics \
  -H "Authorization: Bearer $DRIN_API_KEY"

# An explicit window
curl "https://api.drin.run/v1/metrics?from=2026-05-01T00:00:00Z&to=2026-05-31T23:59:59Z" \
  -H "Authorization: Bearer $DRIN_API_KEY"

02 The response

Three fields: the resolved range, a totals map keyed by event type, and a daily array of { date, counts } — one bucket per day, each with its own counts map.

Response
{
  "range": { "from": "2026-05-26T00:00:00Z", "to": "2026-06-02T00:00:00Z" },
  "totals": {
    "sent": 12480,
    "delivery": 12190,
    "bounce": 142,
    "complaint": 9,
    "open": 8204,
    "click": 1903
  },
  "daily": [
    { "date": "2026-05-26", "counts": { "sent": 1780, "delivery": 1740, "bounce": 22, "complaint": 1 } },
    { "date": "2026-05-27", "counts": { "sent": 1810, "delivery": 1772, "bounce": 18, "complaint": 2 } }
  ]
}
Counts are keyed by event typeKeys in totals and each day's counts are event types — sent, delivery, bounce, complaint, open, click, and the rest. A type with no events in the window is simply absent, so read defensively (treat a missing key as 0).

03 Computing rates

Rates are ratios over sent. Compute them yourself from totals so the denominator is unambiguous:

TypeScript
const t = metrics.totals;
const sent = t.sent ?? 0;

const deliveryRate  = sent ? (t.delivery  ?? 0) / sent : 0;  // want: high
const bounceRate    = sent ? (t.bounce    ?? 0) / sent : 0;  // want: < 4%
const complaintRate = sent ? (t.complaint ?? 0) / sent : 0;  // want: < 0.1%
const openRate      = sent ? (t.open      ?? 0) / sent : 0;
const clickRate     = sent ? (t.click     ?? 0) / sent : 0;

console.log((bounceRate * 100).toFixed(2) + "% bounce");
  • Delivery ratedelivery / sent. The share that reached the mailbox provider. Higher is better.
  • Bounce ratebounce / sent. The single most important number to watch. Keep it well under 4%.
  • Complaint ratecomplaint / sent. Spam-button presses. Keep it under 0.1%.
  • Open / click rate — engagement signals. Useful trends, but treat the absolutes with care (privacy proxies inflate opens; not every client loads tracking).

04 Charting over time

The daily series is built for time-series charts. Map each bucket the same way you mapped the totals to get a rate-over-time line:

TypeScript
// Plot a bounce-rate-over-time line from the daily series.
const points = metrics.daily.map((d) => {
  const sent = d.counts.sent ?? 0;
  return { date: d.date, bounceRate: sent ? (d.counts.bounce ?? 0) / sent : 0 };
});
Watch the trend, not a single dayA one-day spike on low volume is noise; a rising multi-day trend is a signal. Plot the bounce and complaint lines against your thresholds and act on sustained movement.

05 Reading the numbers

The lines that matterDrin watches the same limits AWS does. Sustained bounce above 4% or complaints above 0.1% put your sending — and eventually the whole platform's — reputation at risk, and can trigger an automatic pause. If a rate is climbing, slow down, verify your list, and check the Deliverability guide before it trips.

High bounce usually means a stale or unverified recipient list — clean it and lean on suppressions. High complaints usually mean unwanted mail — tighten consent and make unsubscribing easy. The metrics endpoint is your early-warning system; check it before a provider does it for you.

06 Related