---
title: "One metric over time, with zeros for empty buckets"
method: GET
path: "/v1/stats/timeseries"
tags: ["Stats"]
---

# One metric over time, with zeros for empty buckets

`GET /v1/stats/timeseries`

## Request

- Base URL: `https://api.tessio.eu`
- URL: `https://api.tessio.eu/v1/stats/timeseries`
- Auth: HTTP bearer

One point per bucket from `from` to `to`, a bucket with no checks included as zero, so a chart never has to fill gaps. The granularity follows the range as on the Stats page, except that a range of two days or less is cut into hours, labelled `YYYY-MM-DDTHH:00Z` and ending at the current hour. Weeks and months are UTC calendar steps. `pass_rate` is null for a bucket where nothing ended. Under a project's key, over its project; under an organisation's key, over every project in it, or one with `project_id`. UTC days. Any key may call it, of either scope; each key spends its own budget.

## Query parameters

- `from` string, date
- `to` string, date
- `mode` 'all' | 'live' | 'test'
- `metric` 'checks' | 'expired' | 'failed' | 'pass_rate' | 'passed' | 'under_age'
- `project_id` string, uuid

## Response `200`

OK

- AgeCheckStatsSeries
  - `mode` 'all' | 'live' | 'test'
  - `metric` 'checks' | 'expired' | 'failed' | 'pass_rate' | 'passed' | 'under_age'
  - `granularity` 'day' | 'hour' | 'month' | 'week'
  - `points` StatsPoint[]
    - `bucket` string: YYYY-MM-DD, or YYYY-MM-DDTHH:00Z for hours (UTC)
    - `value` number, nullable
  - `retention` StatsRetention: The first UTC day the purge has left whole, from what it recorded it may have deleted: after an upgrade the longer plan does not bring back days the shorter one already took. It may understate, never overstate: a day it calls whole is. A range that starts earlier counts only what is still held, so read the older days as partial, not as "no checks". Null where no purge has run for the org, so nothing was deleted.
    - `recordsFrom` string, date, nullable: For the checks: every read.
    - `eventsFrom` string, date, nullable: For what is read from each check's timeline: failures, the funnel's step for a fetched request under `eudiw`, held presentations (part of the funnel's `responseReceived`) and `noAnswer`, which leaves out a check whose presentation was held.

## Other responses

- `400`: The range is refused as for every chart (invalid_from, invalid_to, range_inverted, range_too_old, range_too_long), or invalid_mode, invalid_metric, invalid_group_by or invalid_project_id. Checked before the plan, so a malformed request is never answered with an upgrade.
- `401`: No key, or one that is unknown or revoked
- `403`: plan_feature_unavailable. The org's plan does not include this read. Every plan reads the summary, Starter adds the time series, Growth and above read all five.
- `429`: rate_limited: this key's budget is spent.

---

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