Blog

Your notification analytics are now available by API

Thomas SchiavoneThomas SchiavoneSeptember 02, 2026
Template Metrics API cover

The Template Metrics API is live. GET /notifications/{id}/metrics returns the delivery funnel for a notification template as a time series: sends, deliveries, opens, clicks, errors, and undeliverable counts, bucketed by hour, day, week, or month, with every bucket broken out by provider and channel.

This is the part of Courier that doesn't change: if it's in the dashboard, it's on the API. Journeys, templates, brands, routing rules, preference topics, audiences, tenants, provider configuration. The dashboard is a client of the same public API you get, not a privileged surface sitting above it. Analytics was one of the last screens where the answer lived only on the screen.

That parity is the point. It means the numbers aren't stuck in our UI: they can go in your product, next to the rest of your customer's data, or straight to an agent that needs to know how last week's sends went. An agent can call an API. It can't read a chart.

What the Template Metrics API gives you

One request per template, with the shape you'd want to chart already built in.

Sends, deliveries, opens, clicks, and errors in one response

Every bucket carries one row per provider and channel pair that handled messages in that period. A template that sends email through SendGrid and SMS through Twilio returns both rows, with counts for sent, delivered, opened, clicked, errors, and undeliverable. You can see that email is carrying the volume while a single provider quietly racks up errors, without a second call.

The window you want, two ways

Ask for a relative window with lookback as an ISO 8601 duration (P30D, P12W, PT12H), or an exact one with start and end timestamps. The default is the last 30 days.

Buckets that chart cleanly

Set granularity to HOUR, DAY, WEEK, or MONTH. Courier expands your window outward to whole buckets, so a 36-hour request at DAY granularity returns two complete days instead of one and a half, and the response echoes the adjusted start and end for your axis labels. Quiet periods come back too, as buckets with an empty data array, so there are no gaps to fill on your side before the data hits a chart.

Available in every server SDK

The endpoint is in all seven server SDKs: Node, Python, Ruby, Go, Java, PHP, and C#. Same call, same parameters, typed the way the rest of your kit is:

// npm install @trycourier/courier
import Courier from "@trycourier/courier";
const client = new Courier();
const metrics = await client.notifications.getMetrics(templateId, {
lookback: "P7D",
granularity: "DAY",
});
console.log(metrics.start, metrics.end, metrics.series.length);

Or by curl, addressing the template by ID or alias:

curl "https://api.courier.com/notifications/$TEMPLATE_ID/metrics?lookback=P7D&granularity=DAY" \
-H "Authorization: Bearer $COURIER_API_KEY"

What you can build

  • A weekly deliverability report. List your templates with GET /notifications, pull seven days at DAY granularity for each, and post the top senders and their delivery rates to Slack every Monday. Nobody has to remember to run it.
  • An alert on delivery rate, not error count. A provider that accepts every request and delivers nothing produces zero errors. Pull twelve hours at HOUR granularity for your critical templates, compare delivered against sent, and page when the ratio drops with real volume behind it.
  • Per-customer numbers in your own product. If you send on behalf of your customers, the channel and provider breakdown is usually the split a customer-facing dashboard needs. Cache it hourly; the counts move at bucket boundaries, not continuously.
  • A feed into your BI stack. Monthly buckets going back through last year land in a warehouse table without much translation, next to the rest of your product metrics.
  • An agent that answers questions about your sends. Hand an agent your API key and this endpoint and "which template regressed last week?" becomes something it can work out on its own: list the templates, pull seven days for each, compare delivery rates, report back.

Each of these used to mean screenshotting a dashboard or building your own event pipeline. Now it's one endpoint and a loop.

Limits worth knowing

Finer buckets cap the window you can request, because the response would otherwise get enormous:

GranularityMaximum window
HOUR7 days
DAY90 days
WEEKUncapped
MONTHUncapped

How far back you can look, and how fast you can ask, depend on your plan:

PlanMax lookbackRequests per second
Developer (free)30 days1
Business90 days2
Enterprise730 days5

A window past your plan's cap returns a 402 rather than a silently shortened result, so you find out in development instead of shipping a chart that shows less than it claims. Rate limits are per workspace, and every response carries RateLimit-* headers so you can pace a loop over many templates.

Three more things to design around. All windows and buckets are UTC, so a daily bucket is a UTC calendar day. The endpoint covers one template per call, so a workspace-wide view means listing templates and iterating. And it's available in the US region today.

Available now

The Template Metrics API is live on every plan, including the free Developer plan. Nothing to turn on: point it at a template you already send and the numbers come back.

The Analytics tab isn't going anywhere, and this doesn't replace it. Same data, different client: a chart when you're the one looking, JSON when your code or your agent is.


Get started: the Template Metrics API guide for window selection, granularity rules, error responses, and per-language examples, or the API reference for the full schema.