# Get uptime analytics

`GET https://evohub.io/api/v1/uptime/analytics`

Part of the [Uptime API](https://docs-dev.evohub.io/uptime.md) reference · operationId `getUptimeAnalytics`.

Uptime, latency, downtime, outages and SLA results over a date range
for every monitor the caller can see: organization totals, a time
series, a row per monitor, the five monitors furthest below their
SLA target, and a row per team.

- With neither `from` nor `to`, the range is the last 30 UTC days,
  today included.
- A date (`YYYY-MM-DD`) is a whole UTC day, and `to` is the last day
  included. An RFC 3339 time is an exact instant, and `to` is
  excluded.
- The range may be at most 366 days. Ranges up to 48 hours are
  answered in hourly buckets, longer ones in daily buckets of whole
  UTC days; `range` in the answer gives what was used.
- A monitor without its own `sla_target` is held to
  `default_sla_target` (99.9).

Requires the `uptime:monitor:read` scope.

## Authorization

Any one of:

- `bearerKey`
- `headerKey`

Where:

- `bearerKey`: HTTP Bearer — An EvoHub API key (`evohub_…`) as a bearer token.
- `headerKey`: API key in the header `X-API-Key` — An EvoHub API key (`evohub_…`).

## Query parameters

- `from` (string, example `2026-09-01`): Start of the range. Send together with `to`.
- `to` (string, example `2026-09-30`): End of the range. Send together with `from`.
- `compare` (string, one of `previous`, `year`): Also return headline numbers for the period before (`previous`) or the same range a year earlier (`year`).
- `team_id` (string, example `none`): Narrow to one team's monitors, or `none` for only the organization-wide ones. It never widens what the caller can see.

## Responses

### 200 — The analytics.

Content type: `application/json`

Type: `object`

- `data` (UptimeAnalytics, required)
  - `range` (object): The window answered. Daily answers cover whole UTC days, so it can be wider than asked.
    - `from` (string (date-time))
    - `to` (string (date-time))
    - `granularity` (string, one of `hour`, `day`)
    - `tz` (string, value `UTC`)
  - `default_sla_target` (number)
  - `totals` (object)
    - `monitors` (integer)
    - `uptime_percent` (number | null): Check-weighted across all monitors.
    - `monitor_average_uptime_percent` (number | null): The plain mean of each monitor's own uptime.
    - `checks` (integer)
    - `up_checks` (integer)
    - `down_checks` (integer)
    - `degraded_checks` (integer)
    - `degraded_seconds` (integer)
    - `down_seconds` (integer)
    - `latency` (Latency)
      - `avg_ms` (number | null)
      - `p50_ms` (number | null)
      - `p95_ms` (number | null)
    - `sla` (object)
      - `met` (integer)
      - `missed` (integer)
      - `no_data` (integer)
    - `incidents` (IncidentStats)
      - `count` (integer)
      - `resolved` (integer)
      - `open_now` (integer)
      - `downtime_seconds` (number)
      - `mttr` (object): Time to recover, over resolved outages.
        - `count` (integer)
        - `p50_seconds` (number | null)
        - `p95_seconds` (number | null)
        - `avg_seconds` (number | null)
  - `series` (array of object)
    - `bucket` (string (date-time))
    - `checks` (integer)
    - `up_checks` (integer)
    - `uptime_percent` (number | null)
    - `degraded_seconds` (integer)
    - `down_seconds` (integer)
    - `latency` (Latency)
      - `avg_ms` (number | null)
      - `p50_ms` (number | null)
      - `p95_ms` (number | null)
    - `incidents` (integer)
  - `by_monitor` (array of MonitorStats)
    - `monitor_id` (string)
    - `name` (string)
    - `type` (MonitorType, one of `http`, `keyword`, `tcp`, `icmp`, `heartbeat`)
    - `team_id` (string)
    - `is_active` (boolean)
    - `sla_target` (number | null)
    - `sla_target_source` (string, one of `monitor`, `default`): Whether the target is the monitor's own or `default_sla_target`.
    - `uptime_percent` (number | null)
    - `sla_gap` (number | null): Uptime minus target, in percentage points.
    - `sla_met` (boolean | null)
    - `checks` (integer)
    - `up_checks` (integer)
    - `degraded_seconds` (integer)
    - `down_seconds` (integer)
    - `latency` (Latency)
    - `incidents` (IncidentStats)
  - `worst_monitors` (array of MonitorStats): Up to five monitors furthest below their target, then lowest uptime.
    - `monitor_id` (string)
    - `name` (string)
    - `type` (MonitorType, one of `http`, `keyword`, `tcp`, `icmp`, `heartbeat`)
    - `team_id` (string)
    - `is_active` (boolean)
    - `sla_target` (number | null)
    - `sla_target_source` (string, one of `monitor`, `default`): Whether the target is the monitor's own or `default_sla_target`.
    - `uptime_percent` (number | null)
    - `sla_gap` (number | null): Uptime minus target, in percentage points.
    - `sla_met` (boolean | null)
    - `checks` (integer)
    - `up_checks` (integer)
    - `degraded_seconds` (integer)
    - `down_seconds` (integer)
    - `latency` (Latency)
    - `incidents` (IncidentStats)
  - `by_team` (array of object): One row per team; `team_id` `""` is the organization-wide monitors.
    - `team_id` (string)
    - `monitors` (integer)
    - `uptime_percent` (number | null)
    - `sla_missed` (integer)
    - `incidents` (integer)
    - `downtime_seconds` (number)
    - `degraded_seconds` (integer)
  - `coverage` (object): Days rolled up before latency and degraded or down time were recorded add nothing to those figures; this says how many there are.
    - `rows` (integer)
    - `rows_without_detail` (integer)
  - `compare` (null | object): The comparison period's headline numbers, or `null` without `compare`.
    - One of:
      - null
      - object
        - `mode` (string, one of `previous`, `year`)
        - `from` (string (date-time))
        - `to` (string (date-time))
        - `uptime_percent` (number | null)
        - `checks` (integer)
        - `degraded_seconds` (integer)
        - `latency` (Latency)
          - `avg_ms` (number | null)
          - `p50_ms` (number | null)
          - `p95_ms` (number | null)
        - `incidents` (IncidentStats)
          - `count` (integer)
          - `resolved` (integer)
          - `open_now` (integer)
          - `downtime_seconds` (number)
          - `mttr` (object): Time to recover, over resolved outages.
            - `count` (integer)
            - `p50_seconds` (number | null)
            - `p95_seconds` (number | null)
            - `avg_seconds` (number | null)
- `success` (boolean, required, value `true`)

### 400 — `from`, `to` or `compare` is invalid (`VALIDATION_FAILED`, with `details` naming each field).

Content type: `application/json`

Type: `ValidationFailed`

- `error` (object, required)
  - `code` (string, required, value `VALIDATION_FAILED`)
  - `message` (string, required)
  - `details` (array of object, required)
    - `field` (string)
    - `message` (string)

### 401 — No API key was sent, or it is unknown, revoked or expired (`UNAUTHORIZED`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `MONITOR_NOT_FOUND`)
  - `message` (string, required, example `monitor not found`)
  - `request_id` (string)

### 403 — The key lacks the scope this endpoint needs (`FORBIDDEN`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `MONITOR_NOT_FOUND`)
  - `message` (string, required, example `monitor not found`)
  - `request_id` (string)

### 429 — Too many requests (`RATE_LIMITED`). Wait for `Retry-After` seconds.

Headers:

- `Retry-After` (integer): Seconds to wait before retrying.

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `MONITOR_NOT_FOUND`)
  - `message` (string, required, example `monitor not found`)
  - `request_id` (string)

### 500 — Something went wrong on EvoHub's side (`INTERNAL_ERROR`). Retry later.

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `MONITOR_NOT_FOUND`)
  - `message` (string, required, example `monitor not found`)
  - `request_id` (string)

## Example request

```bash
curl -X GET 'https://evohub.io/api/v1/uptime/analytics' \
  -H 'Authorization: Bearer <TOKEN>'
```
