---
title: "Brand overview (totals, rates, timeseries)"
method: GET
path: "/v1/analytics/overview"
tags: ["Analytics"]
---

# Brand overview (totals, rates, timeseries)

`GET /v1/analytics/overview`

Windowed brand overview — the EXACT read behind the app's /analytics metric cards + chart (same unique-recipient and machine-click rules), so API/MCP numbers can never disagree with the page. Defaults to the last 7 days. Optional filters, all of which COMPOSE freely: `source` (csv of send sources), `automationId`, `emailId`, `audienceId` (csv, ≤20), `triggerEventId` (csv, ≤10 — integration trigger-events, resolved to their wired automations), and `domain` (sending domain). A single filter is answered from pre-aggregated rollup rows; any combination (and anything with `domain`, which has no rollup dimension) is answered by aggregating raw events instead — exact, but capped, so watch `truncated` on wide windows. Returns `{ totals, rates, buckets, granularity, timeZone, range, truncated }` — `truncated: true` means the window exceeded the scan budget; narrow the range. Requires the `emails` scope.

## Query parameters

- `from` string, date-time
- `to` string, date-time
- `source` string
- `automationId` string
- `emailId` string
- `audienceId` string
- `triggerEventId` string
- `domain` string

## Response `200`

Brand-wide totals, rates, and a zero-filled timeseries for the window.

- AnalyticsOverviewResponse
  - `totals` object, required
    - `accepted` integer
    - `sent` integer, required
    - `delivered` integer, required
    - `opened` integer, required
    - `openedTotal` integer, required
    - `clicked` integer, required
    - `clickedTotal` integer, required
    - `bounced` integer, required
    - `complained` integer, required
    - `unsubscribed` integer, required
    - `failed` integer, required
    - `providerSuppressed` integer
    - `suppressed` integer, required
    - `quotaSkipped` integer
    - `preSendSkipped` integer
    - `pending` integer
    - `deliveryDelayed` integer, required
  - `rates` object, required
    - `deliveryRate` number, required
    - `openRate` number, required
    - `clickRate` number, required
    - `bounceRate` number, required
    - `complaintRate` number, required
    - `unsubscribeRate` number, required
  - `buckets` object[], required
    - `at` string, date-time, required
    - `sent` integer, required
    - `delivered` integer, required
    - `deliveryDelayed` integer, required
    - `opened` integer, required
    - `clicked` integer, required
    - `bounced` integer, required
    - `complained` integer, required
    - `failed` integer, required
    - `providerSuppressed` integer
    - `suppressed` integer, required
    - `quotaSkipped` integer
    - `unsubscribed` integer, required
  - `granularity` '5m' | '1h' | '1d', required
  - `timeZone` string, required
  - `range` object, required
    - `from` string, date-time, required
    - `to` string, date-time, required
  - `truncated` boolean, required

## Other responses

- `400` — The request body or query string was invalid (unknown key, wrong type, or missing required field). Strict schemas reject unknown keys — including `brandId`, which is always resolved from the API key.
- `401` — The API key was missing, invalid, or revoked.
- `403` — The caller does not have the required `emails` permission.
- `429` — The request hit the rolling rate limit window.
- `500` — Unexpected internal error.

---

[API](https://skmtc.net/brew/apis/brew-public-api-v1.md) · [All operations](https://skmtc.net/brew/apis/brew-public-api-v1/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/brew/brew-public-api-v1/revisions/db96cfedc6c5/schema)
