get_notification_metrics
Delivery funnel for ONE notification template over time: sent, delivered, opened, clicked, errors and undeliverable, per provider and channel, in time buckets.
Choosing the window — supply EITHER lookback OR start and end together, NEVER both.
Supplying both is rejected. For a relative window like 'the last week', lookback alone is
the whole answer: do not also pin start and end. Default is the last 30 days by day.
Fine granularities cover shorter windows: HOUR spans at most 7 days and DAY at most 90. How
far back a workspace may look also depends on its plan; a request reaching further back is
refused with a payment error, which means the plan does not cover that window, NOT that there
is no data. A coarser granularity can reach further back than a fine one.
Reading the numbers correctly:
The first four counters are NESTED, not separate groups. Every delivered message is also counted in sent, every opened one in delivered, every clicked one in opened. So sent >= delivered >= opened >= clicked always. Report rates (delivered/sent) or the counters themselves. Do NOT add them together — the total is meaningless. And sent minus delivered is NOT a failure count; it is only 'did not reach the delivered stage', for any reason.
errors and undeliverable are counted separately and OVERLAP the funnel: a message that failed on one provider and succeeded on a retry appears in both errors and sent. They are not a remainder and do not complete a total.
Every counter is a count of distinct MESSAGES, not of events. A message that errored three times counts once in errors.
A bucket's
dataarray holds one entry per provider and channel. To get a bucket total, add up the entries in that array — that is the only sum that means anything here. Note that rows for Courier's own built-in email sender are excluded, so these entries can add up to less than the workspace's true volume.
What the buckets mean:
A message is counted in the bucket it was ENQUEUED in, not when the event happened. An open today of a message sent last Tuesday is counted in last Tuesday's bucket. So a past bucket can still change: yesterday's
openedmay be higher when you ask again tomorrow.Results are cached for up to an hour and the pipeline adds its own lag, so a message sent minutes ago is expected NOT to appear yet. Never tell a user a just-sent message is missing; say the data has not caught up.
Read the window off the response's
startandend, not off what you asked for. The API widens the window to whole buckets and returns the boundaries it actually used.Quiet buckets are returned with an empty
dataarray, so the series has no gaps.An unknown template id returns an all-empty series rather than an error, and messages sent without a template never appear here at all. An empty result is not proof a template is unused — check that the id is right before concluding anything from it.
Because of that, a NOT FOUND / 404 error is never about the template id. It means the metrics endpoint itself could not be reached, which is an infrastructure or configuration problem on Courier's side. Say that the metrics service is unreachable and that someone should be told; do NOT tell the user to check or correct their template id, which sends them to fix something that was never wrong.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Window end, ISO 8601 with offset. Requires start. Must not be combined with lookback. | |
| start | No | Inclusive window start, ISO 8601 with offset (2026-04-01T00:00:00Z). Requires end. Must not be combined with lookback. | |
| lookback | No | Window length counted back from now, as an ISO 8601 duration (P30D, P12W, PT12H). Defaults to P30D. Must not be combined with start/end. | |
| granularity | No | Bucket size. HOUR covers at most 7 days, DAY at most 90. Defaults to DAY. | DAY |
| notification_id | Yes | The notification template ID to report on (no commas or whitespace) |