---
title: "Latest metrics API"
description: "API reference for Alpacon's latest metrics endpoint. Read every server's newest CPU, memory, disk, disk I/O, and network value in one paginated request."
---

> Full documentation index: https://docs.alpacax.com/llms.txt

# Latest metrics

**Endpoint**: `/api/metrics/latest/`

One request returns a page of servers with each server's newest CPU, memory, disk usage, disk I/O, and network value—the same numbers behind the workspace's metrics overview. It accepts the same filters, search, and pagination as the [server list](/reference/api/servers/servers/#list-servers), so you can page through, search, or narrow a fleet and read many servers' latest numbers in one call instead of querying each server on its own.

Requires the Metrics extension to be enabled for the workspace: a plan that doesn't reach it answers `402`, and a plan that reaches it but hasn't switched it on answers `403`. Requires [`metric:read`](/reference/scopes/#metric-read).

## Request

```http
GET /api/metrics/latest/
```

### Query parameters

Accepts every filter, search field, and pagination parameter the [server list](/reference/api/servers/servers/#list-servers) does—`name`, `groups`, `tag`, `is_connected`, `starred`, `os`, `search`, and the rest of that table—plus:

| Parameter | Type | Description |
|-----------|------|-------------|
| `state` | string | `stale`—servers whose newest sample, across all five metrics, is too old to trust, or missing entirely. `no_data`—servers with no stored sample for any metric yet. Every `no_data` server is also `stale` |
| `ordering` | string | Extends the server list's own `ordering` with `sampled_at` and the five metric families: `cpu`, `memory`, `disk-usage` (or `disk_usage`), `disk-io` (or `disk_io`), `net`. Prefix any of them with `-` for descending. Also accepts `metric_severity` and `-metric_severity` (see [Server severity](#server-severity)). Default: starred servers first, in their saved order, then `name` |
| `page` | integer | Page number |
| `page_size` | integer | Results per page (default: 15, max: 100) |

### Response

```json
{
  "count": 42,
  "current": 1,
  "next": 2,
  "previous": null,
  "last": 3,
  "summary": {
    "critical": 3,
    "warning": 7,
    "stale": 4,
    "no_data": 1
  },
  "results": [
    {
      "id": "0f3c9d2e-1a4b-4c8d-9e6f-2b7a1c5d8e30",
      "name": "web-01",
      "is_connected": true,
      "metric_severity": "warning",
      "cpu": {
        "value": 42.1,
        "unit": "percent",
        "sampled_at": "2026-09-17T02:14:00+09:00",
        "device": null,
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": 80.0,
        "operator": "gte"
      },
      "memory": {
        "value": 68.4,
        "unit": "percent",
        "sampled_at": "2026-09-17T02:14:00+09:00",
        "device": null,
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": 90.0,
        "operator": "gte"
      },
      "disk-usage": {
        "value": 78.0,
        "unit": "percent",
        "sampled_at": "2026-09-17T02:14:00+09:00",
        "device": "/",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": 85.0,
        "operator": "gte"
      },
      "disk-io": {
        "value": 12582912.0,
        "unit": "bytes_per_sec",
        "sampled_at": "2026-09-17T02:14:00+09:00",
        "device": "all",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      },
      "net": {
        "value": 3145728.0,
        "unit": "bytes_per_sec",
        "sampled_at": "2026-09-17T02:14:00+09:00",
        "device": "all",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      }
    },
    {
      "id": "3b8f4c1a-7d2e-4a9b-8c5f-1e6a2b9d4c7f",
      "name": "db-01",
      "is_connected": true,
      "metric_severity": null,
      "cpu": {
        "value": 12.3,
        "unit": "percent",
        "sampled_at": "2026-09-17T02:13:00+09:00",
        "device": null,
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      },
      "memory": {
        "value": null,
        "unit": "percent",
        "sampled_at": null,
        "device": null,
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      },
      "disk-usage": {
        "value": 34.5,
        "unit": "percent",
        "sampled_at": "2026-09-17T02:13:00+09:00",
        "device": "/data",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      },
      "disk-io": {
        "value": 512000.0,
        "unit": "bytes_per_sec",
        "sampled_at": "2026-09-17T02:13:00+09:00",
        "device": "all",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      },
      "net": {
        "value": 204800.0,
        "unit": "bytes_per_sec",
        "sampled_at": "2026-09-17T02:13:00+09:00",
        "device": "all",
        "collected": true,
        "reason": null,
        "interval_s": 60,
        "threshold": null,
        "operator": null
      }
    }
  ]
}
```

Every entry in `results` carries `id`, `name`, `is_connected`, `metric_severity`, and one object per metric family: `cpu`, `memory`, `disk-usage`, `disk-io`, `net`. `unit` is `percent` for CPU, memory, and disk usage, and `bytes_per_sec` for disk I/O and network. `device` names the disk or interface the value came from—the specific mount point for disk usage, `all` for the combined disk I/O or network total, and `null` for CPU and memory, which aren't device-specific.

### Cell thresholds

Each metric object includes these fields:

| Field | Type | Description |
|-------|------|-------------|
| `threshold` | number or null | Effective rule threshold after the server's [rule override](/reference/api/metrics/rule-overrides/) applies, in the cell's `unit` |
| `operator` | string or null | `gte` for a value at or above the threshold, `lte` for a value at or below it |

For `cpu`, `memory`, and `disk-usage`, both fields are `null` when no rule applies to the cell, including when the server is not commissioned (`commissioned=false`) or is disabled, or its applicable rules are disabled by server overrides. If several rules apply, `gte` takes precedence over `lte`; the lowest `gte` threshold or highest `lte` threshold is returned. A disk rule with a device selector applies only when it matches the disk represented by the cell.

For `disk-io` and `net`, both fields are always `null`. These cells sum both directions across devices, while rules evaluate one direction per device.

Reading thresholds requires permission to read rule overrides and the [`rule_override:read`](/reference/scopes/#rule_override-read) token scope. Without that access, `threshold` and `operator` are `null` on every cell.

### Server severity

| Field | Type | Description |
|-------|------|-------------|
| `metric_severity` | string or null | Highest severity among the server's open `metric_threshold` alerts: `critical`, `warning`, then `info`. `null` when there is no such alert or the caller cannot read alerts |

`ordering=-metric_severity` sorts `critical` first, then `warning`, `info`, and `null` across all pages. `ordering=metric_severity` reverses that order. Ties follow the default server order.

Without alert read access, including the [`alert:read`](/reference/scopes/#alert-read) token scope, `metric_severity`, `summary.critical`, and `summary.warning` are `null`, and severity ordering is ignored. Threshold visibility is controlled separately by rule-override read access.

### Summary

The top-level `summary` counts servers in the full filtered set that the caller can see, before pagination. Search and `state` filters apply to these counts too. These are server counts, not alert counts.

| Field | Type | Description |
|-------|------|-------------|
| `critical` | integer or null | Servers whose `metric_severity` is `critical`. `null` without alert read access |
| `warning` | integer or null | Servers whose `metric_severity` is `warning`, excluding servers counted as `critical`. `null` without alert read access |
| `stale` | integer | Servers matching `state=stale`, including those with no data |
| `no_data` | integer | Servers with no stored sample for any metric, matching `state=no_data` |

Every `no_data` server also counts in `stale`. The `stale` and `no_data` counts remain available without `alert:read`.

Required scope: [`metric:read`](/reference/scopes/#metric-read)

### Example

```bash
curl -X GET "https://your-workspace.us1.alpacon.io/api/metrics/latest/?is_connected=true&ordering=-cpu" \
  -H "Authorization: token=\"alpat-xxxxxxxxxxxxxxxxxx\""
```

## When a cell is empty

When no sample has arrived for a family yet, its `value`, `sampled_at`, and `device` are `null`. This can happen on a newly registered server or for a metric that has never reported. `interval_s` says how often, in seconds, a sample should arrive for that family.

`collected` is `true` and `reason` is `null` on every cell you'll see here: reaching this endpoint at all already means the [Metrics extension](/use/servers/monitor/#monitoring-dashboard) is enabled for the workspace, so there's no case where a family it reports is not being collected.

## Finding the busiest or quietest host

Sort on any metric family with `ordering`. Descending finds the busiest server first, ascending finds the quietest:

```bash
# Highest CPU first
curl -X GET "https://your-workspace.us1.alpacon.io/api/metrics/latest/?ordering=-cpu" \
  -H "Authorization: token=\"alpat-xxxxxxxxxxxxxxxxxx\""

# Lowest disk usage first
curl -X GET "https://your-workspace.us1.alpacon.io/api/metrics/latest/?ordering=disk-usage" \
  -H "Authorization: token=\"alpat-xxxxxxxxxxxxxxxxxx\""
```

A server with no value for the family you're sorting on sorts last, whichever direction you use—a fleet ordered by `-net` never opens with a server that hasn't reported any network traffic at all. Combine with `state=stale` or `state=no_data` to separate servers that are behind from ones that just rank low.

## Error responses

| Status | Error code | Description |
|--------|------------|-------------|
| 401 | `UNAUTHORIZED` | Invalid or missing authentication |
| 402 | `workspace_extension_plan_required` | The workspace's plan doesn't include the Metrics extension |
| 403 | `workspace_extension_not_enabled` | The Metrics extension is available on this plan but hasn't been switched on |

Source: https://docs.alpacax.com/reference/api/metrics/latest/
