# Email stats API

Every number on the [Metrics dashboard](/docs/guides/email/tracking-and-metrics) comes from the email stats API, and you can pull the same aggregates yourself: to build your own dashboard, feed a data warehouse, or wire a health check into your alerting. The endpoints are read-only, workspace-scoped, and need an API key with read access to the `emails` scope. They read the same rollups the dashboard does, so a value you fetch matches what the dashboard shows for the same range.

Typed methods ship in the [TypeScript](/docs/sdks/typescript), [Python](/docs/sdks/python), and [Go](/docs/sdks/go) SDKs under `email.stats`, and the same reads are available from the `bird` [CLI](/docs/cli) (`bird email stats …`) and the [MCP server](/docs/ai/mcp-server). Full request and response schemas are in the [API reference](/docs/api/reference/get-email-stats-summary).

## The aggregate and the time series

Three endpoints cover the top of the dashboard:

- **`GET /v1/email/stats/summary`**: the single-row aggregate behind the health cards, holding the lifecycle counts (accepted, delivered, bounced, complained, opened, clicked, and their sub-types), the derived `delivery_rate`, `bounce_rate`, `complaint_rate`, `open_rate`, and `click_rate`, and the processing, delivery, and total latency percentiles (p50/p95/p99) for the range. Pass `compare=previous_period` to also get the preceding equal-length window and the change between them, the "+X% vs last period" the cards show.
- **`GET /v1/email/stats/daily`** and **`GET /v1/email/stats/hourly`**: one row of the same counts per day or per hour, for charting over time.

Rates attribute by **event time, not send time**, so engagement that arrives during the range for a message sent earlier is included. A rate is `null` when its denominator is zero: `open_rate` is `null` for a period that delivered nothing, rather than reading `0`. The exact formula behind each rate, including how late out-of-band bounces adjust the delivered denominator, is documented per field on the [summary reference](/docs/api/reference/get-email-stats-summary).

## Choosing the window

`from` and `to` accept either a calendar day (`YYYY-MM-DD`) or an RFC 3339 instant. With days the window covers whole calendar days (up to 365); with instants it is hour-grain (up to 720 hours, 30 days), so a rolling "last 24 hours" is a single request. Both bounds must use the same form; mixing them returns a `422`. Set `timezone` to an IANA identifier (for example `America/New_York`) to have day and hour boundaries, and the defaults used when `from`/`to` are omitted, computed in that zone instead of UTC; sub-hour offsets like `Asia/Kolkata` (+05:30) are handled correctly.

## Breakdowns

Thirteen breakdown endpoints slice the same delivery and engagement numbers by a single dimension, ranking rows by a `sort` metric (default `processed`) descending and capping the result at `limit` (default 50, maximum 200) with a `total` for "top N of M":

- **Senders**: `/sending-domains`, `/sending-ips`, and `/recipient-domains` (the mailbox domain you sent to).
- **Where it landed**: `/mailbox-providers` (Gmail, Outlook, …) and `/mailbox-provider-regions`.
- **What you sent**: `/tags` (the [tags](/docs/guides/email/sending-email) you set at send time, the most flexible cut), `/categories`, `/templates`, and `/broadcasts`.
- **Engagement context**: `/locations` (recipient geography) and `/clients` (the mail client that rendered the open).
- **Failures**: `/bounce-codes` (grouped by the receiving server's response) and `/complaint-types`.

All breakdowns live under `/v1/email/stats/`. Pass `include_trend=true` to add a per-bucket rate series to each row, ready for sparklines. The summary and time-series endpoints also take a single dimension **filter** per request (`category`, `sending_domain`, `sending_ip`, `recipient_domain`, `tag`, or `template`) so you can scope an aggregate to one sender or campaign without switching to a breakdown.

## Test traffic in the numbers

Sends to [sandbox addresses](/docs/guides/email/testing-sandbox) flow through the same rollups, so test runs show up in every endpoint here exactly as they do on the dashboard.

## Next steps

- [Email metrics](/docs/guides/email/tracking-and-metrics): how the dashboard presents these numbers and when to act on them.
- [Stats summary reference](/docs/api/reference/get-email-stats-summary): every field, filter, and rate formula.
- [Events and webhooks](/docs/guides/email/events): the per-recipient stream when an aggregate isn't enough.