GET /notifications/{id}/metrics returns the delivery funnel for one notification template as a time series: sent, delivered, opened, clicked, errors, and undeliverable, broken out per provider and channel inside every bucket. Use it to build your own dashboards, alert when a delivery rate drops, pull the numbers into a warehouse or BI tool, or let an agent answer “how is this template doing?” without opening the Courier app.
Endpoint
GET https://api.courier.com/notifications/{id}/metrics
Authenticate with your workspace API key as a Bearer token: Authorization: Bearer <token>. id is the template ID (nt_ prefix) or its alias. Full parameter and response details are on the reference page.
Pick a window
Two ways to set the window:lookback: an ISO 8601 duration counted back from now, likeP30D,P12W, orPT12H. If you send no window at all, Courier usesP30D.startandend: ISO 8601 timestamps with an offset, like2026-08-01T00:00:00Z. Supply both or neither. Either one alone returns400, as does astartthat is not earlier thanend. Anendin the future is accepted and not clamped, so the trailing buckets come back empty.
start and end win and lookback is ignored.
All boundaries are UTC. There is no timezone support, so a “day” is a UTC day.
Courier widens the window to whole buckets, so every bucket the window touches comes back complete. A request for the last 36 hours at DAY granularity returns two full days, not a day and a half. The response echoes the snapped start and end. Label charts with those, not with the values you requested.
Pick a granularity
granularity sets the bucket size: HOUR, DAY (the default), WEEK, or MONTH. WEEK buckets start on Sunday.
A finer granularity caps the window it can cover:
A wider window returns
400. Use a coarser granularity instead of splitting the range across calls. WEEK and MONTH have no window cap, but every response is limited to 1000 buckets, and a request that would exceed that also returns 400.
Read the response
series holds one entry per bucket between the snapped start and end, oldest first. Each entry has a period, the start of the bucket in UTC, and a data array with one row per provider and channel that handled a message in that bucket.
Quiet buckets are still returned, with data: [], so a series is plottable as-is with no gap filling on your side.
There is no bucket-level total. Sum the rows in a bucket to get one, and compute rates from the sums:
sent of zero.
delivered depends on the provider reporting delivery back to Courier, and opened is always 0 on channels with no open tracking. See Analytics to set up delivery tracking for your providers.Fetch the last 7 days
Plan limits and rate limits
Rate limits are per workspace, and every response carries
RateLimit-* headers so you can pace a backfill.
Errors
Good to know
- An unknown template ID returns
200with an all-empty series, not404. Confirm the ID before you conclude a template sent nothing. - Messages sent without a template never appear here.
- This endpoint is per-template only. To cover the whole workspace, list your templates with
GET /notificationsand call metrics for each one. - Available in the US region only.
Related
- Analytics: view these metrics in the Courier app.
- Create and edit templates via API: the rest of the
/notificationsAPI. - Message Logs: per-message delivery detail instead of aggregates.