# Get uptime analytics

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

Part of the [Uptime API](https://docs.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 that
  start within the last 89 days are answered in hourly buckets, all
  others 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>'
```
