Reference
Delivery analytics
One delivery rate across all your mail averages Gmail’s 99.8% together with a corporate Exchange server’s 71% and describes neither. This breaks the same window down by receiving provider — and by your own tags — with the time each of them took.
What “time to inbox” measures
Two events on the message, both of them rows in the same append-only log your waybill is verified against:
| Event | When it is written |
|---|---|
accepted | The moment the message entered the send queue. For a scheduled message this is at release, not when you booked it — so a send booked for next Tuesday is not reported as having taken six days. |
delivered | The moment the receiving mail server answered our DATA with a 2xx and took responsibility for the message. |
This is time to the receiving server, not to the inbox proper. What a provider does after accepting a message — greylisting a retry, filing it in Spam, holding it in a scanner — is invisible to every sender on the internet, including us. Anybody quoting you a true time-to-inbox is quoting you a guess. The endpoint returns the two event names in measuredBetween so the definition travels with the numbers.
Nothing is invented where there is nothing to measure
This is the part worth reading twice, because the alternative is an endpoint that lies quietly:
| Field | When there is no answer | Why not zero |
|---|---|---|
deliveryRate | null when settled is 0 | A rate of 0 reads as “none of your mail to this provider arrived”. If nothing has settled, nothing has failed either. |
p50Seconds, p95Seconds | null when samples is 0 | A p95 of 0 would report instantaneous delivery for a provider that has never accepted one of your messages. |
p50Seconds, p95Seconds | The value itself when samples is 1 | One observation is thin evidence, not absent evidence. Every row carries samples so you can decide how much weight it takes. |
settled counts only the messages a receiving server actually answered: delivered, bounced, complained, failed or rejected. Mail still queued is in pending, and scheduled or cancelled mail is in unsent. Neither is in the denominator — cancelling a thousand messages should not read as a provider rejecting them.
Endpoint
/v1/analytics/deliveryanalytics:readanalytics:read is a separate scope from messages:read on purpose. This returns aggregates and nothing else — no recipient address, no subject, no body — so a status board or a support tool can be given the delivery picture without being given everybody’s mail.
| Parameter | Default | What it does |
|---|---|---|
days | 7 | The window, counted back from now. Your plan sets how far it may reach; the platform never allows more than 90. |
groupBy | domain | domain for one row per receiving provider, tag for one row per tag. |
tag | — | Only messages carrying this tag. Combines with either grouping. |
stream | — | Only messages on this stream, by slug. An unknown slug is refused rather than ignored. |
limit, cursor | 20 | Keyset paging, busiest group first. See Pagination. |
How far back days may reach is an entitlement: Free 7 days, Starter 30 days, Growth 90 days, Scale 90 days, Enterprise 90 days. Asking for more returns 403 with "type": "analytics_window_exceeded" rather than a quietly shortened answer — a figure labelled with a window it does not cover is worse than a refusal. The full grid is in limits.
Underneath that, the window is bounded by your plan’s retention period — delivery records are purged on that clock, so a permitted window is still answered from whatever survives it. retentionBounded says so in every response.
Examples
curl "https://api.posthastemail.dev/v1/analytics/delivery?days=30" \
-H "authorization: Bearer $POSTHASTE_KEY"NextSuppressions →Why an address stops receiving mail, and which entries can never be removed.