---
title: "A site's Search Console figures over time"
method: GET
path: "/v1/sites/{site}/search/series"
tags: ["gsc"]
---

# A site's Search Console figures over time

`GET /v1/sites/{site}/search/series`

## Request

- Base URL: `https://frontshelf.io/api`
- URL: `https://frontshelf.io/api/v1/sites/{site}/search/series`
- Auth: HTTP bearer

A site's Search Console clicks, impressions, CTR and average position over time, from the data Frontshelf stores: one point per day, week or month over `range`, the comparison's figures beside each point when `compare` asks for one, the totals, and `coverage` (the dates, whether the figures are exact totals or Google's observed top rows, the missing days and why, the provisional and capped days, the snapshot). A missing day is null, never 0: quote the warnings with the figures. `second` draws a second filter as its own line (paid: compare_filters). A paid feature on a site that is not paid for is BILLING_REQUIRED naming it: hand your human its checkout_url. Next: gsc_table_get for the rows behind a movement.

## Path parameters

- `site` string, required: Site ID (site_…), origin (https://example.com), or bare domain, resolved server-side; the response carries the canonical ID.

## Query parameters

- `source_id` string: One of the site's Search Console properties (ssrc_…, from gsc_sources_list). Omit for the site's primary property.
- `type` 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews': The Google search surface: web (default), image, video, news, discover or googleNews. Discover and Google News have no query dimension and no position.
- `range` union: The dates, as Pacific calendar days: a word (yesterday, 7d, 14d, 28d, 3m, 6m, 12m, 16m, this_month, last_month, this_quarter, last_quarter, ytd, all; last:<days>; <start>..<end>) or the object it stands for ({preset}, {last_days: n}, {start, end} as YYYY-MM-DD). Default 28d.
  - string
  - object
    - `preset` 'yesterday' | '7d' | '14d' | '28d' | '3m' | '6m' | '12m' | '16m' | 'this_month' | 'last_month' | 'this_quarter' | 'last_quarter' | 'ytd' | 'all', required
  - object
    - `last_days` integer, required
  - object
    - `start` string, required
    - `end` string, required
- `compare` union: What to compare against: none (default), previous (the same length before), year (a year earlier), year-weekdays (364 days earlier, weekdays matched) or <start>..<end>; or the object: {kind: none | previous}, {kind: year, match_weekdays}, {kind: custom, start, end}.
  - string
  - object
    - `kind` 'none' | 'previous', required
  - object
    - `kind` 'year', required
    - `match_weekdays` boolean, required
  - object
    - `kind` 'custom', required
    - `start` string, required
    - `end` string, required
- `filter` object: Narrow the rows: query and page as lists of {op: contains | equals | regex | not_contains | not_equals | not_regex, values} (values ORed, conditions ANDed, RE2 patterns); country {mode: include | exclude, codes} as lower-case ISO 3166-1 alpha-3; device {mode, devices: desktop | mobile | tablet}; segments [{id, mode}]; brand: branded | non_branded (needs brand terms); presets: question, long_tail; daily_position_max. Default: nothing narrowed.
  - `query` object[]
    - `op` 'contains' | 'equals' | 'regex' | 'not_contains' | 'not_equals' | 'not_regex', required
    - `values` string[], required
  - `page` object[]
    - `op` 'contains' | 'equals' | 'regex' | 'not_contains' | 'not_equals' | 'not_regex', required
    - `values` string[], required
  - `country` object
    - `mode` 'include' | 'exclude', required
    - `codes` string[], required
  - `device` object
    - `mode` 'include' | 'exclude', required
    - `devices` string[], required
  - `segments` object[]
    - `id` string, required
    - `mode` 'include' | 'exclude', required
  - `brand` 'branded' | 'non_branded'
  - `presets` string[]
  - `daily_position_max` number
- `saved_filter_id` string: A saved filter (ssf_…, from gsc_filters_list) applied on top of `filter`; a cursor read under it expires when the filter is edited.
- `interval` 'day' | 'week' | 'month': One point per day (default; ranges up to 21 days), week (Sunday to Saturday; up to 90 days) or month.
- `second` object: A second filter drawn as its own line over the same dates, to compare two filters (paid: compare_filters).
  - `filter` object, required
    - `query` object[]
      - `op` 'contains' | 'equals' | 'regex' | 'not_contains' | 'not_equals' | 'not_regex', required
      - `values` string[], required
    - `page` object[]
      - `op` 'contains' | 'equals' | 'regex' | 'not_contains' | 'not_equals' | 'not_regex', required
      - `values` string[], required
    - `country` object
      - `mode` 'include' | 'exclude', required
      - `codes` string[], required
    - `device` object
      - `mode` 'include' | 'exclude', required
      - `devices` string[], required
    - `segments` object[]
      - `id` string, required
      - `mode` 'include' | 'exclude', required
    - `brand` 'branded' | 'non_branded'
    - `presets` string[]
    - `daily_position_max` number
  - `saved_filter_id` string: A saved filter (ssf_…, from gsc_filters_list) applied on top of `filter`; a cursor read under it expires when the filter is edited.

## Response `200`

A site's Search Console figures over time

- object
  - `summary` string, required: The answer in one or two sentences, with the numbers it rests on.
  - `warnings` string[], required: What limits this answer (a cap, a read that was cut short). Empty when nothing does.
  - `next_actions` object[], required: What to call next, best first. Follow them.
    - `capability` string, required: What to call next: a capability.
    - `arguments` object, required: Its arguments, complete; pass them as they are.
    - `instruction` string, required: What to do, written to you.
  - `provenance` object, required
    - `crawl_seq` integer, nullable, required: The crawl the answer was read from; null when the site has none yet.
    - `data_freshness` string, required: When that crawl finished (ISO 8601) or `no completed crawl`; for a read of one committed crawl, `committed crawl (immutable snapshot)`, or `not committed (<reason>)` when nothing committed answered.
  - `site_id` string, required: The site's canonical id.
  - `source_id` string, required: The property the figures are from (ssrc_…).
  - `points` object[], required
    - `bucket` string, required
    - `bucket_end` string, required
    - `partial` boolean, required
    - `provisional` boolean, required
    - `current` object, nullable, required: Null when no day of the bucket has figures: absent, never 0.
      - `clicks` number, required
      - `impressions` number, required
      - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
      - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
    - `previous` object, nullable, required
      - `clicks` number, required
      - `impressions` number, required
      - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
      - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
  - `totals` object, required
    - `current` object, nullable, required
      - `clicks` number, required
      - `impressions` number, required
      - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
      - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
    - `previous` object, nullable, required
      - `clicks` number, required
      - `impressions` number, required
      - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
      - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
  - `coverage` object, required
    - `current` object, required: What the figures cover: the dates, the basis, the missing and provisional days, the capped days, the snapshot.
      - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
      - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
      - `grain` 'totals' | 'country_device' | 'query' | 'page' | 'query_page', required
      - `cut` 'all' | 'coarse' | 'geo', required
      - `basis` 'exact' | 'observed', required: `exact`: unfiltered totals; `observed`: Google's listed top rows (any query or page filter), a floor.
      - `aggregation` string, required
      - `snapshot_seq` string, required: The publication the read was fixed at.
      - `final_through` string, nullable, required: The last final day; null before the first.
      - `provisional_days` string[], required: Days Google may still restate.
      - `gaps` object[], required: Days with no figures and why: absent, never 0.
        - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `reason` 'before_history' | 'not_fetched' | 'unrecoverable' | 'not_final', required
      - `capped_days` integer, required: Days Google listed only its top rows on: the detail is a floor.
      - `unsupported` boolean, required: True: Google does not answer this combination, so there are no figures; nothing was measured as 0.
    - `previous` object, nullable, required: What the figures cover: the dates, the basis, the missing and provisional days, the capped days, the snapshot.
      - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
      - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
      - `grain` 'totals' | 'country_device' | 'query' | 'page' | 'query_page', required
      - `cut` 'all' | 'coarse' | 'geo', required
      - `basis` 'exact' | 'observed', required: `exact`: unfiltered totals; `observed`: Google's listed top rows (any query or page filter), a floor.
      - `aggregation` string, required
      - `snapshot_seq` string, required: The publication the read was fixed at.
      - `final_through` string, nullable, required: The last final day; null before the first.
      - `provisional_days` string[], required: Days Google may still restate.
      - `gaps` object[], required: Days with no figures and why: absent, never 0.
        - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `reason` 'before_history' | 'not_fetched' | 'unrecoverable' | 'not_final', required
      - `capped_days` integer, required: Days Google listed only its top rows on: the detail is a floor.
      - `unsupported` boolean, required: True: Google does not answer this combination, so there are no figures; nothing was measured as 0.
  - `interval` 'day' | 'week' | 'month', required
  - `second` object, nullable, required: The second filter's line; null without `second`.
    - `points` object[], required
      - `bucket` string, required
      - `bucket_end` string, required
      - `partial` boolean, required
      - `provisional` boolean, required
      - `current` object, nullable, required: Null when no day of the bucket has figures: absent, never 0.
        - `clicks` number, required
        - `impressions` number, required
        - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
        - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
      - `previous` object, nullable, required
        - `clicks` number, required
        - `impressions` number, required
        - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
        - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
    - `totals` object, required
      - `current` object, nullable, required
        - `clicks` number, required
        - `impressions` number, required
        - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
        - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
      - `previous` object, nullable, required
        - `clicks` number, required
        - `impressions` number, required
        - `ctr` number, nullable, required: Clicks over impressions; null with no impressions.
        - `position` number, nullable, required: The average position; null where Google gives none (Discover, Google News).
    - `coverage` object, required
      - `current` object, required: What the figures cover: the dates, the basis, the missing and provisional days, the capped days, the snapshot.
        - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `grain` 'totals' | 'country_device' | 'query' | 'page' | 'query_page', required
        - `cut` 'all' | 'coarse' | 'geo', required
        - `basis` 'exact' | 'observed', required: `exact`: unfiltered totals; `observed`: Google's listed top rows (any query or page filter), a floor.
        - `aggregation` string, required
        - `snapshot_seq` string, required: The publication the read was fixed at.
        - `final_through` string, nullable, required: The last final day; null before the first.
        - `provisional_days` string[], required: Days Google may still restate.
        - `gaps` object[], required: Days with no figures and why: absent, never 0.
          - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
          - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
          - `reason` 'before_history' | 'not_fetched' | 'unrecoverable' | 'not_final', required
        - `capped_days` integer, required: Days Google listed only its top rows on: the detail is a floor.
        - `unsupported` boolean, required: True: Google does not answer this combination, so there are no figures; nothing was measured as 0.
      - `previous` object, nullable, required: What the figures cover: the dates, the basis, the missing and provisional days, the capped days, the snapshot.
        - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
        - `grain` 'totals' | 'country_device' | 'query' | 'page' | 'query_page', required
        - `cut` 'all' | 'coarse' | 'geo', required
        - `basis` 'exact' | 'observed', required: `exact`: unfiltered totals; `observed`: Google's listed top rows (any query or page filter), a floor.
        - `aggregation` string, required
        - `snapshot_seq` string, required: The publication the read was fixed at.
        - `final_through` string, nullable, required: The last final day; null before the first.
        - `provisional_days` string[], required: Days Google may still restate.
        - `gaps` object[], required: Days with no figures and why: absent, never 0.
          - `start` string, required: A Pacific calendar day, YYYY-MM-DD.
          - `end` string, required: A Pacific calendar day, YYYY-MM-DD.
          - `reason` 'before_history' | 'not_fetched' | 'unrecoverable' | 'not_final', required
        - `capped_days` integer, required: Days Google listed only its top rows on: the detail is a floor.
        - `unsupported` boolean, required: True: Google does not answer this combination, so there are no figures; nothing was measured as 0.

## Other responses

- `400`: SEARCH_SPEC_INVALID, VALIDATION_FAILED
- `401`: UNAUTHENTICATED
- `402`: BILLING_REQUIRED
- `403`: SCOPE_DENIED
- `404`: SITE_NOT_FOUND, NOT_FOUND
- `409`: AMBIGUOUS_SITE, SEARCH_NOT_CONNECTED, AGENT_STOPPED
- `503`: DEPENDENCY_UNAVAILABLE

---

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