---
title: "Visibility over time"
method: GET
path: "/brands/{brandId}/visibility/series"
tags: ["measurement"]
---

# Visibility over time

`GET /brands/{brandId}/visibility/series`

## Request

- Base URL: `https://shruwd.io/api/v1`
- URL: `https://shruwd.io/api/v1/brands/{brandId}/visibility/series`
- Auth: HTTP bearer

The window metric at every cycle close in the range: one point per
`asOf` day the period rollup wrote, for the brand and each competitor,
on one engine. Read from the period rollup only. Each point's metrics
are `DisplayableMetric`s, so a close below ten responses is a gap in
the line, never a zero. `modelChanges` marks the closes where the
provider's model set differed from the previous close; a comparison
across one is confounded (`metrics.md` §6.3). `from` defaults to
ninety days back and is clamped to the plan's history window.

## Query parameters

- `engine` 'google_aio' | 'google_ai_mode' | 'chatgpt': `google_aio` — Google AI Overviews. `google_ai_mode` — Google AI Mode, tracked since 2026-10-15. `chatgpt` — ChatGPT.
- `window` 7 | 30 | 90
- `from` string, date
- `to` string, date

## Response `200`

Visibility series.

- VisibilitySeries
  - `brand` object, required
    - `brandId` string, required
    - `name` string, required
    - `timezone` string, required
  - `engine` 'google_aio' | 'google_ai_mode' | 'chatgpt', required: `google_aio` — Google AI Overviews. `google_ai_mode` — Google AI Mode, tracked since 2026-10-15. `chatgpt` — ChatGPT.
  - `windowDays` 7 | 30 | 90, required
  - `range` object, required
    - `from` string, date, required
    - `to` string, date, required
  - `historyFrom` string, date, nullable, required: Set when `from` was moved forward to the plan's history window.
  - `points` string[], required: Cycle-close days in the range, ascending. Every entity's `series` is index-aligned with this.
  - `entities` object[], required: The brand first, then competitors by how often they were named over the range.
    - `entityId` string, required
    - `canonicalName` string, required
    - `isSelf` boolean, required
    - `series` SeriesPoint[], required: One entry per `points` day; null when the rollup has no row for the entity on that close.
      - `asOf` string, date, required: The cycle-close day this window ends on.
      - `n` integer, required: Responses in the window measured while the entity was tracked: the mention rate's n.
      - `mentionRate` union, required: A metric that can be shown. Never a bare number: either a point estimate with its 95% interval and `n`, or an explicit reason there is no number. `insufficient_data` is **not** zero.
        - object
          - `state` 'ok', required
          - `point` number, required: Proportion in [0, 1].
          - `lo` number, required: Lower bound of the 95% interval.
          - `hi` number, required: Upper bound of the 95% interval.
          - `n` integer, required: Responses the estimate rests on.
        - object
          - `state` 'insufficient_data', required
          - `n` integer, required
          - `needed` integer, required: How many more responses would cross the floor of ten.
        - object
          - `state` 'undefined', required
          - `n` integer, required
          - `reason` string, required
      - `shareOfVoice` union, required: A metric that can be shown. Never a bare number: either a point estimate with its 95% interval and `n`, or an explicit reason there is no number. `insufficient_data` is **not** zero.
        - object
          - `state` 'ok', required
          - `point` number, required: Proportion in [0, 1].
          - `lo` number, required: Lower bound of the 95% interval.
          - `hi` number, required: Upper bound of the 95% interval.
          - `n` integer, required: Responses the estimate rests on.
        - object
          - `state` 'insufficient_data', required
          - `n` integer, required
          - `needed` integer, required: How many more responses would cross the floor of ten.
        - object
          - `state` 'undefined', required
          - `n` integer, required
          - `reason` string, required
      - `avgProminence` number, nullable, required
      - `modelIds` string[], required
  - `modelChanges` object[], required: Closes where the provider's model set differed from the previous close. A comparison across one is confounded.
    - `asOf` string, date, required
    - `from` string[], required
    - `to` string[], required

## Other responses

- `404`: `not_found`: no such resource in this workspace.
- `default`: Every failure has this body.

---

[API](https://skmtc.dev/shruwd/apis/shruwd-api.md) · [All operations](https://skmtc.dev/shruwd/apis/shruwd-api/llms.txt) · [OpenAPI document](https://skmtc.dev/shruwd/apis/shruwd-api/revisions/64a5da079928?raw)
